diff options
author | CoprDistGit <infra@openeuler.org> | 2024-10-22 06:41:18 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-10-22 06:41:18 +0000 |
commit | 29e97240368eeb7e662e3e326ce547dccea742a2 (patch) | |
tree | eb3d47975d564679ba90a4fd8f8d02e69fb6b747 /backport-Bug-1666891-Add-PK11_Pub-Wrap-Unwrap.patch | |
parent | 177ab01f23c074d39686bacd3420fa7e6b560c9b (diff) |
automatic import of nssopeneuler20.03_LTS_SP4
Diffstat (limited to 'backport-Bug-1666891-Add-PK11_Pub-Wrap-Unwrap.patch')
-rw-r--r-- | backport-Bug-1666891-Add-PK11_Pub-Wrap-Unwrap.patch | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/backport-Bug-1666891-Add-PK11_Pub-Wrap-Unwrap.patch b/backport-Bug-1666891-Add-PK11_Pub-Wrap-Unwrap.patch new file mode 100644 index 0000000..19acaf0 --- /dev/null +++ b/backport-Bug-1666891-Add-PK11_Pub-Wrap-Unwrap.patch @@ -0,0 +1,256 @@ +From d055ada2383eaf28d7b28dd7b0b639e2515279e1 Mon Sep 17 00:00:00 2001 +From: jinlun <jinlun@huawei.com> +Date: Tue, 20 Feb 2024 14:41:43 +0800 +Subject: [PATCH] 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 +--- + gtests/pk11_gtest/pk11_rsaoaep_unittest.cc | 67 ++++++++++++++++++++++ + lib/nss/nss.def | 7 +++ + lib/pk11wrap/pk11pub.h | 12 ++++ + lib/pk11wrap/pk11skey.c | 51 ++++++++++++---- + 4 files changed, 126 insertions(+), 11 deletions(-) + +diff --git a/gtests/pk11_gtest/pk11_rsaoaep_unittest.cc b/gtests/pk11_gtest/pk11_rsaoaep_unittest.cc +index 3a986b4..d14eb9c 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 +diff --git a/lib/nss/nss.def b/lib/nss/nss.def +index 1840b8d..4055a98 100644 +--- a/lib/nss/nss.def ++++ b/lib/nss/nss.def +@@ -1181,3 +1181,10 @@ SECMOD_GetSystemFIPSEnabled; + ;+ local: + ;+ *; + ;+}; ++;+NSS_3.59 { # NSS 3.59 release ++;+ global: ++PK11_PubWrapSymKeyWithMechanism; ++PK11_PubUnwrapSymKeyWithMechanism; ++;+ local: ++;+ *; ++;+}; +diff --git a/lib/pk11wrap/pk11pub.h b/lib/pk11wrap/pk11pub.h +index 5edcbf9..3af8487 100644 +--- a/lib/pk11wrap/pk11pub.h ++++ b/lib/pk11wrap/pk11pub.h +@@ -354,6 +354,11 @@ void *PK11_GetSymKeyUserData(PK11SymKey *symKey); + + SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, + PK11SymKey *symKey, SECItem *wrappedKey); ++SECStatus PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey, ++ CK_MECHANISM_TYPE mechType, ++ SECItem *param, ++ PK11SymKey *symKey, ++ SECItem *wrappedKey); + SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params, + PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey); + /* move a key to 'slot' optionally set the key attributes according to either +@@ -448,6 +453,13 @@ PK11SymKey *PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey, + */ + PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey, + CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); ++PK11SymKey *PK11_PubUnwrapSymKeyWithMechanism(SECKEYPrivateKey *key, ++ CK_MECHANISM_TYPE mechType, ++ SECItem *param, ++ SECItem *wrapppedKey, ++ CK_MECHANISM_TYPE target, ++ CK_ATTRIBUTE_TYPE operation, ++ int keySize); + PK11SymKey *PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, + SECItem *wrappedKey, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, +diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c +index 996c039..eed833a 100644 +--- a/lib/pk11wrap/pk11skey.c ++++ b/lib/pk11wrap/pk11skey.c +@@ -1248,13 +1248,23 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx) + symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/); + } + +-/* +- * This function does a straight public key wrap (which only RSA can do). +- * Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and +- * Diffie-Hellman Ciphers. */ ++/* This function does a straight public key wrap with the CKM_RSA_PKCS ++ * mechanism. */ + SECStatus + PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, + PK11SymKey *symKey, SECItem *wrappedKey) ++{ ++ CK_MECHANISM_TYPE inferred = pk11_mapWrapKeyType(pubKey->keyType); ++ return PK11_PubWrapSymKeyWithMechanism(pubKey, inferred, NULL, symKey, ++ wrappedKey); ++} ++ ++/* This function wraps a symmetric key with a public key, such as with the ++ * CKM_RSA_PKCS and CKM_RSA_PKCS_OAEP mechanisms. */ ++SECStatus ++PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey, ++ CK_MECHANISM_TYPE mechType, SECItem *param, ++ PK11SymKey *symKey, SECItem *wrappedKey) + { + PK11SlotInfo *slot; + CK_ULONG len = wrappedKey->len; +@@ -1271,7 +1281,7 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, + } + + /* if this slot doesn't support the mechanism, go to a slot that does */ +- newKey = pk11_ForceSlot(symKey, type, CKA_ENCRYPT); ++ newKey = pk11_ForceSlot(symKey, mechType, CKA_ENCRYPT); + if (newKey != NULL) { + symKey = newKey; + } +@@ -1282,9 +1292,15 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, + } + + slot = symKey->slot; +- mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType); +- mechanism.pParameter = NULL; +- mechanism.ulParameterLen = 0; ++ ++ mechanism.mechanism = mechType; ++ if (param == NULL) { ++ mechanism.pParameter = NULL; ++ mechanism.ulParameterLen = 0; ++ } else { ++ mechanism.pParameter = param->data; ++ mechanism.ulParameterLen = param->len; ++ } + + id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE); + if (id == CK_INVALID_HANDLE) { +@@ -2856,20 +2872,33 @@ PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey, + wrappingKey->cx, keyTemplate, templateCount, isPerm); + } + +-/* unwrap a symetric key with a private key. */ ++/* unwrap a symmetric key with a private key. Only supports CKM_RSA_PKCS. */ + PK11SymKey * + PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, + CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize) + { + CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); ++ ++ return PK11_PubUnwrapSymKeyWithMechanism(wrappingKey, wrapType, NULL, ++ wrappedKey, target, operation, ++ keySize); ++} ++ ++/* unwrap a symmetric key with a private key with the given parameters. */ ++PK11SymKey * ++PK11_PubUnwrapSymKeyWithMechanism(SECKEYPrivateKey *wrappingKey, ++ CK_MECHANISM_TYPE mechType, SECItem *param, ++ SECItem *wrappedKey, CK_MECHANISM_TYPE target, ++ CK_ATTRIBUTE_TYPE operation, int keySize) ++{ + PK11SlotInfo *slot = wrappingKey->pkcs11Slot; + + if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) { + PK11_HandlePasswordCheck(slot, wrappingKey->wincx); + } + +- return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, +- wrapType, NULL, wrappedKey, target, operation, keySize, ++ return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, mechType, param, ++ wrappedKey, target, operation, keySize, + wrappingKey->wincx, NULL, 0, PR_FALSE); + } + +-- +2.33.0 + |