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])