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

418 lines
17 KiB
Diff

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