Skip to content

Commit 98f3f44

Browse files
cpuFiloSottile
authored andcommitted
crypto/internal/fips140test: add feedback KDF ACVP tests
Adds ACVP test coverage for the SP 800-108r1 KDF feedback mode algorithm based on the NIST spec: https://pages.nist.gov/ACVP/draft-celi-acvp-kbkdf.html The HKDF-based implementation in our FIPS module fixes some parameters, requiring tailoring of the advertised capability to match. Notably: * We only support fixedDataOrder "after fixed data" * We only support a counter length of 8 bits * We only support empty IVs No acvp_test.config.json update accompanies this support because the ACVP tests for this algorithm aren't amenable to fixed data testing. Updates golang#69642 Change-Id: I729e899377a64d2b613d6435241aebabeef93bca
1 parent ed997da commit 98f3f44

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

src/crypto/internal/fips140test/acvp_capabilities.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969

7070
{"algorithm":"KAS-ECC-SSC","revision":"Sp800-56Ar3","scheme":{"ephemeralUnified":{"kasRole":["initiator","responder"]},"staticUnified":{"kasRole":["initiator","responder"]}},"domainParameterGenerationMethods":["P-224","P-256","P-384","P-521"]},
7171

72-
{"algorithm":"KDF","revision":"1.0","capabilities":[{"kdfMode":"counter","macMode":["CMAC-AES128","CMAC-AES192","CMAC-AES256"],"supportedLengths":[256],"fixedDataOrder":["before fixed data"],"counterLength":[16]}]},
72+
{"algorithm":"KDF","revision":"1.0","capabilities":[{"kdfMode":"counter","macMode":["CMAC-AES128","CMAC-AES192","CMAC-AES256"],"supportedLengths":[256],"fixedDataOrder":["before fixed data"],"counterLength":[16]},{"kdfMode":"feedback","macMode":["HMAC-SHA2-224","HMAC-SHA2-256","HMAC-SHA2-384","HMAC-SHA2-512","HMAC-SHA2-512/224","HMAC-SHA2-512/256","HMAC-SHA3-224","HMAC-SHA3-256","HMAC-SHA3-384","HMAC-SHA3-512"],"customKeyInLength":0,"supportedLengths":[{"min":8,"max":4096,"increment":8}],"fixedDataOrder":["after fixed data"],"counterLength":[8],"supportsEmptyIv":true,"requiresEmptyIv":true}]},
7373

7474
{"algorithm":"RSA","mode":"keyGen","revision":"FIPS186-5","infoGeneratedByServer":true,"pubExpMode":"fixed","fixedPubExp":"010001","keyFormat":"standard","capabilities":[{"randPQ":"probable","properties":[{"modulo":2048,"primeTest":["2powSecStr"]},{"modulo":3072,"primeTest":["2powSecStr"]},{"modulo":4096,"primeTest":["2powSecStr"]}]}]},
7575
{"algorithm":"RSA","mode":"sigGen","revision":"FIPS186-5","capabilities":[{"sigType":"pkcs1v1.5","properties":[{"modulo":2048,"hashPair":[{"hashAlg":"SHA2-224"},{"hashAlg":"SHA2-256"},{"hashAlg":"SHA2-384"},{"hashAlg":"SHA2-512"}]},{"modulo":3072,"hashPair":[{"hashAlg":"SHA2-224"},{"hashAlg":"SHA2-256"},{"hashAlg":"SHA2-384"},{"hashAlg":"SHA2-512"}]},{"modulo":4096,"hashPair":[{"hashAlg":"SHA2-224"},{"hashAlg":"SHA2-256"},{"hashAlg":"SHA2-384"},{"hashAlg":"SHA2-512"}]}]},{"sigType":"pss","properties":[{"maskFunction":["mgf1"],"modulo":2048,"hashPair":[{"hashAlg":"SHA2-224","saltLen":28},{"hashAlg":"SHA2-256","saltLen":32},{"hashAlg":"SHA2-384","saltLen":48},{"hashAlg":"SHA2-512","saltLen":64}]},{"maskFunction":["mgf1"],"modulo":3072,"hashPair":[{"hashAlg":"SHA2-224","saltLen":28},{"hashAlg":"SHA2-256","saltLen":32},{"hashAlg":"SHA2-384","saltLen":48},{"hashAlg":"SHA2-512","saltLen":64}]},{"maskFunction":["mgf1"],"modulo":4096,"hashPair":[{"hashAlg":"SHA2-224","saltLen":28},{"hashAlg":"SHA2-256","saltLen":32},{"hashAlg":"SHA2-384","saltLen":48},{"hashAlg":"SHA2-512","saltLen":64}]}]}]},

