Skip to content

Commit 035d3c8

Browse files
cpugopherbot
authored andcommitted
crypto/internal/fips140test: add SHAKE-* ACVP tests
This commit adds ACVP test coverage for SHAKE-128 and SHAKE-256 based on the NIST spec: https://pages.nist.gov/ACVP/draft-celi-acvp-sha3.html Updates #69642 Change-Id: Ia6899def452fcb63a03603b7919fcb0c3576474b Reviewed-on: https://go-review.googlesource.com/c/go/+/622395 Reviewed-by: Dmitri Shuralyov <[email protected]> TryBot-Bypass: Dmitri Shuralyov <[email protected]> Auto-Submit: Dmitri Shuralyov <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent 8cb6d3b commit 035d3c8

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

src/crypto/internal/fips140test/acvp_capabilities.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
{"algorithm":"SHA3-384","messageLength":[{"increment":8,"max":65528,"min":0}],"revision":"2.0"},
1212
{"algorithm":"SHA3-512","messageLength":[{"increment":8,"max":65528,"min":0}],"revision":"2.0"},
1313

14+
{"algorithm":"SHAKE-128","inBit":false,"outBit":false,"inEmpty":true,"outputLen":[{"min":16,"max":65536,"increment":8}],"revision":"1.0"},
15+
{"algorithm":"SHAKE-256","inBit":false,"outBit":false,"inEmpty":true,"outputLen":[{"min":16,"max":65536,"increment":8}],"revision":"1.0"},
16+
1417
{"algorithm":"HMAC-SHA2-224","keyLen":[{"increment":8,"max":524288,"min":8}],"macLen":[{"increment":8,"max":224,"min":32}],"revision":"1.0"},
1518
{"algorithm":"HMAC-SHA2-256","keyLen":[{"increment":8,"max":524288,"min":8}],"macLen":[{"increment":8,"max":256,"min":32}],"revision":"1.0"},
1619
{"algorithm":"HMAC-SHA2-384","keyLen":[{"increment":8,"max":524288,"min":8}],"macLen":[{"increment":8,"max":384,"min":32}],"revision":"1.0"},

src/crypto/internal/fips140test/acvp_test.config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
{"Wrapper": "go", "In": "vectors/SHA3-384.bz2", "Out": "expected/SHA3-384.bz2"},
1212
{"Wrapper": "go", "In": "vectors/SHA3-512.bz2", "Out": "expected/SHA3-512.bz2"},
1313

14+
{"Wrapper": "go", "In": "vectors/SHAKE-128.bz2", "Out": "expected/SHAKE-128.bz2"},
15+
{"Wrapper": "go", "In": "vectors/SHAKE-256.bz2", "Out": "expected/SHAKE-256.bz2"},
16+
1417
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-224.bz2", "Out": "expected/HMAC-SHA2-224.bz2"},
1518
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-256.bz2", "Out": "expected/HMAC-SHA2-256.bz2"},
1619
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-384.bz2", "Out": "expected/HMAC-SHA2-384.bz2"},

