summaryrefslogtreecommitdiff
path: root/gtests/pk11_gtest
diff options
context:
space:
mode:
authorKevin Jacobs <kjacobs@mozilla.com>2021-01-25 17:39:56 +0000
committerKevin Jacobs <kjacobs@mozilla.com>2021-01-25 17:39:56 +0000
commite7e4a4a881bc28422834df5b5370a35cf21ba149 (patch)
treec0f02c171114fbabdb47cb31bfcbddf1aa37c3f2 /gtests/pk11_gtest
parentddc9d5dd387672585d52dbf326b40c9ed00ed671 (diff)
downloadnss-hg-e7e4a4a881bc28422834df5b5370a35cf21ba149.tar.gz
Bug 1678398 - Add Export/Import functions for HPKE context. r=mt
This patch adds and exports two new HPKE functions: `PK11_HPKE_ExportContext` and `PK11_HPKE_ImportContext`, which are used to export a serialized HPKE context, then later reimport that context and resume Open and Export operations. Only receiver contexts are currently supported for export (see the rationale in pk11pub.h). One other change introduced here is that `PK11_HPKE_GetEncapPubKey` now works as expected on the receiver side. If the `wrapKey` argument is provided to the Export/Import functions, then the symmetric keys are wrapped with AES Key Wrap with Padding (SP800-38F, 6.3) prior to serialization. Differential Revision: https://phabricator.services.mozilla.com/D99277
Diffstat (limited to 'gtests/pk11_gtest')
-rw-r--r--gtests/pk11_gtest/pk11_hpke_unittest.cc125
1 files changed, 125 insertions, 0 deletions
diff --git a/gtests/pk11_gtest/pk11_hpke_unittest.cc b/gtests/pk11_gtest/pk11_hpke_unittest.cc
index 26385f144..48de0a7af 100644
--- a/gtests/pk11_gtest/pk11_hpke_unittest.cc
+++ b/gtests/pk11_gtest/pk11_hpke_unittest.cc
@@ -116,6 +116,32 @@ class HpkeTest {
EXPECT_EQ(msg, opened);
}
+ void ExportSecret(const ScopedHpkeContext &receiver,
+ ScopedPK11SymKey &exported) {
+ std::vector<uint8_t> context = {'c', 't', 'x', 't'};
+ SECItem context_item = {siBuffer, context.data(),
+ static_cast<unsigned int>(context.size())};
+ PK11SymKey *tmp_exported = nullptr;
+ ASSERT_EQ(SECSuccess, PK11_HPKE_ExportSecret(receiver.get(), &context_item,
+ 64, &tmp_exported));
+ exported.reset(tmp_exported);
+ }
+
+ void ExportImportRecvContext(ScopedHpkeContext &scoped_cx,
+ PK11SymKey *wrapping_key) {
+ SECItem *tmp_exported = nullptr;
+ EXPECT_EQ(SECSuccess, PK11_HPKE_ExportContext(scoped_cx.get(), wrapping_key,
+ &tmp_exported));
+ EXPECT_NE(nullptr, tmp_exported);
+ ScopedSECItem context(tmp_exported);
+ scoped_cx.reset();
+
+ HpkeContext *tmp_imported =
+ PK11_HPKE_ImportContext(context.get(), wrapping_key);
+ EXPECT_NE(nullptr, tmp_imported);
+ scoped_cx.reset(tmp_imported);
+ }
+
bool GenerateKeyPair(ScopedSECKEYPublicKey &pub_key,
ScopedSECKEYPrivateKey &priv_key) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
@@ -437,6 +463,105 @@ TEST_F(ModeParameterizedTest, BadEncapsulatedPubKey) {
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
}
+TEST_P(ModeParameterizedTest, ContextExportImportEncrypt) {
+ std::vector<uint8_t> msg = {'s', 'e', 'c', 'r', 'e', 't'};
+ std::vector<uint8_t> aad = {'a', 'a', 'd'};
+
+ ScopedHpkeContext sender;
+ ScopedHpkeContext receiver;
+ SetUpEphemeralContexts(sender, receiver, std::get<0>(GetParam()),
+ std::get<1>(GetParam()), std::get<2>(GetParam()),
+ std::get<3>(GetParam()));
+ SealOpen(sender, receiver, msg, aad, nullptr);
+ ExportImportRecvContext(receiver, nullptr);
+ SealOpen(sender, receiver, msg, aad, nullptr);
+}
+
+TEST_P(ModeParameterizedTest, ContextExportImportExport) {
+ ScopedHpkeContext sender;
+ ScopedHpkeContext receiver;
+ ScopedPK11SymKey sender_export;
+ ScopedPK11SymKey receiver_export;
+ ScopedPK11SymKey receiver_reexport;
+ SetUpEphemeralContexts(sender, receiver, std::get<0>(GetParam()),
+ std::get<1>(GetParam()), std::get<2>(GetParam()),
+ std::get<3>(GetParam()));
+ ExportSecret(sender, sender_export);
+ ExportSecret(receiver, receiver_export);
+ CheckEquality(sender_export.get(), receiver_export.get());
+ ExportImportRecvContext(receiver, nullptr);
+ ExportSecret(receiver, receiver_reexport);
+ CheckEquality(receiver_export.get(), receiver_reexport.get());
+}
+
+TEST_P(ModeParameterizedTest, ContextExportImportWithWrap) {
+ std::vector<uint8_t> msg = {'s', 'e', 'c', 'r', 'e', 't'};
+ std::vector<uint8_t> aad = {'a', 'a', 'd'};
+
+ // Generate a wrapping key, then use it for export.
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ASSERT_TRUE(slot);
+ ScopedPK11SymKey kek(
+ PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
+ ASSERT_NE(nullptr, kek);
+
+ ScopedHpkeContext sender;
+ ScopedHpkeContext receiver;
+ SetUpEphemeralContexts(sender, receiver, std::get<0>(GetParam()),
+ std::get<1>(GetParam()), std::get<2>(GetParam()),
+ std::get<3>(GetParam()));
+ SealOpen(sender, receiver, msg, aad, nullptr);
+ ExportImportRecvContext(receiver, kek.get());
+ SealOpen(sender, receiver, msg, aad, nullptr);
+}
+
+TEST_P(ModeParameterizedTest, ExportSenderContext) {
+ std::vector<uint8_t> msg = {'s', 'e', 'c', 'r', 'e', 't'};
+ std::vector<uint8_t> aad = {'a', 'a', 'd'};
+
+ ScopedHpkeContext sender;
+ ScopedHpkeContext receiver;
+ SetUpEphemeralContexts(sender, receiver, std::get<0>(GetParam()),
+ std::get<1>(GetParam()), std::get<2>(GetParam()),
+ std::get<3>(GetParam()));
+
+ SECItem *tmp_exported = nullptr;
+ EXPECT_EQ(SECFailure,
+ PK11_HPKE_ExportContext(sender.get(), nullptr, &tmp_exported));
+ EXPECT_EQ(nullptr, tmp_exported);
+ EXPECT_EQ(SEC_ERROR_NOT_A_RECIPIENT, PORT_GetError());
+}
+
+TEST_P(ModeParameterizedTest, ContextUnwrapBadKey) {
+ std::vector<uint8_t> msg = {'s', 'e', 'c', 'r', 'e', 't'};
+ std::vector<uint8_t> aad = {'a', 'a', 'd'};
+
+ // Generate a wrapping key, then use it for export.
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ASSERT_TRUE(slot);
+ ScopedPK11SymKey kek(
+ PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
+ ASSERT_NE(nullptr, kek);
+ ScopedPK11SymKey not_kek(
+ PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
+ ASSERT_NE(nullptr, not_kek);
+ ScopedHpkeContext sender;
+ ScopedHpkeContext receiver;
+
+ SetUpEphemeralContexts(sender, receiver, std::get<0>(GetParam()),
+ std::get<1>(GetParam()), std::get<2>(GetParam()),
+ std::get<3>(GetParam()));
+
+ SECItem *tmp_exported = nullptr;
+ EXPECT_EQ(SECSuccess,
+ PK11_HPKE_ExportContext(receiver.get(), kek.get(), &tmp_exported));
+ EXPECT_NE(nullptr, tmp_exported);
+ ScopedSECItem context(tmp_exported);
+
+ EXPECT_EQ(nullptr, PK11_HPKE_ImportContext(context.get(), not_kek.get()));
+ EXPECT_EQ(SEC_ERROR_BAD_DATA, PORT_GetError());
+}
+
TEST_P(ModeParameterizedTest, EphemeralKeys) {
std::vector<uint8_t> msg = {'s', 'e', 'c', 'r', 'e', 't'};
std::vector<uint8_t> aad = {'a', 'a', 'd'};