Support key wrap with padding in CAVP.

Change-Id: I27a282ee2b11083a1137990b00a9d599dd1f48df
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/36625
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/util/fipstools/cavp/cavp_keywrap_test.cc b/util/fipstools/cavp/cavp_keywrap_test.cc
index c7270df..a4abccd 100644
--- a/util/fipstools/cavp/cavp_keywrap_test.cc
+++ b/util/fipstools/cavp/cavp_keywrap_test.cc
@@ -28,15 +28,16 @@
 
 struct TestCtx {
   bool encrypt;
+  bool padding;
 };
 
-}
+}  // namespace
 
 static bool AESKeyWrap(std::vector<uint8_t> *out, bool encrypt,
                        const std::vector<uint8_t> &key,
                        const std::vector<uint8_t> &in) {
   size_t key_bits = key.size() * 8;
-  if (key_bits != 128 && key_bits != 256) {
+  if (key_bits != 128 && key_bits != 192 && key_bits != 256) {
     return false;
   }
   AES_KEY aes_key;
@@ -60,6 +61,36 @@
   return true;
 }
 
+static bool AESKeyWrapWithPadding(std::vector<uint8_t> *out, bool encrypt,
+                                  const std::vector<uint8_t> &key,
+                                  const std::vector<uint8_t> &in) {
+  const size_t key_bits = key.size() * 8;
+  if (key_bits != 128 && key_bits != 192 && key_bits != 256) {
+    return false;
+  }
+  AES_KEY aes_key;
+
+  size_t out_len;
+  if (encrypt) {
+    out->resize(in.size() + 15);
+    if (AES_set_encrypt_key(key.data(), key_bits, &aes_key) ||
+        !AES_wrap_key_padded(&aes_key, out->data(), &out_len, out->size(),
+                             in.data(), in.size())) {
+      return false;
+    }
+  } else {
+    out->resize(in.size());
+    if (AES_set_decrypt_key(key.data(), key_bits, &aes_key) ||
+        !AES_unwrap_key_padded(&aes_key, out->data(), &out_len, out->size(),
+                               in.data(), in.size())) {
+      return false;
+    }
+  }
+
+  out->resize(out_len);
+  return true;
+}
+
 static bool TestCipher(FileTest *t, void *arg) {
   TestCtx *ctx = reinterpret_cast<TestCtx *>(arg);
 
@@ -75,8 +106,13 @@
   }
   // clang-format on
 
+  auto wrap_function = AESKeyWrap;
+  if (ctx->padding) {
+    wrap_function = AESKeyWrapWithPadding;
+  }
+
   printf("%s", t->CurrentTestToString().c_str());
-  if (!AESKeyWrap(&result, ctx->encrypt, key, in)) {
+  if (!wrap_function(&result, ctx->encrypt, key, in)) {
     if (ctx->encrypt) {
       return false;
     } else {
@@ -93,7 +129,7 @@
 static int usage(char *arg) {
   fprintf(
       stderr,
-      "usage: %s (enc|dec) (128|256) <test file>\n",
+      "usage: %s (enc|dec|enc-pad|dec-pad) (128|192|256) <test file>\n",
       arg);
   return 1;
 }
@@ -104,16 +140,21 @@
   }
 
   const std::string op(argv[1]);
-  bool encrypt;
+  bool encrypt = false;
+  bool padding = false;
   if (op == "enc") {
     encrypt = true;
   } else if (op == "dec") {
-    encrypt = false;
+  } else if (op == "enc-pad") {
+    encrypt = true;
+    padding = true;
+  } else if (op == "dec-pad") {
+    padding = true;
   } else {
     return usage(argv[0]);
   }
 
-  TestCtx ctx = {encrypt};
+  TestCtx ctx = {encrypt, padding};
 
   FileTest::Options opts;
   opts.path = argv[3];
diff --git a/util/fipstools/cavp/run_cavp.go b/util/fipstools/cavp/run_cavp.go
index 438bb78..b37f453 100644
--- a/util/fipstools/cavp/run_cavp.go
+++ b/util/fipstools/cavp/run_cavp.go
@@ -283,9 +283,17 @@
 	nil,
 	[]test{
 		{"KW_AD_128", []string{"dec", "128"}, false},
+		{"KW_AD_192", []string{"dec", "192"}, false},
 		{"KW_AD_256", []string{"dec", "256"}, false},
 		{"KW_AE_128", []string{"enc", "128"}, false},
+		{"KW_AE_192", []string{"enc", "192"}, false},
 		{"KW_AE_256", []string{"enc", "256"}, false},
+		{"KWP_AD_128", []string{"dec-pad", "128"}, false},
+		{"KWP_AD_192", []string{"dec-pad", "192"}, false},
+		{"KWP_AD_256", []string{"dec-pad", "256"}, false},
+		{"KWP_AE_128", []string{"enc-pad", "128"}, false},
+		{"KWP_AE_192", []string{"enc-pad", "192"}, false},
+		{"KWP_AE_256", []string{"enc-pad", "256"}, false},
 	},
 }