util/fipstools: support feedback KDF w/ empty IVs The module wrapper I'm testing supports feedback mode KDF w/ HKDF using an 8 bit counter and no IV. This commit updates the subprocess handling for the KDF algorithm to support this use-case. By offering feedback-mode support with empty IV only the diff is quite minimal. Module wrappers are assumed to use a capability with both "supportsEmptyIv":true and "requiresEmptyIv":true. See the NIST KDF ACVP spec for more information: https://pages.nist.gov/ACVP/draft-celi-acvp-kbkdf.html Change-Id: I30eb9d0e8bb88c793d05014e4d98e034675f13b6 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/74747 Reviewed-by: Adam Langley <agl@google.com> Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/util/fipstools/acvp/ACVP.md b/util/fipstools/acvp/ACVP.md index 38700ac..fc14a85 100644 --- a/util/fipstools/acvp/ACVP.md +++ b/util/fipstools/acvp/ACVP.md
@@ -97,6 +97,7 @@ | hmacDRBG-reseed/<HASH>| Output length, entropy, personalisation, reseedAD, reseedEntropy, ad1, ad2, nonce | Output | | hmacDRBG-pr/<HASH>| Output length, entropy, personalisation, ad1, entropy1, ad2, entropy2, nonce | Output | | KDF-counter | Number output bytes, PRF name, counter location string, key (or empty), number of counter bits | key, counter, derived key | +| KDF-feedback | Number output bytes, PRF name, counter location string, key (or empty), number of counter bits | key, counter, derived key | | RSA/keyGen | Modulus bit-size | e, p, q, n, d | | RSA/sigGen/<HASH>/pkcs1v1.5 | Modulus bit-size | n, e, signature | | RSA/sigGen/<HASH>/pss | Modulus bit-size | n, e, signature |
diff --git a/util/fipstools/acvp/acvptool/subprocess/kdf.go b/util/fipstools/acvp/acvptool/subprocess/kdf.go index b4e6ca6..0f4e744 100644 --- a/util/fipstools/acvp/acvptool/subprocess/kdf.go +++ b/util/fipstools/acvp/acvptool/subprocess/kdf.go
@@ -75,12 +75,15 @@ return nil, fmt.Errorf("%d bit key in test group %d: fractional bytes not supported", group.OutputBits, group.ID) } - if group.KDFMode != "counter" { - // feedback mode would need the IV to be handled. + if group.KDFMode != "counter" && group.KDFMode != "feedback" { // double-pipeline mode is not useful. return nil, fmt.Errorf("KDF mode %q not supported", group.KDFMode) } + if group.KDFMode == "feedback" && !group.ZeroIV { + return nil, fmt.Errorf("feedback mode with non-zero IV not supported") + } + switch group.CounterLocation { case "after fixed data", "before fixed data": break @@ -108,7 +111,11 @@ } // Make the call to the crypto module. - m.TransactAsync("KDF-counter", 3, [][]byte{outputBytes, []byte(group.MACMode), []byte(group.CounterLocation), key, counterBits}, func(result [][]byte) error { + cmd := "KDF-counter" + if group.KDFMode == "feedback" { + cmd = "KDF-feedback" + } + m.TransactAsync(cmd, 3, [][]byte{outputBytes, []byte(group.MACMode), []byte(group.CounterLocation), key, counterBits}, func(result [][]byte) error { testResp.ID = test.ID if test.Deferred { testResp.KeyIn = hex.EncodeToString(result[0])