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/&lt;HASH&gt;| Output length, entropy, personalisation, reseedAD, reseedEntropy, ad1, ad2, nonce | Output |
 | hmacDRBG-pr/&lt;HASH&gt;| 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/&lt;HASH&gt;/pkcs1v1.5 | Modulus bit-size | n, e, signature |
 | RSA/sigGen/&lt;HASH&gt;/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])