Skip to content

Commit 02728a2

Browse files
cpugopherbot
authored andcommitted
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>
1 parent f92e01c commit 02728a2

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[
2+
{"algorithm":"SHA2-384","messageLength":[{"increment":7040,"max":8192,"min":1152}],"revision":"1.0"}
3+
]

src/crypto/internal/fips140test/acvp_test.go

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"bytes"
2424
"crypto/elliptic"
2525
"crypto/internal/cryptotest"
26+
"crypto/internal/entropy/v1.0.0"
2627
"crypto/internal/fips140"
2728
"crypto/internal/fips140/aes"
2829
"crypto/internal/fips140/aes/gcm"
@@ -62,6 +63,11 @@ import (
6263

6364
var noPAAPAI = os.Getenv("GONOPAAPAI") == "1"
6465

66+
// Use the capabilities, configuration and commands for the entropy source.
67+
// This is used to test the separate entropy source in crypto/internal/entropy
68+
// since the algorithm name alone can't indicate which to test.
69+
var entropyTesting = os.Getenv("GOENTROPYSOURCEACVP") == "1"
70+
6571
func TestMain(m *testing.M) {
6672
if noPAAPAI {
6773
for _, p := range impl.Packages() {
@@ -155,6 +161,13 @@ var (
155161
//go:embed acvp_capabilities.json
156162
capabilitiesJson []byte
157163

164+
// Separate capabilities specific to testing the entropy source's SHA2-384 implementation.
165+
// This implementation differs from the FIPS module's SHA2-384 in its supported input sizes.
166+
// Set the GOENTROPYSOURCEACVP environment variable to use these capabilities in place of
167+
// capabilitiesJson
168+
//go:embed acvp_capabilities.entropy.json
169+
entropyCapabilitiesJson []byte
170+
158171
// commands should reflect what config says we support. E.g. adding a command here will be a NOP
159172
// unless the configuration/acvp_capabilities.json indicates the command's associated algorithm
160173
// is supported.
@@ -183,6 +196,14 @@ var (
183196
"SHA3-512": cmdHashAft(sha3.New512()),
184197
"SHA3-512/MCT": cmdSha3Mct(sha3.New512()),
185198

199+
// Note: the "/ENTROPY" suffix is our own creation, and applied conditionally
200+
// based on the environment variable that indicates our acvp_test module wrapper
201+
// is being used for evaluating the separate SHA-384 implementation for the
202+
// CPU jitter entropy conditioning. Set GOENTROPYSOURCEACVP=1 to use these commands
203+
// in place of SHA2-384.
204+
"SHA2-384/ENTROPY": cmdEntropyHashEntropySha384Aft(),
205+
"SHA2-384/MCT/ENTROPY": cmdEntropyHashEntropySha384Mct(),
206+
186207
// Note: SHAKE AFT and VOT test types can be handled by the same command
187208
// handler impl, but use distinct acvptool command names, and so are
188209
// 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 {
363384
return fmt.Errorf("reading request: %w", err)
364385
}
365386

387+
if entropyTesting && strings.HasPrefix(req.name, "SHA2-384") {
388+
req.name = fmt.Sprintf("%s/ENTROPY", req.name)
389+
}
390+
366391
cmd, exists := commands[req.name]
367392
if !exists {
368393
return fmt.Errorf("unknown command: %q", req.name)
@@ -460,9 +485,16 @@ func writeResponse(writer io.Writer, args [][]byte) error {
460485
// which takes no arguments and returns a single byte string
461486
// which is a JSON blob of ACVP algorithm configuration."
462487
func cmdGetConfig() command {
488+
// If GOENTROPYSOURCEACVP is set, then use the entropyCapabilitiesJson
489+
// instead of capabilitiesJson.
490+
capabilities := [][]byte{capabilitiesJson}
491+
if entropyTesting {
492+
capabilities = [][]byte{entropyCapabilitiesJson}
493+
}
494+
463495
return command{
464496
handler: func(args [][]byte) ([][]byte, error) {
465-
return [][]byte{capabilitiesJson}, nil
497+
return capabilities, nil
466498
},
467499
}
468500
}
@@ -533,6 +565,46 @@ func cmdHashMct(h hash.Hash) command {
533565
}
534566
}
535567

568+
// cmdEntropyHashEntropySha384Aft returns a command handler that tests the
569+
// entropy package's SHA2-384 digest for AFT inputs.
570+
func cmdEntropyHashEntropySha384Aft() command {
571+
return command{
572+
requiredArgs: 1, // Message to hash.
573+
handler: func(args [][]byte) ([][]byte, error) {
574+
digest := entropy.TestingOnlySHA384(args[0])
575+
return [][]byte{digest[:]}, nil
576+
},
577+
}
578+
}
579+
580+
// cmdEntropyHashEntropySha384Mct returns a command handler that tests the
581+
// entropy package's SHA2-384 digest for MCT inputs.
582+
func cmdEntropyHashEntropySha384Mct() command {
583+
return command{
584+
requiredArgs: 1, // Seed message.
585+
handler: func(args [][]byte) ([][]byte, error) {
586+
hSize := 48
587+
seed := args[0]
588+
589+
digest := make([]byte, 0, hSize)
590+
buf := make([]byte, 0, 3*hSize)
591+
buf = append(buf, seed...)
592+
buf = append(buf, seed...)
593+
buf = append(buf, seed...)
594+
595+
for i := 0; i < 1000; i++ {
596+
digestRaw := entropy.TestingOnlySHA384(buf)
597+
digest = digestRaw[:hSize]
598+
599+
copy(buf, buf[hSize:])
600+
copy(buf[2*hSize:], digest)
601+
}
602+
603+
return [][]byte{buf[hSize*2:]}, nil
604+
},
605+
}
606+
}
607+
536608
// cmdSha3Mct returns a command handler for the specified hash
537609
// algorithm for SHA-3 monte carlo test (MCT) test cases.
538610
//

0 commit comments

Comments
 (0)