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  

View as plain text