Source file src/crypto/internal/fips140/cast.go
1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fips140 6 7 import ( 8 "crypto/internal/fips140deps/godebug" 9 "errors" 10 "strings" 11 _ "unsafe" // for go:linkname 12 ) 13 14 // fatal is [runtime.fatal], pushed via linkname. 15 // 16 //go:linkname fatal crypto/internal/fips140.fatal 17 func fatal(string) 18 19 // failfipscast is a GODEBUG key allowing simulation of a CAST or PCT failure, 20 // as required during FIPS 140-3 functional testing. The value is the whole name 21 // of the target CAST or PCT. 22 var failfipscast = godebug.Value("#failfipscast") 23 24 // CAST runs the named Cryptographic Algorithm Self-Test (if operated in FIPS 25 // mode) and aborts the program (stopping the module input/output and entering 26 // the "error state") if the self-test fails. 27 // 28 // CASTs are mandatory self-checks that must be performed by FIPS 140-3 modules 29 // before the algorithm is used. See Implementation Guidance 10.3.A. 30 // 31 // The name must not contain commas, colons, hashes, or equal signs. 32 // 33 // If a package p calls CAST from its init function, an import of p should also 34 // be added to crypto/internal/fips140test. If a package p calls CAST on the first 35 // use of the algorithm, an invocation of that algorithm should be added to 36 // fipstest.TestConditionals. 37 func CAST(name string, f func() error) { 38 if strings.ContainsAny(name, ",#=:") { 39 panic("fips: invalid self-test name: " + name) 40 } 41 if !Enabled { 42 return 43 } 44 45 err := f() 46 if name == failfipscast { 47 err = errors.New("simulated CAST failure") 48 } 49 if err != nil { 50 fatal("FIPS 140-3 self-test failed: " + name + ": " + err.Error()) 51 panic("unreachable") 52 } 53 if debug { 54 println("FIPS 140-3 self-test passed:", name) 55 } 56 } 57 58 // PCT runs the named Pairwise Consistency Test (if operated in FIPS mode) and 59 // returns any errors. If an error is returned, the key must not be used. 60 // 61 // PCTs are mandatory for every key pair that is generated/imported, including 62 // ephemeral keys (which effectively doubles the cost of key establishment). See 63 // Implementation Guidance 10.3.A Additional Comment 1. 64 // 65 // The name must not contain commas, colons, hashes, or equal signs. 66 // 67 // If a package p calls PCT during key generation, an invocation of that 68 // function should be added to fipstest.TestConditionals. 69 func PCT(name string, f func() error) error { 70 if strings.ContainsAny(name, ",#=:") { 71 panic("fips: invalid self-test name: " + name) 72 } 73 if !Enabled { 74 return nil 75 } 76 77 err := f() 78 if name == failfipscast { 79 err = errors.New("simulated PCT failure") 80 } 81 return err 82 } 83