src/crypto/internal/fips140test/acvp_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ const (
9595
var (
9696
// SHA2 algorithm capabilities:
9797
// https://pages.nist.gov/ACVP/draft-celi-acvp-sha.html#section-7.2
98+
// SHA3 and SHAKE algorithm capabilities:
99+
// https://pages.nist.gov/ACVP/draft-celi-acvp-sha3.html#name-sha3-and-shake-algorithm-ca
98100
// HMAC algorithm capabilities:
99101
// https://pages.nist.gov/ACVP/draft-fussell-acvp-mac.html#section-7
100102
// PBKDF2 algorithm capabilities:
@@ -140,6 +142,17 @@ var (
140142
"SHA3-512": cmdHashAft(sha3.New512()),
141143
"SHA3-512/MCT": cmdSha3Mct(sha3.New512()),
142144

145+
// Note: SHAKE AFT and VOT test types can be handled by the same command
146+
// handler impl, but use distinct acvptool command names, and so are
147+
// registered twice with the same digest: once under "SHAKE-xxx" for AFT,
148+
// and once under"SHAKE-xxx/VOT" for VOT.
149+
"SHAKE-128": cmdShakeAftVot(sha3.NewShake128()),
150+
"SHAKE-128/VOT": cmdShakeAftVot(sha3.NewShake128()),
151+
"SHAKE-128/MCT": cmdShakeMct(sha3.NewShake128()),
152+
"SHAKE-256": cmdShakeAftVot(sha3.NewShake256()),
153+
"SHAKE-256/VOT": cmdShakeAftVot(sha3.NewShake256()),
154+
"SHAKE-256/MCT": cmdShakeMct(sha3.NewShake256()),
155+
143156
"HMAC-SHA2-224": cmdHmacAft(func() fips140.Hash { return sha256.New224() }),
144157
"HMAC-SHA2-256": cmdHmacAft(func() fips140.Hash { return sha256.New() }),
145158
"HMAC-SHA2-384": cmdHmacAft(func() fips140.Hash { return sha512.New384() }),
@@ -410,6 +423,70 @@ func cmdSha3Mct(h fips140.Hash) command {
410423
}
411424
}
412425

426+
func cmdShakeAftVot(h *sha3.SHAKE) command {
427+
return command{
428+
requiredArgs: 2, // Message, output length (bytes)
429+
handler: func(args [][]byte) ([][]byte, error) {
430+
msg := args[0]
431+
432+
outLenBytes := binary.LittleEndian.Uint32(args[1])
433+
digest := make([]byte, outLenBytes)
434+
435+
h.Reset()
436+
h.Write(msg)
437+
h.Read(digest)
438+
439+
return [][]byte{digest}, nil
440+
},
441+
}
442+
}
443+
444+
func cmdShakeMct(h *sha3.SHAKE) command {
445+
return command{
446+
requiredArgs: 4, // Seed message, min output length (bytes), max output length (bytes), output length (bytes)
447+
handler: func(args [][]byte) ([][]byte, error) {
448+
md := args[0]
449+
minOutBytes := binary.LittleEndian.Uint32(args[1])
450+
maxOutBytes := binary.LittleEndian.Uint32(args[2])
451+
452+
outputLenBytes := binary.LittleEndian.Uint32(args[3])
453+
if outputLenBytes < 2 {
454+
return nil, fmt.Errorf("invalid output length: %d", outputLenBytes)
455+
}
456+
457+
rangeBytes := maxOutBytes - minOutBytes + 1
458+
if rangeBytes == 0 {
459+
return nil, fmt.Errorf("invalid maxOutBytes and minOutBytes: %d, %d", maxOutBytes, minOutBytes)
460+
}
461+
462+
for i := 0; i < 1000; i++ {
463+
// "The MSG[i] input to SHAKE MUST always contain at least 128 bits. If this is not the case
464+
// as the previous digest was too short, append empty bits to the rightmost side of the digest."
465+
boundary := min(len(md), 16)
466+
msg := make([]byte, 16)
467+
copy(msg, md[:boundary])
468+
469+
// MD[i] = SHAKE(MSG[i], OutputLen * 8)
470+
h.Reset()
471+
h.Write(msg)
472+
digest := make([]byte, outputLenBytes)
473+
h.Read(digest)
474+
md = digest
475+
476+
// RightmostOutputBits = 16 rightmost bits of MD[i] as an integer
477+
// OutputLen = minOutBytes + (RightmostOutputBits % Range)
478+
rightmostOutput := uint32(md[outputLenBytes-2])<<8 | uint32(md[outputLenBytes-1])
479+
outputLenBytes = minOutBytes + (rightmostOutput % rangeBytes)
480+
}
481+
482+
encodedOutputLenBytes := make([]byte, 4)
483+
binary.LittleEndian.PutUint32(encodedOutputLenBytes, outputLenBytes)
484+
485+
return [][]byte{md, encodedOutputLenBytes}, nil
486+
},
487+
}
488+
}
489+
413490
func cmdHmacAft(h func() fips140.Hash) command {
414491
return command{
415492
requiredArgs: 2, // Message and key

0 commit comments

Comments
 (0)