Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Bug 1585429 - Add HKDF test vectors r=jcj
Adds test vectors for SHA1/256/384/512 HKDF. This includes the RFC test vectors, as well as upper-bound length checks for the output key material. Differential Revision: https://phabricator.services.mozilla.com/D45434 --HG-- extra : moz-landing-system : lando
- Loading branch information
Kevin Jacobs
committed
Jan 13, 2020
1 parent
618a32f
commit 1486269
Showing
4 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* 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/. */ | ||
|
||
#ifndef hkdf_vectors_h__ | ||
#define hkdf_vectors_h__ | ||
|
||
#include <vector> | ||
|
||
typedef struct hkdf_result_str { | ||
SECStatus expect_rv; | ||
bool output_match; | ||
} hkdf_result; | ||
|
||
typedef struct hkdf_vector_str { | ||
uint32_t test_id; | ||
CK_MECHANISM_TYPE mech; | ||
size_t l; | ||
std::vector<uint8_t> ikm; | ||
std::vector<uint8_t> salt; | ||
std::vector<uint8_t> info; | ||
std::vector<uint8_t> okm; | ||
hkdf_result res; | ||
} hkdf_vector; | ||
|
||
// Vectors sourced from https://tools.ietf.org/html/rfc5869 | ||
// Test IDs correspond to those in Appendix A. | ||
const hkdf_vector kHkdfTestVectors[] = { | ||
{1, | ||
CKM_NSS_HKDF_SHA256, | ||
42, | ||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, | ||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, | ||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, | ||
0x0c}, | ||
{0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9}, | ||
{0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, | ||
0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, | ||
0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, | ||
0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65}, | ||
{SECSuccess, true}}, | ||
|
||
{2, | ||
CKM_NSS_HKDF_SHA256, | ||
82, | ||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, | ||
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | ||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, | ||
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, | ||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, | ||
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, | ||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}, | ||
{0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, | ||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, | ||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, | ||
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, | ||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, | ||
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, | ||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf}, | ||
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, | ||
0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, | ||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, | ||
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, | ||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, | ||
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, | ||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}, | ||
{0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c, | ||
0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, | ||
0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99, | ||
0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09, | ||
0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9, | ||
0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, | ||
0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87}, | ||
{SECSuccess, true}}, | ||
|
||
{3, | ||
CKM_NSS_HKDF_SHA256, | ||
42, | ||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, | ||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, | ||
{}, | ||
{}, | ||
{0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, | ||
0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, | ||
0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, | ||
0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8}, | ||
{SECSuccess, true}}, | ||
|
||
{4, | ||
CKM_NSS_HKDF_SHA1, | ||
42, | ||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, | ||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, | ||
0x0c}, | ||
{0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9}, | ||
{0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, | ||
0x56, 0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, | ||
0x09, 0x15, 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, 0xc2, | ||
0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3, 0xf8, 0x96}, | ||
{SECSuccess, true}}, | ||
|
||
{5, | ||
CKM_NSS_HKDF_SHA1, | ||
82, | ||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, | ||
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | ||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, | ||
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, | ||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, | ||
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, | ||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}, | ||
{0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, | ||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, | ||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, | ||
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, | ||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, | ||
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, | ||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf}, | ||
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, | ||
0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, | ||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, | ||
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, | ||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, | ||
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, | ||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}, | ||
{0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5, | ||
0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19, | ||
0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3, 0xf1, 0xa4, | ||
0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c, | ||
0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c, 0x7f, 0x9d, | ||
0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43, | ||
0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4}, | ||
{SECSuccess, true}}, | ||
|
||
{6, | ||
CKM_NSS_HKDF_SHA1, | ||
42, | ||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, | ||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, | ||
{}, | ||
{}, | ||
{0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, | ||
0x98, 0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, | ||
0xa3, 0x06, 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, 0xea, | ||
0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3, 0x49, 0x18}, | ||
{SECSuccess, true}}, | ||
|
||
{7, | ||
CKM_NSS_HKDF_SHA1, | ||
42, | ||
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, | ||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, | ||
{}, | ||
{}, | ||
{0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, | ||
0x6a, 0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, | ||
0xd4, 0x23, 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, 0x67, | ||
0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48}, | ||
{SECSuccess, true}}}; | ||
#endif // hkdf_vectors_h__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* -*- 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 "testvectors/hkdf-vectors.h" | ||
#include "util.h" | ||
|
||
namespace nss_test { | ||
|
||
class Pkcs11HkdfTest : public ::testing::TestWithParam<hkdf_vector> { | ||
protected: | ||
ScopedPK11SymKey ImportKey(CK_MECHANISM_TYPE mech, 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_SIGN, ikm_item, nullptr)); | ||
|
||
return ikm; | ||
} | ||
|
||
void RunTest(hkdf_vector vec) { | ||
SECItem ikm_item = {siBuffer, vec.ikm.data(), | ||
static_cast<unsigned int>(vec.ikm.size())}; | ||
|
||
CK_NSS_HKDFParams hkdf_params = { | ||
true, vec.salt.data(), static_cast<unsigned int>(vec.salt.size()), | ||
true, vec.info.data(), static_cast<unsigned int>(vec.info.size())}; | ||
SECItem params_item = {siBuffer, (unsigned char *)&hkdf_params, | ||
sizeof(hkdf_params)}; | ||
|
||
ScopedPK11SymKey ikm = ImportKey(vec.mech, &ikm_item); | ||
ASSERT_NE(nullptr, ikm.get()); | ||
ScopedPK11SymKey okm = ScopedPK11SymKey( | ||
PK11_Derive(ikm.get(), vec.mech, ¶ms_item, | ||
CKM_GENERIC_SECRET_KEY_GEN, CKA_DERIVE, vec.l)); | ||
if (vec.res.expect_rv == SECSuccess) { | ||
ASSERT_NE(nullptr, okm.get()); | ||
if (vec.res.output_match) { | ||
ASSERT_EQ(SECSuccess, PK11_ExtractKeyValue(okm.get())); | ||
SECItem *act_okm_item = PK11_GetKeyData(okm.get()); | ||
SECItem vec_okm_item = {siBuffer, vec.okm.data(), | ||
static_cast<unsigned int>(vec.okm.size())}; | ||
ASSERT_EQ(0, SECITEM_CompareItem(&vec_okm_item, act_okm_item)); | ||
} | ||
} else { | ||
ASSERT_EQ(nullptr, okm.get()); | ||
} | ||
} | ||
}; | ||
|
||
TEST_P(Pkcs11HkdfTest, TestVectors) { RunTest(GetParam()); } | ||
|
||
INSTANTIATE_TEST_CASE_P(Pkcs11HkdfTests, Pkcs11HkdfTest, | ||
::testing::ValuesIn(kHkdfTestVectors)); | ||
|
||
TEST_F(Pkcs11HkdfTest, OkmLimits) { | ||
hkdf_vector vector{ | ||
0, | ||
CKM_NSS_HKDF_SHA1, | ||
255 * SHA1_LENGTH /* per rfc5869 */, | ||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, | ||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, | ||
{}, | ||
{}, | ||
{}, | ||
{SECSuccess, false} /* Only looking at return value */ | ||
}; | ||
|
||
// SHA1 limit | ||
RunTest(vector); | ||
|
||
// SHA1 limit + 1 | ||
vector.l += 1; | ||
vector.res.expect_rv = SECFailure; | ||
RunTest(vector); | ||
|
||
// SHA256 limit | ||
vector.mech = CKM_NSS_HKDF_SHA256; | ||
vector.l = 255 * SHA256_LENGTH; /* per rfc5869 */ | ||
vector.res.expect_rv = SECSuccess; | ||
RunTest(vector); | ||
|
||
// SHA256 limit + 1 | ||
vector.l += 1; | ||
vector.res.expect_rv = SECFailure; | ||
RunTest(vector); | ||
|
||
// SHA384 limit | ||
vector.mech = CKM_NSS_HKDF_SHA384; | ||
vector.l = 255 * SHA384_LENGTH; /* per rfc5869 */ | ||
vector.res.expect_rv = SECSuccess; | ||
RunTest(vector); | ||
|
||
// SHA384 limit + 1 | ||
vector.l += 1; | ||
vector.res.expect_rv = SECFailure; | ||
RunTest(vector); | ||
|
||
// SHA512 limit | ||
vector.mech = CKM_NSS_HKDF_SHA512; | ||
vector.l = 255 * SHA512_LENGTH; /* per rfc5869 */ | ||
vector.res.expect_rv = SECSuccess; | ||
RunTest(vector); | ||
|
||
// SHA512 limit + 1 | ||
vector.l += 1; | ||
vector.res.expect_rv = SECFailure; | ||
RunTest(vector); | ||
} | ||
} // namespace nss_test |