summaryrefslogtreecommitdiff
path: root/gtests/pk11_gtest
diff options
context:
space:
mode:
authorKevin Jacobs <kjacobs@mozilla.com>2020-01-16 21:42:56 +0000
committerKevin Jacobs <kjacobs@mozilla.com>2020-01-16 21:42:56 +0000
commit1d9fba9af57f097e333fcda14b0f207030972609 (patch)
treebbdf5736d5c293f71c9143b529eadee65b9b957a /gtests/pk11_gtest
parentec4c67acc49349c622d09d05c36c7ecda4c85e3c (diff)
downloadnss-hg-1d9fba9af57f097e333fcda14b0f207030972609.tar.gz
Bug 1604596 - Update Wycheproof vectors and add support for CBC, P256-ECDH, and CMAC tests r=franziskus
This patch updates to the latest Wycheproof vectors and adds Wycheproof support for CBC, CMAC, and P256-ECDH: ChaCha20: +141 tests Curve25519: +431 tests GCM: +39 tests CBC (new): +183 tests CMAC (new): +308 tests P256 ECDH (new): +460 tests Differential Revision: https://phabricator.services.mozilla.com/D57477
Diffstat (limited to 'gtests/pk11_gtest')
-rw-r--r--gtests/pk11_gtest/manifest.mn1
-rw-r--r--gtests/pk11_gtest/pk11_aes_cmac_unittest.cc43
-rw-r--r--gtests/pk11_gtest/pk11_aes_gcm_unittest.cc22
-rw-r--r--gtests/pk11_gtest/pk11_cbc_unittest.cc52
-rw-r--r--gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc18
-rw-r--r--gtests/pk11_gtest/pk11_curve25519_unittest.cc4
-rw-r--r--gtests/pk11_gtest/pk11_ecdh_unittest.cc80
-rw-r--r--gtests/pk11_gtest/pk11_gtest.gyp1
8 files changed, 195 insertions, 26 deletions
diff --git a/gtests/pk11_gtest/manifest.mn b/gtests/pk11_gtest/manifest.mn
index 4bf73a699..d655bb4bf 100644
--- a/gtests/pk11_gtest/manifest.mn
+++ b/gtests/pk11_gtest/manifest.mn
@@ -16,6 +16,7 @@ CPPSRCS = \
pk11_der_private_key_import_unittest.cc \
pk11_des_unittest.cc \
pk11_ecdsa_unittest.cc \
+ pk11_ecdh_unittest.cc \
pk11_encrypt_derive_unittest.cc \
pk11_export_unittest.cc \
pk11_find_certs_unittest.cc \
diff --git a/gtests/pk11_gtest/pk11_aes_cmac_unittest.cc b/gtests/pk11_gtest/pk11_aes_cmac_unittest.cc
index c520fffd1..45e4cac1a 100644
--- a/gtests/pk11_gtest/pk11_aes_cmac_unittest.cc
+++ b/gtests/pk11_gtest/pk11_aes_cmac_unittest.cc
@@ -14,11 +14,12 @@
#include "gtest/gtest.h"
#include "nss_scoped_ptrs.h"
+#include "testvectors/cmac-vectors.h"
#include "util.h"
namespace nss_test {
-class Pkcs11AesCmacTest : public ::testing::Test {
+class Pkcs11AesCmacTest : public ::testing::TestWithParam<AesCmacTestVector> {
protected:
ScopedPK11SymKey ImportKey(CK_MECHANISM_TYPE mech, SECItem *key_item) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
@@ -54,8 +55,46 @@ class Pkcs11AesCmacTest : public ::testing::Test {
ASSERT_EQ(SECSuccess, ret);
ASSERT_EQ(0, SECITEM_CompareItem(&output_item, &expected_item));
}
+
+ void RunTestVector(const AesCmacTestVector vec) {
+ bool valid = !vec.invalid;
+ std::string err = "Test #" + std::to_string(vec.id) + " failed";
+ std::vector<uint8_t> key = hex_string_to_bytes(vec.key);
+ std::vector<uint8_t> tag = hex_string_to_bytes(vec.tag);
+ std::vector<uint8_t> msg = hex_string_to_bytes(vec.msg);
+
+ std::vector<uint8_t> output(AES_BLOCK_SIZE);
+ // Don't provide a null pointer, even if the input is empty.
+ uint8_t tmp;
+ SECItem key_item = {siBuffer, key.data() ? key.data() : &tmp,
+ static_cast<unsigned int>(key.size())};
+ SECItem tag_item = {siBuffer, tag.data() ? tag.data() : &tmp,
+ static_cast<unsigned int>(tag.size())};
+ SECItem msg_item = {siBuffer, msg.data() ? msg.data() : &tmp,
+ static_cast<unsigned int>(msg.size())};
+ SECItem out_item = {siBuffer, output.data() ? output.data() : &tmp,
+ static_cast<unsigned int>(output.size())};
+
+ ScopedPK11SymKey p11_key = ImportKey(CKM_AES_CMAC_GENERAL, &key_item);
+ if (vec.comment == "invalid key size") {
+ ASSERT_EQ(nullptr, p11_key.get()) << err;
+ return;
+ }
+
+ ASSERT_NE(nullptr, p11_key.get()) << err;
+ SECStatus rv = PK11_SignWithSymKey(p11_key.get(), CKM_AES_CMAC, NULL,
+ &out_item, &msg_item);
+
+ EXPECT_EQ(SECSuccess, rv) << err;
+ EXPECT_EQ(valid, 0 == SECITEM_CompareItem(&out_item, &tag_item)) << err;
+ }
};
+TEST_P(Pkcs11AesCmacTest, TestVectors) { RunTestVector(GetParam()); }
+
+INSTANTIATE_TEST_CASE_P(WycheproofTestVector, Pkcs11AesCmacTest,
+ ::testing::ValuesIn(kCmacWycheproofVectors));
+
// Sanity check of the PKCS #11 API only. Extensive tests for correctness of
// underling CMAC implementation conducted in the following file:
// gtests/freebl_gtest/cmac_unittests.cc
@@ -88,4 +127,4 @@ TEST_F(Pkcs11AesCmacTest, InvalidKeySize) {
ScopedPK11SymKey result = ImportKey(CKM_AES_CMAC, &key_item);
ASSERT_EQ(nullptr, result.get());
}
-}
+} // namespace nss_test
diff --git a/gtests/pk11_gtest/pk11_aes_gcm_unittest.cc b/gtests/pk11_gtest/pk11_aes_gcm_unittest.cc
index 2c58063d4..94736c695 100644
--- a/gtests/pk11_gtest/pk11_aes_gcm_unittest.cc
+++ b/gtests/pk11_gtest/pk11_aes_gcm_unittest.cc
@@ -18,19 +18,17 @@
namespace nss_test {
-class Pkcs11AesGcmTest : public ::testing::TestWithParam<gcm_kat_value> {
+class Pkcs11AesGcmTest : public ::testing::TestWithParam<AesGcmKatValue> {
protected:
- void RunTest(const gcm_kat_value val) {
- std::vector<uint8_t> key = hex_string_to_bytes(val.key);
- std::vector<uint8_t> iv = hex_string_to_bytes(val.iv);
- std::vector<uint8_t> plaintext = hex_string_to_bytes(val.plaintext);
- std::vector<uint8_t> aad = hex_string_to_bytes(val.additional_data);
- std::vector<uint8_t> result = hex_string_to_bytes(val.result);
- bool invalid_ct = val.invalid_ct;
- bool invalid_iv = val.invalid_iv;
- std::stringstream s;
- s << "Test #" << val.test_id << " failed.";
- std::string msg = s.str();
+ void RunTest(const AesGcmKatValue vec) {
+ std::vector<uint8_t> key = hex_string_to_bytes(vec.key);
+ std::vector<uint8_t> iv = hex_string_to_bytes(vec.iv);
+ std::vector<uint8_t> plaintext = hex_string_to_bytes(vec.plaintext);
+ std::vector<uint8_t> aad = hex_string_to_bytes(vec.additional_data);
+ std::vector<uint8_t> result = hex_string_to_bytes(vec.result);
+ bool invalid_ct = vec.invalid_ct;
+ bool invalid_iv = vec.invalid_iv;
+ std::string msg = "Test #" + std::to_string(vec.id) + " failed";
// Ignore GHASH-only vectors.
if (key.empty()) {
return;
diff --git a/gtests/pk11_gtest/pk11_cbc_unittest.cc b/gtests/pk11_gtest/pk11_cbc_unittest.cc
index ecc705ad4..43b267cea 100644
--- a/gtests/pk11_gtest/pk11_cbc_unittest.cc
+++ b/gtests/pk11_gtest/pk11_cbc_unittest.cc
@@ -9,8 +9,10 @@
#include "pk11pub.h"
#include "secerr.h"
-#include "nss_scoped_ptrs.h"
#include "gtest/gtest.h"
+#include "nss_scoped_ptrs.h"
+#include "testvectors/cbc-vectors.h"
+#include "util.h"
namespace nss_test {
@@ -555,4 +557,52 @@ INSTANTIATE_TEST_CASE_P(EncryptDecrypt, Pkcs11CbcPadTest,
::testing::Values(CKM_AES_CBC_PAD, CKM_AES_CBC,
CKM_DES3_CBC_PAD, CKM_DES3_CBC));
+class Pkcs11AesCbcWycheproofTest
+ : public ::testing::TestWithParam<AesCbcTestVector> {
+ protected:
+ void RunTest(const AesCbcTestVector vec) {
+ bool valid = vec.valid;
+ std::string err = "Test #" + std::to_string(vec.id) + " failed";
+ std::vector<uint8_t> key = hex_string_to_bytes(vec.key);
+ std::vector<uint8_t> iv = hex_string_to_bytes(vec.iv);
+ std::vector<uint8_t> ciphertext = hex_string_to_bytes(vec.ciphertext);
+ std::vector<uint8_t> msg = hex_string_to_bytes(vec.msg);
+ std::vector<uint8_t> decrypted(vec.ciphertext.size());
+ unsigned int decrypted_len = 0;
+
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ASSERT_NE(nullptr, slot);
+
+ // Don't provide a null pointer, even if the length is 0. We don't want to
+ // fail on trivial checks.
+ uint8_t tmp;
+ SECItem iv_item = {siBuffer, iv.data() ? iv.data() : &tmp,
+ static_cast<unsigned int>(iv.size())};
+ SECItem key_item = {siBuffer, key.data() ? key.data() : &tmp,
+ static_cast<unsigned int>(key.size())};
+
+ PK11SymKey* pKey = PK11_ImportSymKey(slot.get(), kMech, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &key_item, nullptr);
+ ASSERT_NE(nullptr, pKey);
+ ScopedPK11SymKey spKey = ScopedPK11SymKey(pKey);
+
+ SECStatus rv = PK11_Decrypt(spKey.get(), kMech, &iv_item, decrypted.data(),
+ &decrypted_len, decrypted.size(),
+ ciphertext.data(), ciphertext.size());
+
+ ASSERT_EQ(valid ? SECSuccess : SECFailure, rv) << err;
+ if (valid) {
+ EXPECT_EQ(msg.size(), static_cast<size_t>(decrypted_len)) << err;
+ EXPECT_EQ(0, memcmp(msg.data(), decrypted.data(), decrypted_len)) << err;
+ }
+ }
+
+ const CK_MECHANISM_TYPE kMech = CKM_AES_CBC_PAD;
+};
+
+TEST_P(Pkcs11AesCbcWycheproofTest, TestVectors) { RunTest(GetParam()); }
+
+INSTANTIATE_TEST_CASE_P(WycheproofTestVector, Pkcs11AesCbcWycheproofTest,
+ ::testing::ValuesIn(kCbcWycheproofVectors));
+
} // namespace nss_test
diff --git a/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc b/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc
index 10cc2a8c6..26634411c 100644
--- a/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc
+++ b/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc
@@ -26,7 +26,7 @@ static const uint8_t kCtrNonce[16] = {'c', 0, 0, 0, 'n'};
static const uint8_t kData[16] = {'d'};
class Pkcs11ChaCha20Poly1305Test
- : public ::testing::TestWithParam<chaChaTestVector> {
+ : public ::testing::TestWithParam<ChaChaTestVector> {
public:
void EncryptDecrypt(const ScopedPK11SymKey& key, const bool invalid_iv,
const bool invalid_tag, const uint8_t* data,
@@ -168,10 +168,10 @@ class Pkcs11ChaCha20Poly1305Test
}
}
- void EncryptDecrypt(const chaChaTestVector testvector) {
+ void EncryptDecrypt(const ChaChaTestVector testvector) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
- SECItem keyItem = {siBuffer, toUcharPtr(testvector.Key.data()),
- static_cast<unsigned int>(testvector.Key.size())};
+ SECItem keyItem = {siBuffer, toUcharPtr(testvector.key.data()),
+ static_cast<unsigned int>(testvector.key.size())};
// Import key.
ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), kMech, PK11_OriginUnwrap,
@@ -179,11 +179,11 @@ class Pkcs11ChaCha20Poly1305Test
EXPECT_TRUE(!!key);
// Check.
- EncryptDecrypt(key, testvector.invalidIV, testvector.invalidTag,
- testvector.Data.data(), testvector.Data.size(),
- testvector.AAD.data(), testvector.AAD.size(),
- testvector.IV.data(), testvector.IV.size(),
- testvector.CT.data(), testvector.CT.size());
+ EncryptDecrypt(key, testvector.invalid_iv, testvector.invalid_tag,
+ testvector.plaintext.data(), testvector.plaintext.size(),
+ testvector.aad.data(), testvector.aad.size(),
+ testvector.iv.data(), testvector.iv.size(),
+ testvector.ciphertext.data(), testvector.ciphertext.size());
}
protected:
diff --git a/gtests/pk11_gtest/pk11_curve25519_unittest.cc b/gtests/pk11_gtest/pk11_curve25519_unittest.cc
index 647e3a706..b26e5d41e 100644
--- a/gtests/pk11_gtest/pk11_curve25519_unittest.cc
+++ b/gtests/pk11_gtest/pk11_curve25519_unittest.cc
@@ -15,7 +15,7 @@
namespace nss_test {
class Pkcs11Curve25519Test
- : public ::testing::TestWithParam<curve25519_testvector> {
+ : public ::testing::TestWithParam<EcdhTestVectorStr> {
protected:
void Derive(const uint8_t* pkcs8, size_t pkcs8_len, const uint8_t* spki,
size_t spki_len, const uint8_t* secret, size_t secret_len,
@@ -107,7 +107,7 @@ class Pkcs11Curve25519Test
}
};
- void Derive(const curve25519_testvector testvector) {
+ void Derive(const EcdhTestVectorStr testvector) {
Derive(testvector.private_key.data(), testvector.private_key.size(),
testvector.public_key.data(), testvector.public_key.size(),
testvector.secret.data(), testvector.secret.size(),
diff --git a/gtests/pk11_gtest/pk11_ecdh_unittest.cc b/gtests/pk11_gtest/pk11_ecdh_unittest.cc
new file mode 100644
index 000000000..b6be1972f
--- /dev/null
+++ b/gtests/pk11_gtest/pk11_ecdh_unittest.cc
@@ -0,0 +1,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 "nss.h"
+#include "pk11pub.h"
+
+#include "cpputil.h"
+#include "nss_scoped_ptrs.h"
+
+#include "testvectors/p256ecdh-vectors.h"
+#include "gtest/gtest.h"
+
+namespace nss_test {
+
+class Pkcs11P256EcdhTest : public ::testing::TestWithParam<EcdhTestVector> {
+ protected:
+ void Derive(const EcdhTestVector vec) {
+ std::string err = "Test #" + std::to_string(vec.id) + " failed";
+
+ SECItem expect_item = {siBuffer, toUcharPtr(vec.secret.data()),
+ static_cast<unsigned int>(vec.secret.size())};
+
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ASSERT_TRUE(slot);
+
+ SECItem priv_item = {siBuffer, toUcharPtr(vec.private_key.data()),
+ static_cast<unsigned int>(vec.private_key.size())};
+ SECKEYPrivateKey* key = nullptr;
+ SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+ slot.get(), &priv_item, nullptr, nullptr, false, false, KU_ALL, &key,
+ nullptr);
+ EXPECT_EQ(SECSuccess, rv) << err;
+
+ ScopedSECKEYPrivateKey priv_key(key);
+ ASSERT_TRUE(priv_key) << err;
+
+ SECItem spki_item = {siBuffer, toUcharPtr(vec.public_key.data()),
+ static_cast<unsigned int>(vec.public_key.size())};
+
+ ScopedCERTSubjectPublicKeyInfo cert_spki(
+ SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
+ if (vec.valid) {
+ ASSERT_TRUE(!!cert_spki) << err;
+ } else if (!cert_spki) {
+ ASSERT_TRUE(vec.invalid_asn) << err;
+ return;
+ }
+
+ ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get()));
+ if (vec.valid) {
+ ASSERT_TRUE(!!pub_key) << err;
+ } else if (!pub_key) {
+ ASSERT_FALSE(vec.valid) << err;
+ return;
+ }
+
+ ScopedPK11SymKey sym_key(
+ PK11_PubDeriveWithKDF(priv_key.get(), pub_key.get(), false, nullptr,
+ nullptr, CKM_ECDH1_DERIVE, CKM_SHA512_HMAC,
+ CKA_DERIVE, 0, CKD_NULL, nullptr, nullptr));
+ ASSERT_EQ(vec.valid, !!sym_key) << err;
+
+ if (vec.valid) {
+ rv = PK11_ExtractKeyValue(sym_key.get());
+ EXPECT_EQ(SECSuccess, rv) << err;
+
+ SECItem* derived_key = PK11_GetKeyData(sym_key.get());
+ EXPECT_EQ(0, SECITEM_CompareItem(derived_key, &expect_item)) << err;
+ }
+ };
+};
+
+TEST_P(Pkcs11P256EcdhTest, TestVectors) { Derive(GetParam()); }
+
+INSTANTIATE_TEST_CASE_P(WycheproofP256EcdhTest, Pkcs11P256EcdhTest,
+ ::testing::ValuesIn(kP256EcdhWycheproofVectors));
+
+} // namespace nss_test
diff --git a/gtests/pk11_gtest/pk11_gtest.gyp b/gtests/pk11_gtest/pk11_gtest.gyp
index 58ea31cf6..c746ac650 100644
--- a/gtests/pk11_gtest/pk11_gtest.gyp
+++ b/gtests/pk11_gtest/pk11_gtest.gyp
@@ -22,6 +22,7 @@
'pk11_der_private_key_import_unittest.cc',
'pk11_des_unittest.cc',
'pk11_ecdsa_unittest.cc',
+ 'pk11_ecdh_unittest.cc',
'pk11_encrypt_derive_unittest.cc',
'pk11_find_certs_unittest.cc',
'pk11_hkdf_unittest.cc',