Blame SOURCES/nss-3.53.1-ike-app-b-fix.patch

8b3762
diff -up ./gtests/common/testvectors_base/test-structs.h.orig ./gtests/common/testvectors_base/test-structs.h
8b3762
--- ./gtests/common/testvectors_base/test-structs.h.orig	2020-06-16 15:50:59.000000000 -0700
8b3762
+++ ./gtests/common/testvectors_base/test-structs.h	2020-12-05 10:54:36.648849921 -0800
8b3762
@@ -66,6 +66,31 @@ typedef struct EcdhTestVectorStr {
8b3762
   bool valid;
8b3762
 } EcdhTestVector;
8b3762
 
8b3762
+enum class IkeTestType {
8b3762
+  ikeGxy,         /* CKM_NSS_IKE_PRF_DERIVE case 1 */
8b3762
+  ikeV1Psk,       /* CKM_NSS_IKE_PRF_DERIVE case 2 */
8b3762
+  ikeV2Rekey,    /* CKM_NSS_IKE_PRF_DERIVE case 3 */
8b3762
+  ikeV1,          /* CKM_NSS_IKE1_PRF_DERIVE */
8b3762
+  ikeV1AppB,      /* CKM_NSS_IKE1_PRF_APP_B_DERIVE base mode */
8b3762
+  ikeV1AppBQuick, /* CKM_NSS_IKE1_PRF_APP_B_DERIVE quick mode */
8b3762
+  ikePlus         /* CKM_NSS_IKE_PRF_DERIVE */
8b3762
+};
8b3762
+
8b3762
+typedef struct IkeTestVectorStr {
8b3762
+  uint32_t id;
8b3762
+  IkeTestType test_type;
8b3762
+  std::string ikm;
8b3762
+  std::string gxykm;
8b3762
+  std::string prevkm;
8b3762
+  std::string okm;
8b3762
+  std::string Ni;
8b3762
+  std::string Nr;
8b3762
+  std::string seed_data;
8b3762
+  uint8_t key_number;
8b3762
+  uint32_t size;
8b3762
+  bool valid;
8b3762
+} IkeTestVector;
8b3762
+
8b3762
 typedef struct RsaSignatureTestVectorStr {
8b3762
   SECOidTag hash_oid;
8b3762
   uint32_t id;
8b3762
diff -up ./gtests/common/testvectors/ike-sha1-vectors.h.orig ./gtests/common/testvectors/ike-sha1-vectors.h
8b3762
--- ./gtests/common/testvectors/ike-sha1-vectors.h.orig	2020-12-05 10:54:36.649849926 -0800
8b3762
+++ ./gtests/common/testvectors/ike-sha1-vectors.h	2020-12-05 11:01:09.170017713 -0800
8b3762
@@ -0,0 +1,114 @@
8b3762
+/* vim: set ts=2 et sw=2 tw=80: */
8b3762
+/* This Source Code Form is subject to the terms of the Mozilla Public
8b3762
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
8b3762
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
8b3762
+
8b3762
+/* This file is generated from sources in nss/gtests/common/wycheproof
8b3762
+ * automatically and should not be touched manually.
8b3762
+ * Generation is trigged by calling python3 genTestVectors.py */
8b3762
+
8b3762
+#ifndef ike_sha1_vectors_h__
8b3762
+#define ike_sha1_vectors_h__
8b3762
+
8b3762
+#include "testvectors_base/test-structs.h"
8b3762
+
8b3762
+const IkeTestVector kIkeSha1ProofVectors[] = {
8b3762
+    // these vectors are from this NIST samples
8b3762
+    {1, IkeTestType::ikeGxy, 
8b3762
+     "8ba4cbc73c0187301dc19a975823854dbd641c597f637f8d053a83b9514673eb",
8b3762
+     "", "", "707197817fb2d90cf54d1842606bdea59b9f4823",
8b3762
+     "69a62284195f1680", "80c94ba25c8abda5",
8b3762
+     "", 0, 0, true },
8b3762
+    {2, IkeTestType::ikeV1, 
8b3762
+     "707197817fb2d90cf54d1842606bdea59b9f4823",
8b3762
+     "8ba4cbc73c0187301dc19a975823854dbd641c597f637f8d053a83b9514673eb",
8b3762
+     "", "384be709a8a5e63c3ed160cfe3921c4b37d5b32d",
8b3762
+     "8c3bcd3a69831d7f", "d2d9a7ff4fbe95a7",
8b3762
+     "", 0, 0, true },
8b3762
+    {3, IkeTestType::ikeV1, 
8b3762
+     "707197817fb2d90cf54d1842606bdea59b9f4823",
8b3762
+     "8ba4cbc73c0187301dc19a975823854dbd641c597f637f8d053a83b9514673eb",
8b3762
+     "384be709a8a5e63c3ed160cfe3921c4b37d5b32d",
8b3762
+     "48b327575abe3adba0f279849e289022a13e2b47",
8b3762
+     "8c3bcd3a69831d7f", "d2d9a7ff4fbe95a7",
8b3762
+     "", 1, 0, true },
8b3762
+    {4, IkeTestType::ikeV1, 
8b3762
+     "707197817fb2d90cf54d1842606bdea59b9f4823",
8b3762
+     "8ba4cbc73c0187301dc19a975823854dbd641c597f637f8d053a83b9514673eb",
8b3762
+     "48b327575abe3adba0f279849e289022a13e2b47",
8b3762
+     "a4a415c8e0c38c0da847c356cc61c24df8025560",
8b3762
+     "8c3bcd3a69831d7f", "d2d9a7ff4fbe95a7",
8b3762
+     "", 2, 0, true },
8b3762
+    {5, IkeTestType::ikeV1Psk, "c0", "", "",
8b3762
+     "ab3be41bc62f2ef0c41a3076d58768be77fadd2e",
8b3762
+     "03a6f25a83c8c2a3", "9d958a6618f77e7f",
8b3762
+     "", 0, 0, true },
8b3762
+    {6, IkeTestType::ikeGxy, 
8b3762
+     "4b2c1f971981a8ad8d0abeafabf38cf75fc8349c148142465ed9c8b516b8be52",
8b3762
+     "", "", "a9a7b222b59f8f48645f28a1db5b5f5d7479cba7",
8b3762
+     "32b50d5f4a3763f3", "9206a04b26564cb1",
8b3762
+     "", 0, 0, true },
8b3762
+    {7, IkeTestType::ikeV2Rekey, 
8b3762
+     "a14293677cc80ff8f9cc0eee30d895da9d8f4056",
8b3762
+     "863f3c9d06efd39d2b907b97f8699e5dd5251ef64a2a176f36ee40c87d4f9330",
8b3762
+     "", "63e81194946ebd05df7df5ebf5d8750056bf1f1d",
8b3762
+     "32b50d5f4a3763f3", "9206a04b26564cb1",
8b3762
+     "", 0, 0, true },
8b3762
+    {8, IkeTestType::ikePlus, 
8b3762
+     "a9a7b222b59f8f48645f28a1db5b5f5d7479cba7", "", "", 
8b3762
+     "a14293677cc80ff8f9cc0eee30d895da9d8f405666e30ef0dfcb63c634a46002a2a63080e514a062768b76606f9fa5e992204fc5a670bde3f10d6b027113936a5c55b648a194ae587b0088d52204b702c979fa280870d2ed41efa9c549fd11198af1670b143d384bd275c5f594cf266b05ebadca855e4249520a441a81157435a7a56cc4", "", "",
8b3762
+     // seed_data is Ni || Nr || SPIi || SPIr
8b3762
+     // NOTE: there is no comma so the strings are concatenated together.
8b3762
+     "32b50d5f4a3763f3" // Ni
8b3762
+     "9206a04b26564cb1" // Nr
8b3762
+     "34c9e7c188868785" // SPIi
8b3762
+     "3ff77d760d2b2199", // SPIr
8b3762
+     0, 132, true },
8b3762
+    {9, IkeTestType::ikePlus, 
8b3762
+     "a9a7b222b59f8f48645f28a1db5b5f5d7479cba7", "", "", 
8b3762
+     "a14293677cc80ff8f9cc0eee30d895da9d8f405666e30ef0dfcb63c634a46002a2a63080e514a062", "", "",
8b3762
+     // seed_data is Ni || Nr || SPIi || SPIr
8b3762
+     // NOTE: there is no comma so the strings are concatenated together.
8b3762
+     "32b50d5f4a3763f3" // Ni
8b3762
+     "9206a04b26564cb1" // Nr
8b3762
+     "34c9e7c188868785" // SPIi
8b3762
+     "3ff77d760d2b2199", // SPIr
8b3762
+     0, 40, true },
8b3762
+    {10, IkeTestType::ikePlus, 
8b3762
+     "a9a7b222b59f8f48645f28a1db5b5f5d7479cba7", "", "", 
8b3762
+     "a14293677cc80ff8f9cc0eee30d895", "", "",
8b3762
+     // seed_data is Ni || Nr || SPIi || SPIr
8b3762
+     // NOTE: there is no comma so the strings are concatenated together.
8b3762
+     "32b50d5f4a3763f3" // Ni
8b3762
+     "9206a04b26564cb1" // Nr
8b3762
+     "34c9e7c188868785" // SPIi
8b3762
+     "3ff77d760d2b2199", // SPIr
8b3762
+     0, 15, true },
8b3762
+    // these vectors are self-generated 
8b3762
+    {11, IkeTestType::ikeV1AppB, 
8b3762
+     "63e81194946ebd05df7df5ebf5d8750056bf1f1d", "", "", 
8b3762
+     "933347a07de5782247dd36d1562ffe0eecade1eb4134165257e3af1000af8ae3f165063828cbb60d910b7db38fa3c7f62c4afaaf3203da065c841729853edb23e9e7ac8286ae65c8cb6c667d79268c0bd6705abb9131698eb822b1c1f9dd142fc7be2c1010ee0152e10195add98999c6b6d42c8fe9c1b134d56ad5f2c6f20e815bd25c52",
8b3762
+     "", "", "", 0, 132, true },
8b3762
+    {12, IkeTestType::ikeV1AppB, 
8b3762
+     "63e81194946ebd05df7df5ebf5d8750056bf1f1d", "", "", 
8b3762
+     "933347a07de5782247dd36d1562ffe0eecade1eb4134165257e3af1000af8ae3f165063828cbb60d",
8b3762
+     "", "", "", 0, 40, true },
8b3762
+    {13, IkeTestType::ikeV1AppB, 
8b3762
+     "63e81194946ebd05df7df5ebf5d8750056bf1f1d", "", "",
8b3762
+     "63e81194946ebd05df7df5ebf5d875",
8b3762
+     "", "", "", 0, 15, true },
8b3762
+    {14, IkeTestType::ikeV1AppBQuick, 
8b3762
+     "63e81194946ebd05df7df5ebf5d8750056bf1f1d", "", "",
8b3762
+     "933347a07de5782247dd36d1562ffe0eecade1ebaeaa476a5f578c34a9b2b7101a621202f61db924c5ef9efa3bb2698095841603b7ac8a880329a927ecd4ad53a944b607a5ac2f3d154e2748c188d7370d76be83fc204fdacf0f66b99dd760ba619ffac65eda1420c8a936dac5a599afaf4043b29ef2b65dc042724355b550875316c6fd",
8b3762
+     "", "", "0", 0, 132, true },
8b3762
+    {15, IkeTestType::ikeV1AppBQuick, 
8b3762
+     "63e81194946ebd05df7df5ebf5d8750056bf1f1d", "", "",
8b3762
+     "933347a07de5782247dd36d1562ffe0eecade1ebaeaa476a5f578c34a9b2b7101a621202f61db924",
8b3762
+     "", "", "0", 0, 40, true },
8b3762
+    {16, IkeTestType::ikeV1AppBQuick, 
8b3762
+     "63e81194946ebd05df7df5ebf5d8750056bf1f1d", "", "",
8b3762
+     "933347a07de5782247dd36d1562ffe",
8b3762
+     "", "", "0", 0, 15, true },
8b3762
+     };
8b3762
+
8b3762
+#endif  // ike_sha1_vectors_h__
8b3762
diff -up ./gtests/pk11_gtest/manifest.mn.orig ./gtests/pk11_gtest/manifest.mn
8b3762
--- ./gtests/pk11_gtest/manifest.mn.orig	2020-12-05 10:53:12.529385354 -0800
8b3762
+++ ./gtests/pk11_gtest/manifest.mn	2020-12-05 10:54:36.649849926 -0800
8b3762
@@ -22,6 +22,7 @@ CPPSRCS = \
8b3762
       pk11_export_unittest.cc \
8b3762
       pk11_find_certs_unittest.cc \
8b3762
       pk11_hkdf_unittest.cc \
8b3762
+      pk11_ike_unittest.cc \
8b3762
       pk11_import_unittest.cc \
8b3762
       pk11_kdf_unittest.cc \
8b3762
       pk11_kbkdf.cc \
8b3762
diff -up ./gtests/pk11_gtest/pk11_gtest.gyp.orig ./gtests/pk11_gtest/pk11_gtest.gyp
8b3762
--- ./gtests/pk11_gtest/pk11_gtest.gyp.orig	2020-06-16 15:50:59.000000000 -0700
8b3762
+++ ./gtests/pk11_gtest/pk11_gtest.gyp	2020-12-05 10:54:36.649849926 -0800
8b3762
@@ -27,6 +27,7 @@
8b3762
         'pk11_encrypt_derive_unittest.cc',
8b3762
         'pk11_find_certs_unittest.cc',
8b3762
         'pk11_hkdf_unittest.cc',
8b3762
+        'pk11_ike_unittest.cc',
8b3762
         'pk11_import_unittest.cc',
8b3762
         'pk11_kbkdf.cc',
8b3762
         'pk11_keygen.cc',
8b3762
diff -up ./gtests/pk11_gtest/pk11_ike_unittest.cc.orig ./gtests/pk11_gtest/pk11_ike_unittest.cc
8b3762
--- ./gtests/pk11_gtest/pk11_ike_unittest.cc.orig	2020-12-05 10:54:36.649849926 -0800
8b3762
+++ ./gtests/pk11_gtest/pk11_ike_unittest.cc	2020-12-05 10:54:36.649849926 -0800
8b3762
@@ -0,0 +1,197 @@
8b3762
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
8b3762
+/* vim: set ts=2 et sw=2 tw=80: */
8b3762
+/* This Source Code Form is subject to the terms of the Mozilla Public
8b3762
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
8b3762
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
8b3762
+
8b3762
+#include <memory>
8b3762
+#include "blapi.h"
8b3762
+#include "gtest/gtest.h"
8b3762
+#include "nss.h"
8b3762
+#include "nss_scoped_ptrs.h"
8b3762
+#include "pk11pub.h"
8b3762
+#include "secerr.h"
8b3762
+#include "sechash.h"
8b3762
+#include "util.h"
8b3762
+
8b3762
+#include "testvectors/ike-sha1-vectors.h"
8b3762
+#ifdef notdef
8b3762
+#include "testvectors/ike-sha256-vectors.h"
8b3762
+#include "testvectors/ike-aesxcbc-vectors.h"
8b3762
+#endif
8b3762
+
8b3762
+namespace nss_test {
8b3762
+
8b3762
+class Pkcs11IkeTest
8b3762
+    : public ::testing::TestWithParam<
8b3762
+          std::tuple<IkeTestVector, CK_MECHANISM_TYPE>> {
8b3762
+ protected:
8b3762
+  void dump_item(const char *label, SECItem *item) {
8b3762
+   printf("%s: %d bytes { \"",label, item->len);
8b3762
+   unsigned int i;
8b3762
+   for (i=0; i < item->len; i++) {
8b3762
+      printf("%02x",item->data[i]);
8b3762
+   }
8b3762
+   printf("\"\n");
8b3762
+  }
8b3762
+
8b3762
+  ScopedPK11SymKey ImportKey(SECItem &ikm_item) {
8b3762
+    ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
8b3762
+    if (!slot) {
8b3762
+      ADD_FAILURE() << "Can't get slot";
8b3762
+      return nullptr;
8b3762
+    }
8b3762
+    ScopedPK11SymKey ikm(PK11_ImportSymKey(slot.get(), 
8b3762
+                                  CKM_GENERIC_SECRET_KEY_GEN,
8b3762
+                                  PK11_OriginUnwrap, CKA_DERIVE, &ikm_item,
8b3762
+                                  nullptr));
8b3762
+    return ikm;
8b3762
+  }
8b3762
+
8b3762
+  void RunVectorTest(const IkeTestVector &vec, CK_MECHANISM_TYPE prf_mech) {
8b3762
+    std::string msg = "Test #" + std::to_string(vec.id) + " failed";
8b3762
+    std::vector<uint8_t> vec_ikm = hex_string_to_bytes(vec.ikm);
8b3762
+    std::vector<uint8_t> vec_okm = hex_string_to_bytes(vec.okm);
8b3762
+    std::vector<uint8_t> vec_gxykm = hex_string_to_bytes(vec.gxykm);
8b3762
+    std::vector<uint8_t> vec_prevkm = hex_string_to_bytes(vec.prevkm);
8b3762
+    std::vector<uint8_t> vec_Ni = hex_string_to_bytes(vec.Ni);
8b3762
+    std::vector<uint8_t> vec_Nr = hex_string_to_bytes(vec.Nr);
8b3762
+    std::vector<uint8_t> vec_seed_data = hex_string_to_bytes(vec.seed_data);
8b3762
+    SECItem ikm_item = {siBuffer, vec_ikm.data(),
8b3762
+                        static_cast<unsigned int>(vec_ikm.size())};
8b3762
+    SECItem okm_item = {siBuffer, vec_okm.data(),
8b3762
+                        static_cast<unsigned int>(vec_okm.size())};
8b3762
+    SECItem prevkm_item = {siBuffer, vec_prevkm.data(),
8b3762
+                         static_cast<unsigned int>(vec_prevkm.size())};
8b3762
+    SECItem gxykm_item = {siBuffer, vec_gxykm.data(),
8b3762
+                         static_cast<unsigned int>(vec_gxykm.size())};
8b3762
+    CK_MECHANISM_TYPE derive_mech = CKM_NSS_IKE_PRF_DERIVE;
8b3762
+    ScopedPK11SymKey gxy_key= nullptr;
8b3762
+    ScopedPK11SymKey prev_key= nullptr;
8b3762
+    ScopedPK11SymKey ikm = ImportKey(ikm_item);
8b3762
+
8b3762
+    // IKE_PRF structure (used in cases 1, 2 and 3) 
8b3762
+    CK_NSS_IKE_PRF_DERIVE_PARAMS nss_ike_prf_params = {
8b3762
+        prf_mech, false, false,
8b3762
+        vec_Ni.data(), static_cast<CK_ULONG>(vec_Ni.size()),
8b3762
+        vec_Nr.data(), static_cast<CK_ULONG>(vec_Nr.size()),
8b3762
+        CK_INVALID_HANDLE
8b3762
+    };
8b3762
+
8b3762
+    // IKE_V1_PRF, used to derive session keys.
8b3762
+    CK_NSS_IKE1_PRF_DERIVE_PARAMS nss_ike_v1_prf_params = {
8b3762
+        prf_mech, false, CK_INVALID_HANDLE, CK_INVALID_HANDLE,
8b3762
+        vec_Ni.data(), static_cast<CK_ULONG>(vec_Ni.size()),
8b3762
+        vec_Nr.data(), static_cast<CK_ULONG>(vec_Nr.size()),
8b3762
+        vec.key_number
8b3762
+    };
8b3762
+
8b3762
+    // IKE_V1_APP_B, do quick mode (all session keys in one call).
8b3762
+    CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS nss_ike_app_b_prf_params_quick = {
8b3762
+        prf_mech, false, CK_INVALID_HANDLE,
8b3762
+        vec_seed_data.data(), static_cast<CK_ULONG>(vec_seed_data.size())
8b3762
+    };
8b3762
+
8b3762
+    // IKE_V1_APP_B, used for long session keys in ike_v1
8b3762
+    CK_MECHANISM_TYPE nss_ike_app_b_prf_params = prf_mech;
8b3762
+
8b3762
+    // IKE_PRF_PLUS, used to generate session keys in ike v2
8b3762
+    CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS nss_ike_prf_plus_params = {
8b3762
+        prf_mech, false, CK_INVALID_HANDLE, 
8b3762
+        vec_seed_data.data(), static_cast<CK_ULONG>(vec_seed_data.size())
8b3762
+    };
8b3762
+    
8b3762
+                                             
8b3762
+    SECItem params_item = {siBuffer, (unsigned char *)&nss_ike_prf_params,
8b3762
+                           sizeof(nss_ike_prf_params)};
8b3762
+
8b3762
+    switch (vec.test_type) {
8b3762
+      case IkeTestType::ikeGxy:
8b3762
+        nss_ike_prf_params.bDataAsKey = true;
8b3762
+        break;
8b3762
+      case IkeTestType::ikeV1Psk:
8b3762
+        break;
8b3762
+      case IkeTestType::ikeV2Rekey:
8b3762
+        nss_ike_prf_params.bRekey = true;
8b3762
+        gxy_key = ImportKey(gxykm_item);
8b3762
+        nss_ike_prf_params.hNewKey = PK11_GetSymKeyHandle(gxy_key.get());
8b3762
+        break;
8b3762
+      case IkeTestType::ikeV1:
8b3762
+        derive_mech = CKM_NSS_IKE1_PRF_DERIVE;
8b3762
+        params_item.data = (unsigned char *) &nss_ike_v1_prf_params;
8b3762
+        params_item.len = sizeof(nss_ike_v1_prf_params);
8b3762
+        gxy_key = ImportKey(gxykm_item);
8b3762
+        nss_ike_v1_prf_params.hKeygxy = PK11_GetSymKeyHandle(gxy_key.get());
8b3762
+        if (prevkm_item.len != 0) {
8b3762
+            prev_key = ImportKey(prevkm_item);
8b3762
+            nss_ike_v1_prf_params.bHasPrevKey = true;
8b3762
+            nss_ike_v1_prf_params.hPrevKey = PK11_GetSymKeyHandle(prev_key.get());
8b3762
+        }
8b3762
+        break;
8b3762
+      case IkeTestType::ikeV1AppB:
8b3762
+        derive_mech = CKM_NSS_IKE1_APP_B_PRF_DERIVE;
8b3762
+        params_item.data = (unsigned char *) &nss_ike_app_b_prf_params;
8b3762
+        params_item.len = sizeof(nss_ike_app_b_prf_params);
8b3762
+        break;
8b3762
+      case IkeTestType::ikeV1AppBQuick:
8b3762
+        derive_mech = CKM_NSS_IKE1_APP_B_PRF_DERIVE;
8b3762
+        params_item.data = (unsigned char *) &nss_ike_app_b_prf_params_quick;
8b3762
+        params_item.len = sizeof(nss_ike_app_b_prf_params_quick);
8b3762
+        if (gxykm_item.len != 0) {
8b3762
+            gxy_key = ImportKey(gxykm_item);
8b3762
+            nss_ike_app_b_prf_params_quick.bHasKeygxy = true;
8b3762
+            nss_ike_app_b_prf_params_quick.hKeygxy = 
8b3762
+                 PK11_GetSymKeyHandle(gxy_key.get());
8b3762
+        }
8b3762
+        break;
8b3762
+      case IkeTestType::ikePlus:
8b3762
+        derive_mech = CKM_NSS_IKE_PRF_PLUS_DERIVE;
8b3762
+        params_item.data = (unsigned char *) &nss_ike_prf_plus_params;
8b3762
+        params_item.len = sizeof(nss_ike_prf_plus_params);
8b3762
+        break;
8b3762
+      default:
8b3762
+        ADD_FAILURE() << msg;
8b3762
+        return;
8b3762
+    }
8b3762
+    ASSERT_NE(nullptr, ikm) << msg;
8b3762
+
8b3762
+    ScopedPK11SymKey okm = ScopedPK11SymKey(
8b3762
+        PK11_Derive(ikm.get(), derive_mech, &params_item,
8b3762
+                    CKM_GENERIC_SECRET_KEY_GEN, CKA_DERIVE, vec.size));
8b3762
+    if (vec.valid) {
8b3762
+      ASSERT_NE(nullptr, okm.get()) << msg;
8b3762
+      ASSERT_EQ(SECSuccess, PK11_ExtractKeyValue(okm.get())) << msg;
8b3762
+      SECItem *outItem = PK11_GetKeyData(okm.get());
8b3762
+      if (SECITEM_CompareItem(&okm_item, outItem) != 0) {
8b3762
+         dump_item("expected key:", &okm_item);
8b3762
+         dump_item("calculated key:", outItem);
8b3762
+      }
8b3762
+      ASSERT_EQ(0, SECITEM_CompareItem(&okm_item, PK11_GetKeyData(okm.get())))
8b3762
+          << msg;
8b3762
+    } else {
8b3762
+      ASSERT_EQ(nullptr, okm.get()) << msg;
8b3762
+    }
8b3762
+  }
8b3762
+};
8b3762
+
8b3762
+TEST_P(Pkcs11IkeTest, IkeproofVectors) {
8b3762
+  RunVectorTest(std::get<0>(GetParam()), std::get<1>(GetParam()));
8b3762
+}
8b3762
+
8b3762
+INSTANTIATE_TEST_CASE_P(
8b3762
+    IkeSha1, Pkcs11IkeTest,
8b3762
+    ::testing::Combine(::testing::ValuesIn(kIkeSha1ProofVectors),
8b3762
+                       ::testing::Values(CKM_SHA_1_HMAC)));
8b3762
+#ifdef notdef
8b3762
+INSTANTIATE_TEST_CASE_P(
8b3762
+    IkeSha256, Pkcs11IkeTest,
8b3762
+    ::testing::Combine(::testing::ValuesIn(kIkeSha256ProofVectors),
8b3762
+                       ::testing::Values(CKM_SHA256_HMAC)));
8b3762
+
8b3762
+INSTANTIATE_TEST_CASE_P(
8b3762
+    IkeAESXCBC, Pkcs11IkeTest,
8b3762
+    ::testing::Combine(::testing::ValuesIn(kIkeAesXcbcProofVectors),
8b3762
+                       ::testing::Values(CKM_AES_XCBC_MAC)));
8b3762
+#endif
8b3762
+
8b3762
+}  // namespace nss_test
8b3762
diff -up ./lib/softoken/sftkike.c.orig ./lib/softoken/sftkike.c
8b3762
--- ./lib/softoken/sftkike.c.orig	2020-12-05 10:53:12.629385906 -0800
8b3762
+++ ./lib/softoken/sftkike.c	2020-12-05 10:59:16.073393113 -0800
8b3762
@@ -720,6 +720,7 @@ sftk_ike1_appendix_b_prf(CK_SESSION_HAND
8b3762
     unsigned int macSize;
8b3762
     unsigned int outKeySize;
8b3762
     unsigned int genKeySize;
8b3762
+    PRBool quickMode = PR_FALSE;
8b3762
     CK_RV crv;
8b3762
     prfContext context;
8b3762
 
8b3762
@@ -748,6 +749,11 @@ sftk_ike1_appendix_b_prf(CK_SESSION_HAND
8b3762
             crv = CKR_KEY_HANDLE_INVALID;
8b3762
             goto fail;
8b3762
         }
8b3762
+        quickMode = PR_TRUE;
8b3762
+    }
8b3762
+
8b3762
+    if (params->ulExtraDataLen !=0) {
8b3762
+        quickMode = PR_TRUE;
8b3762
     }
8b3762
 
8b3762
     macSize = prf_length(&context);
8b3762
@@ -756,10 +762,16 @@ sftk_ike1_appendix_b_prf(CK_SESSION_HAND
8b3762
         keySize = macSize;
8b3762
     }
8b3762
 
8b3762
-    if (keySize <= inKey->attrib.ulValueLen) {
8b3762
+    /* In appendix B, we are just expanding or contracting a single key.
8b3762
+     * If the input key is less than equal the the key size we want, just
8b3762
+     * subset the original key. In quick mode we are actually getting new
8b3762
+     * keys (salted with our seed data and our gxy key), so we want to run
8b3762
+     * through our algorithm */
8b3762
+    if ((!quickMode) && (keySize <= inKey->attrib.ulValueLen)) {
8b3762
         return sftk_forceAttribute(outKey, CKA_VALUE,
8b3762
                                    inKey->attrib.pValue, keySize);
8b3762
     }
8b3762
+
8b3762
     outKeySize = PR_ROUNDUP(keySize, macSize);
8b3762
     outKeyData = PORT_Alloc(outKeySize);
8b3762
     if (outKeyData == NULL) {