blob: 6ca1752bb3880358831d1e9d9cb7f98c072815d0 [file] [log] [blame]
/* 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 "testvectors/p384ecdh-vectors.h"
#include "testvectors/p521ecdh-vectors.h"
#include "gtest/gtest.h"
namespace nss_test {
class Pkcs11EcdhTest : 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(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