src/crypto/internal/fips140test/acvp_test.go

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ var (
131131
// https://pages.nist.gov/ACVP/draft-hammett-acvp-kas-ssc-ecc.html#section-7.3
132132
// HMAC DRBG and CTR DRBG algorithm capabilities:
133133
// https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#section-7.2
134-
// KDF-Counter algorithm capabilities:
134+
// KDF-Counter and KDF-Feedback algorithm capabilities:
135135
// https://pages.nist.gov/ACVP/draft-celi-acvp-kbkdf.html#section-7.3
136136
// RSA algorithm capabilities:
137137
// https://pages.nist.gov/ACVP/draft-celi-acvp-rsa.html#section-7.3
@@ -268,8 +268,6 @@ var (
268268
"ctrDRBG/AES-256": cmdCtrDrbgAft(),
269269
"ctrDRBG-reseed/AES-256": cmdCtrDrbgReseedAft(),
270270

271-
"KDF-counter": cmdKdfCounterAft(),
272-
273271
"RSA/keyGen": cmdRsaKeyGenAft(),
274272

275273
"RSA/sigGen/SHA2-224/pkcs1v1.5": cmdRsaSigGenAft(func() fips140.Hash { return sha256.New224() }, "SHA-224", false),
@@ -289,6 +287,9 @@ var (
289287
"RSA/sigVer/SHA2-256/pss": cmdRsaSigVerAft(func() fips140.Hash { return sha256.New() }, "SHA-256", true),
290288
"RSA/sigVer/SHA2-384/pss": cmdRsaSigVerAft(func() fips140.Hash { return sha512.New384() }, "SHA-384", true),
291289
"RSA/sigVer/SHA2-512/pss": cmdRsaSigVerAft(func() fips140.Hash { return sha512.New() }, "SHA-512", true),
290+
291+
"KDF-counter": cmdKdfCounterAft(),
292+
"KDF-feedback": cmdKdfFeedbackAft(),
292293
}
293294
)
294295

@@ -1651,6 +1652,57 @@ func cmdKdfCounterAft() command {
16511652
}
16521653
}
16531654

1655+
func cmdKdfFeedbackAft() command {
1656+
return command{
1657+
requiredArgs: 5, // Number output bytes, PRF name, counter location string, key, number of counter bits, IV
1658+
handler: func(args [][]byte) ([][]byte, error) {
1659+
// The max supported output len for the KDF algorithm type is 4096 bits, making an int cast
1660+
// here safe.
1661+
// See https://pages.nist.gov/ACVP/draft-celi-acvp-kbkdf.html#section-7.3.2
1662+
outputBytes := int(binary.LittleEndian.Uint32(args[0]))
1663+
prf := string(args[1])
1664+
counterLocation := args[2]
1665+
key := args[3]
1666+
counterBits := binary.LittleEndian.Uint32(args[4])
1667+
1668+
if !strings.HasPrefix(prf, "HMAC-") {
1669+
return nil, fmt.Errorf("feedback KDF received unsupported PRF %q", prf)
1670+
}
1671+
prf = prf[len("HMAC-"):]
1672+
1673+
h, err := lookupHash(prf)
1674+
if err != nil {
1675+
return nil, fmt.Errorf("feedback KDF received unsupported PRF %q: %w", prf, err)
1676+
}
1677+
1678+
if !bytes.Equal(counterLocation, []byte("after fixed data")) {
1679+
return nil, fmt.Errorf("feedback KDF received unsupported counter location %q", string(counterLocation))
1680+
}
1681+
1682+
// The spec doesn't describe the "deferred" property for a KDF counterMode test case.
1683+
// BoringSSL's acvptool sends an empty key when deferred=true, but with the capabilities
1684+
// we register all test cases have deferred=false and provide a key from the populated
1685+
// keyIn property.
1686+
if len(key) == 0 {
1687+
return nil, errors.New("deferred test cases are not supported")
1688+
}
1689+
1690+
if counterBits != 8 {
1691+
return nil, fmt.Errorf("feedback KDF received unsupported counter length %d", counterBits)
1692+
}
1693+
1694+
var context [12]byte
1695+
rand.Reader.Read(context[:])
1696+
fixedData := make([]byte, 1+1+12) // 1 byte label (we pick null), 1 null byte, 12 bytes context.
1697+
copy(fixedData[2:], context[:])
1698+
1699+
result := hkdf.Expand(h, key, string(fixedData[:]), outputBytes)
1700+
1701+
return [][]byte{key, fixedData[:], result[:]}, nil
1702+
},
1703+
}
1704+
}
1705+
16541706
func cmdRsaKeyGenAft() command {
16551707
return command{
16561708
requiredArgs: 1, // Modulus bit-size
@@ -1775,7 +1827,7 @@ func TestACVP(t *testing.T) {
17751827

17761828
const (
17771829
bsslModule = "boringssl.googlesource.com/boringssl.git"
1778-
bsslVersion = "v0.0.0-20250116010235-21f54b2730ee"
1830+
bsslVersion = "v0.0.0-20250123161947-ba24bde161f7"
17791831
goAcvpModule = "github.com/cpu/go-acvp"
17801832
goAcvpVersion = "v0.0.0-20250110181646-e47fea3b5d7d"
17811833
)

0 commit comments

Comments
 (0)