mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
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 <dmitshur@golang.org> TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
parent
8cb6d3b826
commit
035d3c8f53
3 changed files with 83 additions and 0 deletions
|
@ -11,6 +11,9 @@
|
|||
{"algorithm":"SHA3-384","messageLength":[{"increment":8,"max":65528,"min":0}],"revision":"2.0"},
|
||||
{"algorithm":"SHA3-512","messageLength":[{"increment":8,"max":65528,"min":0}],"revision":"2.0"},
|
||||
|
||||
{"algorithm":"SHAKE-128","inBit":false,"outBit":false,"inEmpty":true,"outputLen":[{"min":16,"max":65536,"increment":8}],"revision":"1.0"},
|
||||
{"algorithm":"SHAKE-256","inBit":false,"outBit":false,"inEmpty":true,"outputLen":[{"min":16,"max":65536,"increment":8}],"revision":"1.0"},
|
||||
|
||||
{"algorithm":"HMAC-SHA2-224","keyLen":[{"increment":8,"max":524288,"min":8}],"macLen":[{"increment":8,"max":224,"min":32}],"revision":"1.0"},
|
||||
{"algorithm":"HMAC-SHA2-256","keyLen":[{"increment":8,"max":524288,"min":8}],"macLen":[{"increment":8,"max":256,"min":32}],"revision":"1.0"},
|
||||
{"algorithm":"HMAC-SHA2-384","keyLen":[{"increment":8,"max":524288,"min":8}],"macLen":[{"increment":8,"max":384,"min":32}],"revision":"1.0"},
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
{"Wrapper": "go", "In": "vectors/SHA3-384.bz2", "Out": "expected/SHA3-384.bz2"},
|
||||
{"Wrapper": "go", "In": "vectors/SHA3-512.bz2", "Out": "expected/SHA3-512.bz2"},
|
||||
|
||||
{"Wrapper": "go", "In": "vectors/SHAKE-128.bz2", "Out": "expected/SHAKE-128.bz2"},
|
||||
{"Wrapper": "go", "In": "vectors/SHAKE-256.bz2", "Out": "expected/SHAKE-256.bz2"},
|
||||
|
||||
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-224.bz2", "Out": "expected/HMAC-SHA2-224.bz2"},
|
||||
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-256.bz2", "Out": "expected/HMAC-SHA2-256.bz2"},
|
||||
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-384.bz2", "Out": "expected/HMAC-SHA2-384.bz2"},
|
||||
|
|
|
@ -95,6 +95,8 @@ const (
|
|||
var (
|
||||
// SHA2 algorithm capabilities:
|
||||
// https://pages.nist.gov/ACVP/draft-celi-acvp-sha.html#section-7.2
|
||||
// SHA3 and SHAKE algorithm capabilities:
|
||||
// https://pages.nist.gov/ACVP/draft-celi-acvp-sha3.html#name-sha3-and-shake-algorithm-ca
|
||||
// HMAC algorithm capabilities:
|
||||
// https://pages.nist.gov/ACVP/draft-fussell-acvp-mac.html#section-7
|
||||
// PBKDF2 algorithm capabilities:
|
||||
|
@ -140,6 +142,17 @@ var (
|
|||
"SHA3-512": cmdHashAft(sha3.New512()),
|
||||
"SHA3-512/MCT": cmdSha3Mct(sha3.New512()),
|
||||
|
||||
// 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,
|
||||
// and once under"SHAKE-xxx/VOT" for VOT.
|
||||
"SHAKE-128": cmdShakeAftVot(sha3.NewShake128()),
|
||||
"SHAKE-128/VOT": cmdShakeAftVot(sha3.NewShake128()),
|
||||
"SHAKE-128/MCT": cmdShakeMct(sha3.NewShake128()),
|
||||
"SHAKE-256": cmdShakeAftVot(sha3.NewShake256()),
|
||||
"SHAKE-256/VOT": cmdShakeAftVot(sha3.NewShake256()),
|
||||
"SHAKE-256/MCT": cmdShakeMct(sha3.NewShake256()),
|
||||
|
||||
"HMAC-SHA2-224": cmdHmacAft(func() fips140.Hash { return sha256.New224() }),
|
||||
"HMAC-SHA2-256": cmdHmacAft(func() fips140.Hash { return sha256.New() }),
|
||||
"HMAC-SHA2-384": cmdHmacAft(func() fips140.Hash { return sha512.New384() }),
|
||||
|
@ -410,6 +423,70 @@ func cmdSha3Mct(h fips140.Hash) command {
|
|||
}
|
||||
}
|
||||
|
||||
func cmdShakeAftVot(h *sha3.SHAKE) command {
|
||||
return command{
|
||||
requiredArgs: 2, // Message, output length (bytes)
|
||||
handler: func(args [][]byte) ([][]byte, error) {
|
||||
msg := args[0]
|
||||
|
||||
outLenBytes := binary.LittleEndian.Uint32(args[1])
|
||||
digest := make([]byte, outLenBytes)
|
||||
|
||||
h.Reset()
|
||||
h.Write(msg)
|
||||
h.Read(digest)
|
||||
|
||||
return [][]byte{digest}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func cmdShakeMct(h *sha3.SHAKE) command {
|
||||
return command{
|
||||
requiredArgs: 4, // Seed message, min output length (bytes), max output length (bytes), output length (bytes)
|
||||
handler: func(args [][]byte) ([][]byte, error) {
|
||||
md := args[0]
|
||||
minOutBytes := binary.LittleEndian.Uint32(args[1])
|
||||
maxOutBytes := binary.LittleEndian.Uint32(args[2])
|
||||
|
||||
outputLenBytes := binary.LittleEndian.Uint32(args[3])
|
||||
if outputLenBytes < 2 {
|
||||
return nil, fmt.Errorf("invalid output length: %d", outputLenBytes)
|
||||
}
|
||||
|
||||
rangeBytes := maxOutBytes - minOutBytes + 1
|
||||
if rangeBytes == 0 {
|
||||
return nil, fmt.Errorf("invalid maxOutBytes and minOutBytes: %d, %d", maxOutBytes, minOutBytes)
|
||||
}
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
// "The MSG[i] input to SHAKE MUST always contain at least 128 bits. If this is not the case
|
||||
// as the previous digest was too short, append empty bits to the rightmost side of the digest."
|
||||
boundary := min(len(md), 16)
|
||||
msg := make([]byte, 16)
|
||||
copy(msg, md[:boundary])
|
||||
|
||||
// MD[i] = SHAKE(MSG[i], OutputLen * 8)
|
||||
h.Reset()
|
||||
h.Write(msg)
|
||||
digest := make([]byte, outputLenBytes)
|
||||
h.Read(digest)
|
||||
md = digest
|
||||
|
||||
// RightmostOutputBits = 16 rightmost bits of MD[i] as an integer
|
||||
// OutputLen = minOutBytes + (RightmostOutputBits % Range)
|
||||
rightmostOutput := uint32(md[outputLenBytes-2])<<8 | uint32(md[outputLenBytes-1])
|
||||
outputLenBytes = minOutBytes + (rightmostOutput % rangeBytes)
|
||||
}
|
||||
|
||||
encodedOutputLenBytes := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(encodedOutputLenBytes, outputLenBytes)
|
||||
|
||||
return [][]byte{md, encodedOutputLenBytes}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func cmdHmacAft(h func() fips140.Hash) command {
|
||||
return command{
|
||||
requiredArgs: 2, // Message and key
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue