diff options
author | Robert Relyea <rrelyea@redhat.com> | 2020-10-23 15:34:01 -0700 |
---|---|---|
committer | Robert Relyea <rrelyea@redhat.com> | 2020-10-23 15:34:01 -0700 |
commit | a709ad895bea3d3580f8a9ddee86fd7cebe1fcad (patch) | |
tree | 08e7659a33a9244d354d014346e369b1cda7e560 /gtests/pk11_gtest | |
parent | 1e26e71f47e3f74d8b928641c0f8827c6548e72f (diff) | |
download | nss-hg-a709ad895bea3d3580f8a9ddee86fd7cebe1fcad.tar.gz |
Bug 1666891 - Add PK11_Pub{Wrap,Unwrap}SymKeyWithMechanism r=mt,rrelyea
Summary
This is useful for RSA-OAEP support.
The CKM_RSA_PKCS_OAEP mechanism requires a CK_RSA_PKCS_OAEP_PARAMS
be present for PKCS#11 calls. This provides required context for OAEP.
However, PK11_PubWrapSymKey lacks a way of providing this context and
historically silently converted CKM_RSA_PKCS_OAEP to CKM_RSA_PKCS when
a RSA key is provided. Introducing a new call will let us indicate
parameters and potentially support other mechanisms in the future.
This call mirrors the earlier calls introduced for RSA-PSS:
PK11_SignWithMechanism and PK11_VerifyWithMechanism.
The CKM_RSA_PKCS_OAEP mechanism requires a CK_RSA_PKCS_OAEP_PARAMS
be present for PKCS#11 calls. This provides required context for OAEP.
However, PK11_PubUnwrapSymKey lacks a way of providing this context,
and additionally lacked a way of indicating which mechanism type to use
for the unwrap operation (instead detecting it by key type). Introducing
a new call will let us indicate parameters and potentially support other
mechanisms in the future.
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
Differential Revision: https://phabricator.services.mozilla.com/D93424
Diffstat (limited to 'gtests/pk11_gtest')
-rw-r--r-- | gtests/pk11_gtest/pk11_rsaoaep_unittest.cc | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/gtests/pk11_gtest/pk11_rsaoaep_unittest.cc b/gtests/pk11_gtest/pk11_rsaoaep_unittest.cc index 3a986b4cb..d14eb9c64 100644 --- a/gtests/pk11_gtest/pk11_rsaoaep_unittest.cc +++ b/gtests/pk11_gtest/pk11_rsaoaep_unittest.cc @@ -116,4 +116,71 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( WycheproofOaep2048Sha512Sha512Test, RsaOaepWycheproofTest, ::testing::ValuesIn(kRsaOaep2048Sha512Mgf1Sha512WycheproofVectors)); + +TEST(Pkcs11RsaOaepTest, TestOaepWrapUnwrap) { + const size_t kRsaKeyBits = 2048; + const size_t kwrappedBufLen = 4096; + + SECStatus rv = SECFailure; + + ScopedSECKEYPrivateKey priv; + ScopedSECKEYPublicKey pub; + PK11RSAGenParams rsa_params; + rsa_params.keySizeInBits = kRsaKeyBits; + rsa_params.pe = 65537; + + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + ASSERT_NE(slot, nullptr); + + SECKEYPublicKey* p_pub_tmp = nullptr; + priv.reset(PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN, + &rsa_params, &p_pub_tmp, false, false, + nullptr)); + pub.reset(p_pub_tmp); + + ASSERT_NE(priv.get(), nullptr); + ASSERT_NE(pub.get(), nullptr); + + ScopedPK11SymKey to_wrap( + PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr)); + + CK_RSA_PKCS_OAEP_PARAMS oaep_params = {CKM_SHA256, CKG_MGF1_SHA256, + CKZ_DATA_SPECIFIED, NULL, 0}; + + SECItem param = {siBuffer, (unsigned char*)&oaep_params, sizeof(oaep_params)}; + + ScopedSECItem wrapped(SECITEM_AllocItem(nullptr, nullptr, kwrappedBufLen)); + rv = PK11_PubWrapSymKeyWithMechanism(pub.get(), CKM_RSA_PKCS_OAEP, ¶m, + to_wrap.get(), wrapped.get()); + ASSERT_EQ(rv, SECSuccess); + + PK11SymKey* p_unwrapped_tmp = nullptr; + + // This fails because this method is broken and assumes CKM_RSA_PKCS and + // doesn't understand OAEP. + p_unwrapped_tmp = PK11_PubUnwrapSymKey(priv.get(), wrapped.get(), CKM_AES_CBC, + CKA_DECRYPT, 16); + ASSERT_EQ(p_unwrapped_tmp, nullptr); + + ScopedPK11SymKey unwrapped; + p_unwrapped_tmp = PK11_PubUnwrapSymKeyWithMechanism( + priv.get(), CKM_RSA_PKCS_OAEP, ¶m, wrapped.get(), CKM_AES_CBC, + CKA_DECRYPT, 16); + ASSERT_NE(p_unwrapped_tmp, nullptr); + + unwrapped.reset(p_unwrapped_tmp); + + // Extract key's value in order to validate decryption worked. + rv = PK11_ExtractKeyValue(to_wrap.get()); + ASSERT_EQ(rv, SECSuccess); + + rv = PK11_ExtractKeyValue(unwrapped.get()); + ASSERT_EQ(rv, SECSuccess); + + // References owned by PKCS#11 layer; no need to scope and free. + SECItem* expectedItem = PK11_GetKeyData(to_wrap.get()); + SECItem* actualItem = PK11_GetKeyData(unwrapped.get()); + + ASSERT_EQ(SECITEM_CompareItem(actualItem, expectedItem), 0); +} } // namespace nss_test |