/* 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 #include "nss.h" #include "pk11pub.h" #include "cpputil.h" #include "nss_scoped_ptrs.h" #include "testvectors/p256ecdh-vectors.h" #include "testvectors/p384ecdh-vectors.h" #include "testvectors/p521ecdh-vectors.h" #include "gtest/gtest.h" namespace nss_test { class Pkcs11EcdhTest : public ::testing::TestWithParam { 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(vec.secret.size())}; ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); ASSERT_TRUE(slot); SECItem priv_item = {siBuffer, toUcharPtr(vec.private_key.data()), static_cast(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(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(Pkcs11EcdhTest, TestVectors) { Derive(GetParam()); } INSTANTIATE_TEST_SUITE_P(WycheproofP256EcdhTest, Pkcs11EcdhTest, ::testing::ValuesIn(kP256EcdhWycheproofVectors)); INSTANTIATE_TEST_SUITE_P(WycheproofP384EcdhTest, Pkcs11EcdhTest, ::testing::ValuesIn(kP384EcdhWycheproofVectors)); INSTANTIATE_TEST_SUITE_P(WycheproofP521EcdhTest, Pkcs11EcdhTest, ::testing::ValuesIn(kP521EcdhWycheproofVectors)); } // namespace nss_test