Source file src/crypto/internal/fips/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 fips 6 7 import ( 8 "errors" 9 "internal/godebug" 10 "strings" 11 _ "unsafe" // for go:linkname 12 ) 13 14 // fatal is [runtime.fatal], pushed via linkname. 15 // 16 //go:linkname fatal 17 func fatal(string) 18 19 // failfipscast is a GODEBUG key allowing simulation of a Cryptographic Algorithm 20 // Self-Test (CAST) failure, as required during FIPS 140-3 functional testing. 21 // The value is a substring of the target CAST name. 22 var failfipscast = godebug.New("#failfipscast") 23 24 // testingOnlyCASTHook is called during tests with each CAST name. 25 var testingOnlyCASTHook func(string) 26 27 // CAST runs the named Cryptographic Algorithm Self-Test (if compiled and 28 // operated in FIPS mode) and aborts the program (stopping the module 29 // input/output and entering the "error state") if the self-test fails. 30 // 31 // These are mandatory self-checks that must be performed by FIPS 140-3 modules 32 // before the algorithm is used. See Implementation Guidance 10.3.A. 33 // 34 // The name must not contain commas, colons, hashes, or equal signs. 35 // 36 // When calling this function, also add the calling package to cast_test.go. 37 func CAST(name string, f func() error) { 38 if strings.ContainsAny(name, ",#=:") { 39 panic("fips: invalid self-test name: " + name) 40 } 41 if testingOnlyCASTHook != nil { 42 testingOnlyCASTHook(name) 43 } 44 45 err := f() 46 if failfipscast.Value() != "" && strings.Contains(name, failfipscast.Value()) { 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 } 54