mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
crypto/internal/fips140test: add entropy SHA2-384 testing
The crypto/internal/fips140/entropy package vendors a minimal implementation of SHA2-384 to insulate it from changes in the FIPS module implementation. This means it also requires ACVP testing separate from the FIPS module implementation. This commit implements the required ACVP testing support. There's no way via the ACVP protocol, or acvptool, to specify that we want to test a specific SHA2-384 implementation compared to normal. We use a new environment variable (GOENTROPYSOURCEACVP=1) to make that distinction. The capabilities we advertise when testing the entropy SHA2-384 implementation are limited to something that best describes the input sizes that the entropy module's implementation supports within the requirements imposed by ACVP. We allow 144 byte messages (3*digest size) to support MCT and in particular the "standard" MCT algorithm, and allow 1024 byte messages as the production supported message size used by the entropy module itself. Change-Id: I6e693a3fa23efba35d8a7d029ddf0b11036621c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/711740 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
f92e01c117
commit
02728a2846
2 changed files with 76 additions and 1 deletions
|
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
{"algorithm":"SHA2-384","messageLength":[{"increment":7040,"max":8192,"min":1152}],"revision":"1.0"}
|
||||
]
|
||||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/elliptic"
|
||||
"crypto/internal/cryptotest"
|
||||
"crypto/internal/entropy/v1.0.0"
|
||||
"crypto/internal/fips140"
|
||||
"crypto/internal/fips140/aes"
|
||||
"crypto/internal/fips140/aes/gcm"
|
||||
|
|
@ -62,6 +63,11 @@ import (
|
|||
|
||||
var noPAAPAI = os.Getenv("GONOPAAPAI") == "1"
|
||||
|
||||
// Use the capabilities, configuration and commands for the entropy source.
|
||||
// This is used to test the separate entropy source in crypto/internal/entropy
|
||||
// since the algorithm name alone can't indicate which to test.
|
||||
var entropyTesting = os.Getenv("GOENTROPYSOURCEACVP") == "1"
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if noPAAPAI {
|
||||
for _, p := range impl.Packages() {
|
||||
|
|
@ -155,6 +161,13 @@ var (
|
|||
//go:embed acvp_capabilities.json
|
||||
capabilitiesJson []byte
|
||||
|
||||
// Separate capabilities specific to testing the entropy source's SHA2-384 implementation.
|
||||
// This implementation differs from the FIPS module's SHA2-384 in its supported input sizes.
|
||||
// Set the GOENTROPYSOURCEACVP environment variable to use these capabilities in place of
|
||||
// capabilitiesJson
|
||||
//go:embed acvp_capabilities.entropy.json
|
||||
entropyCapabilitiesJson []byte
|
||||
|
||||
// commands should reflect what config says we support. E.g. adding a command here will be a NOP
|
||||
// unless the configuration/acvp_capabilities.json indicates the command's associated algorithm
|
||||
// is supported.
|
||||
|
|
@ -183,6 +196,14 @@ var (
|
|||
"SHA3-512": cmdHashAft(sha3.New512()),
|
||||
"SHA3-512/MCT": cmdSha3Mct(sha3.New512()),
|
||||
|
||||
// Note: the "/ENTROPY" suffix is our own creation, and applied conditionally
|
||||
// based on the environment variable that indicates our acvp_test module wrapper
|
||||
// is being used for evaluating the separate SHA-384 implementation for the
|
||||
// CPU jitter entropy conditioning. Set GOENTROPYSOURCEACVP=1 to use these commands
|
||||
// in place of SHA2-384.
|
||||
"SHA2-384/ENTROPY": cmdEntropyHashEntropySha384Aft(),
|
||||
"SHA2-384/MCT/ENTROPY": cmdEntropyHashEntropySha384Mct(),
|
||||
|
||||
// Note: SHAKE AFT and VOT test types can be handled by the same command
|
||||
// handler impl, but use distinct acvptool command names, and so are
|
||||
// registered twice with the same digest: once under "SHAKE-xxx" for AFT,
|
||||
|
|
@ -363,6 +384,10 @@ func processingLoop(reader io.Reader, writer io.Writer) error {
|
|||
return fmt.Errorf("reading request: %w", err)
|
||||
}
|
||||
|
||||
if entropyTesting && strings.HasPrefix(req.name, "SHA2-384") {
|
||||
req.name = fmt.Sprintf("%s/ENTROPY", req.name)
|
||||
}
|
||||
|
||||
cmd, exists := commands[req.name]
|
||||
if !exists {
|
||||
return fmt.Errorf("unknown command: %q", req.name)
|
||||
|
|
@ -460,9 +485,16 @@ func writeResponse(writer io.Writer, args [][]byte) error {
|
|||
// which takes no arguments and returns a single byte string
|
||||
// which is a JSON blob of ACVP algorithm configuration."
|
||||
func cmdGetConfig() command {
|
||||
// If GOENTROPYSOURCEACVP is set, then use the entropyCapabilitiesJson
|
||||
// instead of capabilitiesJson.
|
||||
capabilities := [][]byte{capabilitiesJson}
|
||||
if entropyTesting {
|
||||
capabilities = [][]byte{entropyCapabilitiesJson}
|
||||
}
|
||||
|
||||
return command{
|
||||
handler: func(args [][]byte) ([][]byte, error) {
|
||||
return [][]byte{capabilitiesJson}, nil
|
||||
return capabilities, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -533,6 +565,46 @@ func cmdHashMct(h hash.Hash) command {
|
|||
}
|
||||
}
|
||||
|
||||
// cmdEntropyHashEntropySha384Aft returns a command handler that tests the
|
||||
// entropy package's SHA2-384 digest for AFT inputs.
|
||||
func cmdEntropyHashEntropySha384Aft() command {
|
||||
return command{
|
||||
requiredArgs: 1, // Message to hash.
|
||||
handler: func(args [][]byte) ([][]byte, error) {
|
||||
digest := entropy.TestingOnlySHA384(args[0])
|
||||
return [][]byte{digest[:]}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// cmdEntropyHashEntropySha384Mct returns a command handler that tests the
|
||||
// entropy package's SHA2-384 digest for MCT inputs.
|
||||
func cmdEntropyHashEntropySha384Mct() command {
|
||||
return command{
|
||||
requiredArgs: 1, // Seed message.
|
||||
handler: func(args [][]byte) ([][]byte, error) {
|
||||
hSize := 48
|
||||
seed := args[0]
|
||||
|
||||
digest := make([]byte, 0, hSize)
|
||||
buf := make([]byte, 0, 3*hSize)
|
||||
buf = append(buf, seed...)
|
||||
buf = append(buf, seed...)
|
||||
buf = append(buf, seed...)
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
digestRaw := entropy.TestingOnlySHA384(buf)
|
||||
digest = digestRaw[:hSize]
|
||||
|
||||
copy(buf, buf[hSize:])
|
||||
copy(buf[2*hSize:], digest)
|
||||
}
|
||||
|
||||
return [][]byte{buf[hSize*2:]}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// cmdSha3Mct returns a command handler for the specified hash
|
||||
// algorithm for SHA-3 monte carlo test (MCT) test cases.
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue