commit 0b0db692d859aee994b012a512b713140ba1e825 parent c9704533beb0bcf71ab2ce7cae798cc954632a4f Author: pstanciu <pstanciu@mozilla.com> Date: Wed, 22 Oct 2025 23:21:04 +0300 Revert "Bug 1992446 - upgrade NSS to 18dcc6d128e0b6f2acc3276e81669ec5870b713e. r=nss-reviewers,jschanck UPGRADE_NSS_RELEASE" for causing WPT failures @ ec_importKey.https.any.worker.html This reverts commit 7279cec1892bb643802f0bad6d992e25d147f85a. Diffstat:
14 files changed, 12 insertions(+), 427 deletions(-)
diff --git a/security/nss/gtests/pk11_gtest/pk11_import_unittest.cc b/security/nss/gtests/pk11_gtest/pk11_import_unittest.cc @@ -15,7 +15,6 @@ #include "nss_scoped_ptrs.h" #include "gtest/gtest.h" #include "databuffer.h" -#include "pk11_import_vectors.h" #include "pk11_keygen.h" namespace nss_test { @@ -299,121 +298,4 @@ INSTANTIATE_TEST_SUITE_P(Pk11KeyImportTestEC, Pk11KeyImportTestEC, SEC_OID_SECG_EC_SECP521R1, SEC_OID_CURVE25519)); -struct Pkcs11CompressedECKeyTestParams { - DataBuffer compressedKey; - DataBuffer uncompressedKey; -}; - -class Pk11KeyImportTestECCompressed - : public Pk11KeyImportTestBase, - public ::testing::WithParamInterface<Pkcs11CompressedECKeyTestParams> { - public: - Pk11KeyImportTestECCompressed() = default; - virtual ~Pk11KeyImportTestECCompressed() = default; -}; - -// Importing a private key in PKCS#8 format with a point not on the curve will -// succeed. Using the contained public key however will fail when trying to -// import it before using it for any operation. -TEST_P(Pk11KeyImportTestECCompressed, CompressedPointTest) { - DataBuffer spki(GetParam().compressedKey); - SECItem spki_item = {siBuffer, toUcharPtr(spki.data()), - static_cast<unsigned int>(spki.len())}; - - ScopedCERTSubjectPublicKeyInfo cert_spki( - SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); - ASSERT_TRUE(cert_spki); - ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get())); - ASSERT_TRUE(pub_key); - - ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); - ASSERT_TRUE(slot); - - CK_OBJECT_HANDLE id = - PK11_ImportPublicKey(slot.get(), pub_key.get(), PR_FALSE); - ASSERT_NE(id, (unsigned int)CK_INVALID_HANDLE); - - StackSECItem publicDecoded; - SECStatus rv = PK11_ReadRawAttribute(PK11_TypePubKey, pub_key.get(), - CKA_EC_POINT, &publicDecoded); - ASSERT_EQ(rv, SECSuccess); - - ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); - ASSERT_TRUE(arena); - - SECItem decodedItem; - rv = SEC_QuickDERDecodeItem(arena.get(), &decodedItem, - SEC_ASN1_GET(SEC_OctetStringTemplate), - &publicDecoded); - - ASSERT_EQ(rv, SECSuccess); - ASSERT_EQ(decodedItem.len, GetParam().uncompressedKey.len()); - ASSERT_EQ(0, PORT_Memcmp(decodedItem.data, GetParam().uncompressedKey.data(), - decodedItem.len)); -}; - -static const Pkcs11CompressedECKeyTestParams kCompressedVectors[] = { - {DataBuffer(kP256CompressedSpki, sizeof(kP256CompressedSpki)), - DataBuffer(kP256Uncompressed, sizeof(kP256Uncompressed))}, - {DataBuffer(kP384CompressedSpki, sizeof(kP384CompressedSpki)), - DataBuffer(kP384Uncompressed, sizeof(kP384Uncompressed))}, - {DataBuffer(kP521CompressedSpki, sizeof(kP521CompressedSpki)), - DataBuffer(kP521Uncompressed, sizeof(kP521Uncompressed))}}; - -INSTANTIATE_TEST_SUITE_P(Pk11KeyImportTestECCompressed, - Pk11KeyImportTestECCompressed, - ::testing::ValuesIn(kCompressedVectors)); - -// Importing a key with 0x7 sign value instead of 0x02/0x03 -TEST_F(Pk11KeyImportTestEC, CompressedPointWrongSign) { - DataBuffer spki(kP256CompressedSpkiWrongSign, - sizeof(kP256CompressedSpkiWrongSign)); - SECItem spki_item = {siBuffer, toUcharPtr(spki.data()), - static_cast<unsigned int>(spki.len())}; - - ScopedCERTSubjectPublicKeyInfo cert_spki( - SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); - ASSERT_TRUE(cert_spki); - ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get())); - ASSERT_TRUE(pub_key); - - ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); - ASSERT_TRUE(slot); - - CK_OBJECT_HANDLE id = - PK11_ImportPublicKey(slot.get(), pub_key.get(), PR_FALSE); - ASSERT_EQ(id, (unsigned int)CK_INVALID_HANDLE); -} - -TEST_F(Pk11KeyImportTestEC, CompressedPointWrongLen) { - DataBuffer spki(kP256CompressedSpkiWrongPointLength, - sizeof(kP256CompressedSpkiWrongPointLength)); - SECItem spki_item = {siBuffer, toUcharPtr(spki.data()), - static_cast<unsigned int>(spki.len())}; - - ScopedCERTSubjectPublicKeyInfo cert_spki( - SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); - ASSERT_FALSE(cert_spki); -} - -TEST_F(Pk11KeyImportTestEC, CompressedPointNotOnCurve) { - DataBuffer spki(kP256CompressedSpkiNotOnCurve, - sizeof(kP256CompressedSpkiNotOnCurve)); - SECItem spki_item = {siBuffer, toUcharPtr(spki.data()), - static_cast<unsigned int>(spki.len())}; - - ScopedCERTSubjectPublicKeyInfo cert_spki( - SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); - ASSERT_TRUE(cert_spki); - ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get())); - ASSERT_TRUE(pub_key); - - ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); - ASSERT_TRUE(slot); - - CK_OBJECT_HANDLE id = - PK11_ImportPublicKey(slot.get(), pub_key.get(), PR_FALSE); - ASSERT_NE(id, (unsigned int)CK_INVALID_HANDLE); -} - } // namespace nss_test diff --git a/security/nss/gtests/pk11_gtest/pk11_import_vectors.h b/security/nss/gtests/pk11_gtest/pk11_import_vectors.h @@ -1,85 +0,0 @@ -/* 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/. */ - -// The test -namespace nss_test { -const uint8_t kP256CompressedSpki[] = { - 0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x22, 0x00, 0x02, 0xd2, 0x10, 0xb0, 0xa6, 0xf9, 0xd9, 0xf0, 0x12, 0x86, - 0x80, 0x58, 0xb4, 0x3f, 0xa4, 0xf4, 0x71, 0x01, 0x85, 0x43, 0xbb, 0xa0, - 0x0c, 0x92, 0x50, 0xdf, 0x92, 0x57, 0xc2, 0xac, 0xae, 0x5d, 0xd1}; - -const uint8_t kP256Uncompressed[] = { - 0x04, 0xd2, 0x10, 0xb0, 0xa6, 0xf9, 0xd9, 0xf0, 0x12, 0x86, 0x80, - 0x58, 0xb4, 0x3f, 0xa4, 0xf4, 0x71, 0x01, 0x85, 0x43, 0xbb, 0xa0, - 0x0c, 0x92, 0x50, 0xdf, 0x92, 0x57, 0xc2, 0xac, 0xae, 0x5d, 0xd1, - 0xce, 0x03, 0x75, 0x52, 0xd4, 0x81, 0x45, 0x0c, 0xe3, 0x9b, 0x4d, - 0x10, 0x95, 0x70, 0x1b, 0x17, 0x5b, 0xfa, 0xb3, 0x4b, 0x8e, 0x6c, - 0x09, 0x9e, 0x18, 0xf1, 0xc1, 0x98, 0x35, 0x83, 0x61, 0xe8}; - -const uint8_t kP384CompressedSpki[] = { - 0x30, 0x46, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x32, 0x00, 0x02, - 0x21, 0x9c, 0x14, 0xd6, 0x66, 0x17, 0xb3, 0x6e, 0xc6, 0xd8, 0x85, 0x6b, - 0x38, 0x5b, 0x73, 0xa7, 0x4d, 0x34, 0x4f, 0xd8, 0xae, 0x75, 0xef, 0x04, - 0x64, 0x35, 0xdd, 0xa5, 0x4e, 0x3b, 0x44, 0xbd, 0x5f, 0xbd, 0xeb, 0xd1, - 0xd0, 0x8d, 0xd6, 0x9e, 0x2d, 0x7d, 0xc1, 0xdc, 0x21, 0x8c, 0xb4, 0x35}; - -const uint8_t kP384Uncompressed[] = { - 0x04, 0x21, 0x9c, 0x14, 0xd6, 0x66, 0x17, 0xb3, 0x6e, 0xc6, 0xd8, - 0x85, 0x6b, 0x38, 0x5b, 0x73, 0xa7, 0x4d, 0x34, 0x4f, 0xd8, 0xae, - 0x75, 0xef, 0x04, 0x64, 0x35, 0xdd, 0xa5, 0x4e, 0x3b, 0x44, 0xbd, - 0x5f, 0xbd, 0xeb, 0xd1, 0xd0, 0x8d, 0xd6, 0x9e, 0x2d, 0x7d, 0xc1, - 0xdc, 0x21, 0x8c, 0xb4, 0x35, 0xbd, 0x28, 0x13, 0x8c, 0xc7, 0x78, - 0x33, 0x7a, 0x84, 0x2f, 0x6b, 0xd6, 0x1b, 0x24, 0x0e, 0x74, 0x24, - 0x9f, 0x24, 0x66, 0x7c, 0x2a, 0x58, 0x10, 0xa7, 0x6b, 0xfc, 0x28, - 0xe0, 0x33, 0x5f, 0x88, 0xa6, 0x50, 0x1d, 0xec, 0x01, 0x97, 0x6d, - 0xa8, 0x5a, 0xfb, 0x00, 0x86, 0x9c, 0xb6, 0xac, 0xe8}; - -const uint8_t kP521CompressedSpki[] = { - 0x30, 0x58, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, 0x44, 0x00, 0x03, - 0x01, 0x56, 0xf4, 0x79, 0xf8, 0xdf, 0x1e, 0x20, 0xa7, 0xff, 0xc0, 0x4c, - 0xe4, 0x20, 0xc3, 0xe1, 0x54, 0xae, 0x25, 0x19, 0x96, 0xbe, 0xe4, 0x2f, - 0x03, 0x4b, 0x84, 0xd4, 0x1b, 0x74, 0x3f, 0x34, 0xe4, 0x5f, 0x31, 0x1b, - 0x81, 0x3a, 0x9c, 0xde, 0xc8, 0xcd, 0xa5, 0x9b, 0xbb, 0xbd, 0x31, 0xd4, - 0x60, 0xb3, 0x29, 0x25, 0x21, 0xe7, 0xc1, 0xb7, 0x22, 0xe5, 0x66, 0x7c, - 0x03, 0xdb, 0x2f, 0xae, 0x75, 0x3f}; - -const uint8_t kP521Uncompressed[] = { - 0x04, 0x01, 0x56, 0xf4, 0x79, 0xf8, 0xdf, 0x1e, 0x20, 0xa7, 0xff, 0xc0, - 0x4c, 0xe4, 0x20, 0xc3, 0xe1, 0x54, 0xae, 0x25, 0x19, 0x96, 0xbe, 0xe4, - 0x2f, 0x03, 0x4b, 0x84, 0xd4, 0x1b, 0x74, 0x3f, 0x34, 0xe4, 0x5f, 0x31, - 0x1b, 0x81, 0x3a, 0x9c, 0xde, 0xc8, 0xcd, 0xa5, 0x9b, 0xbb, 0xbd, 0x31, - 0xd4, 0x60, 0xb3, 0x29, 0x25, 0x21, 0xe7, 0xc1, 0xb7, 0x22, 0xe5, 0x66, - 0x7c, 0x03, 0xdb, 0x2f, 0xae, 0x75, 0x3f, 0x01, 0x50, 0x17, 0x36, 0xcf, - 0xe2, 0x47, 0x39, 0x43, 0x20, 0xd8, 0xe4, 0xaf, 0xc2, 0xfd, 0x39, 0xb5, - 0xa9, 0x33, 0x10, 0x61, 0xb8, 0x1e, 0x22, 0x41, 0x28, 0x2b, 0x9e, 0x17, - 0x89, 0x18, 0x22, 0xb5, 0xb7, 0x9e, 0x05, 0x2f, 0x45, 0x97, 0xb5, 0x96, - 0x43, 0xfd, 0x39, 0x37, 0x9c, 0x51, 0xbd, 0x51, 0x25, 0xc4, 0xf4, 0x8b, - 0xc3, 0xf0, 0x25, 0xce, 0x3c, 0xd3, 0x69, 0x53, 0x28, 0x6c, 0xcb, 0x38, - 0xfb}; - -const uint8_t kP256CompressedSpkiWrongSign[] = { - 0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x22, 0x00, 0x07, 0xd2, 0x10, 0xb0, 0xa6, 0xf9, 0xd9, 0xf0, 0x12, 0x86, - 0x80, 0x58, 0xb4, 0x3f, 0xa4, 0xf4, 0x71, 0x01, 0x85, 0x43, 0xbb, 0xa0, - 0x0c, 0x92, 0x50, 0xdf, 0x92, 0x57, 0xc2, 0xac, 0xae, 0x5d, 0xd1}; - -const uint8_t kP256CompressedSpkiWrongPointLength[] = { - 0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x22, 0x00, 0x02, 0xd2, 0x10, 0xb0, 0xa6, 0xf9, 0xd9, 0xf0, 0x12, 0x86, - 0x80, 0x58, 0xb4, 0x3f, 0xa4, 0xf4, 0x71, 0x01, 0x85, 0x43, 0xbb, 0xa0, - 0x0c, 0x92, 0x50, 0xdf, 0x92, 0x57, 0xc2, 0xac, 0xae, 0x5d}; - -const uint8_t kP256CompressedSpkiNotOnCurve[] = { - 0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x22, 0x00, 0x02, 0xd2, 0x10, 0xb0, 0xa6, 0xf9, 0xd9, 0xf0, 0x12, 0x86, - 0x80, 0x58, 0xb4, 0x3f, 0xa4, 0xf4, 0x71, 0x01, 0x85, 0x43, 0xbb, 0xa0, - 0x0c, 0x92, 0x50, 0xdf, 0x92, 0x57, 0xc2, 0xac, 0xae, 0x5d, 0xd2}; -} // namespace nss_test diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c @@ -2158,7 +2158,6 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage chain = CERT_NewCertList(); if (NULL == chain) { - CERT_DestroyCertificate(cert); PORT_SetError(SEC_ERROR_NO_MEMORY); return NULL; } @@ -2166,7 +2165,6 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) { if (SECSuccess != CERT_AddCertToListTail(chain, cert)) { /* return partial chain */ - CERT_DestroyCertificate(cert); PORT_SetError(SEC_ERROR_NO_MEMORY); return chain; } @@ -2180,7 +2178,6 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage } /* return partial chain */ - CERT_DestroyCertificate(cert); PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); return chain; } diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h @@ -1962,13 +1962,6 @@ SECStatus MLDSA_VerifyInit(MLDSAPublicKey *key, const SECItem *sgnCtx, SECStatus MLDSA_VerifyUpdate(MLDSAContext *ctx, const SECItem *data); SECStatus MLDSA_VerifyFinal(MLDSAContext *ctx, const SECItem *signature); -/* Decompress public key. - ** On input, publicCompressed == buffer containing compressed key - ** Output, publicRaw == decompressed public key. The function returns true iff the - ** decompressed key belongs to the appropriate curve. - */ -SECStatus EC_DecompressPublicKey(const SECItem *publicCompressed, const ECParams *params, SECItem *publicUncompressed); - SEC_END_PROTOS #endif /* _BLAPI_H_ */ diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c @@ -710,21 +710,3 @@ EC_DerivePublicKey(const SECItem *privateKey, const ECParams *ecParams, SECItem return method->pt_mul(publicKey, (SECItem *)privateKey, NULL); } - -/* Supported only for P-256, P-384 and P-521*/ -SECStatus -EC_DecompressPublicKey(const SECItem *publicCompressed, const ECParams *ecParams, SECItem *publicUncompressed) -{ - /* I don't think that we need a special ECMethod extension for decompression. */ - switch (ecParams->name) { - case ECCurve_NIST_P256: - return ec_secp256r1_decompress(publicCompressed, publicUncompressed); - case ECCurve_NIST_P384: - return ec_secp384r1_decompress(publicCompressed, publicUncompressed); - case ECCurve_NIST_P521: - return ec_secp521r1_decompress(publicCompressed, publicUncompressed); - default: - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); - return SECFailure; - } -} diff --git a/security/nss/lib/freebl/ecl/ecl.h b/security/nss/lib/freebl/ecl/ecl.h @@ -26,8 +26,6 @@ SECStatus ec_secp256r1_sign_digest(ECPrivateKey *key, SECItem *signature, SECStatus ec_secp256r1_verify_digest(ECPublicKey *key, const SECItem *signature, const SECItem *digest); -SECStatus ec_secp256r1_decompress(const SECItem *publicCompressed, SECItem *publicRaw); - SECStatus ec_secp521r1_pt_mul(SECItem *X, SECItem *k, SECItem *P); SECStatus ec_secp521r1_pt_validate(const SECItem *px); SECStatus ec_secp521r1_scalar_validate(const SECItem *scalar); @@ -37,7 +35,6 @@ SECStatus ec_secp521r1_sign_digest(ECPrivateKey *key, SECItem *signature, const unsigned int kblen); SECStatus ec_secp521r1_verify_digest(ECPublicKey *key, const SECItem *signature, const SECItem *digest); -SECStatus ec_secp521r1_decompress(const SECItem *publicCompressed, SECItem *publicRaw); SECStatus ec_secp384r1_pt_mul(SECItem *X, SECItem *k, SECItem *P); SECStatus ec_secp384r1_pt_validate(const SECItem *px); @@ -48,6 +45,5 @@ SECStatus ec_secp384r1_sign_digest(ECPrivateKey *key, SECItem *signature, const unsigned int kblen); SECStatus ec_secp384r1_verify_digest(ECPublicKey *key, const SECItem *signature, const SECItem *digest); -SECStatus ec_secp384r1_decompress(const SECItem *publicCompressed, SECItem *publicRaw); #endif /* __ecl_h_ */ diff --git a/security/nss/lib/freebl/ecl/ecp_secp256r1.c b/security/nss/lib/freebl/ecl/ecp_secp256r1.c @@ -314,52 +314,3 @@ ec_secp256r1_verify_digest(ECPublicKey *key, const SECItem *signature, return res; } - -/* - Point decompression for P-256. - - publicCompressed must be 33 bytes (1 byte for a sign and 32 bytes for the x coordinate. - publicUncompressed must be 64 bytes (32 * 2). - The function returns SECSuccess if the decompression was success and the decompresse - point is a valid P-256 curve point. -*/ - -SECStatus -ec_secp256r1_decompress(const SECItem *publicCompressed, SECItem *publicUncompressed) -{ - if (!publicCompressed || !publicCompressed->data) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicCompressed->len != 33) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - if (!publicUncompressed || !publicUncompressed->data) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicUncompressed->len != 65) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y0 && - publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y1) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); - return SECFailure; - } - - bool b = Hacl_P256_compressed_to_raw(publicCompressed->data, publicUncompressed->data + 1); - - if (!b) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - publicUncompressed->data[0] = EC_POINT_FORM_UNCOMPRESSED; - return SECSuccess; -} diff --git a/security/nss/lib/freebl/ecl/ecp_secp384r1.c b/security/nss/lib/freebl/ecl/ecp_secp384r1.c @@ -311,52 +311,3 @@ ec_secp384r1_verify_digest(ECPublicKey *key, const SECItem *signature, return res; } - -/* - Point decompression for P-384. - - publicCompressed must be 49 bytes (1 byte for a sign and 48 bytes for the x coordinate. - publicUncompressed must be 96 bytes (48 * 2). - The function returns SECSuccess if the decompression was success and the decompresse - point is a valid P-384 curve point. -*/ - -SECStatus -ec_secp384r1_decompress(const SECItem *publicCompressed, SECItem *publicUncompressed) -{ - if (!publicCompressed || !publicCompressed->data) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicCompressed->len != 49) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - if (!publicUncompressed || !publicUncompressed->data) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicUncompressed->len != 97) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y0 && - publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y1) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); - return SECFailure; - } - - bool b = Hacl_P384_compressed_to_raw(publicCompressed->data, publicUncompressed->data + 1); - - if (!b) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - publicUncompressed->data[0] = EC_POINT_FORM_UNCOMPRESSED; - return SECSuccess; -} diff --git a/security/nss/lib/freebl/ecl/ecp_secp521r1.c b/security/nss/lib/freebl/ecl/ecp_secp521r1.c @@ -317,52 +317,3 @@ ec_secp521r1_verify_digest(ECPublicKey *key, const SECItem *signature, return res; } - -/* - Point decompression for P-521. - - publicCompressed must be 67 bytes (1 byte for a sign and 66 bytes for the x coordinate. - publicUncompressed must be 132 bytes (66 * 2). - The function returns SECSuccess if the decompression was success and the decompresse - point is a valid P-521 curve point. -*/ - -SECStatus -ec_secp521r1_decompress(const SECItem *publicCompressed, SECItem *publicUncompressed) -{ - if (!publicCompressed || !publicCompressed->data) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicCompressed->len != 67) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - if (!publicUncompressed || !publicUncompressed->data) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicUncompressed->len != 133) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y0 && - publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y1) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); - return SECFailure; - } - - bool b = Hacl_P521_compressed_to_raw(publicCompressed->data, publicUncompressed->data + 1); - - if (!b) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - publicUncompressed->data[0] = EC_POINT_FORM_UNCOMPRESSED; - return SECSuccess; -} diff --git a/security/nss/lib/freebl/ldvector.c b/security/nss/lib/freebl/ldvector.c @@ -459,9 +459,6 @@ static const struct FREEBLVectorStr vector = { MLDSA_VerifyFinal, /* End of version 3.031 */ - EC_DecompressPublicKey, - /* End of version 3.032 */ - }; const FREEBLVector* diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c @@ -2958,12 +2958,3 @@ MLDSA_VerifyFinal(MLDSAContext *ctx, const SECItem *signature) return SECFailure; return (vector->p_MLDSA_VerifyFinal)(ctx, signature); } - -/* ============== New for 3.0032 =============================== */ -SECStatus -EC_DecompressPublicKey(const SECItem *publicCompressed, const ECParams *params, SECItem *publicUncompressed) -{ - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return SECFailure; - return (vector->p_EC_DecompressPublicKey)(publicCompressed, params, publicUncompressed); -} diff --git a/security/nss/lib/freebl/loader.h b/security/nss/lib/freebl/loader.h @@ -10,7 +10,7 @@ #include "blapi.h" -#define FREEBL_VERSION 0x0332 +#define FREEBL_VERSION 0x0331 struct FREEBLVectorStr { @@ -940,9 +940,6 @@ struct FREEBLVectorStr { SECStatus (*p_MLDSA_VerifyFinal)(MLDSAContext *ctx, const SECItem *signature); /* Version 3.031 came to here */ - SECStatus (*p_EC_DecompressPublicKey)(const SECItem *publicCompressed, const ECParams *params, SECItem *publicUncompressed); - /* Version 3.032 came to here */ - /* Add new function pointers at the end of this struct and bump * FREEBL_VERSION at the beginning of this file. */ }; diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c @@ -1254,6 +1254,7 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, sizeof(CK_BBOOL)); if (crv != CKR_OK) return crv; + object->objectInfo = sftk_GetPubKey(object, key_type, &crv); if (object->objectInfo == NULL) { return crv; @@ -2185,6 +2186,7 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, object, CKA_EC_POINT); if (crv == CKR_OK) { unsigned int keyLen = EC_GetPointSize(&pubKey->u.ec.ecParams); + /* special note: We can't just use the first byte to distinguish * between EC_POINT_FORM_UNCOMPRESSED and SEC_ASN1_OCTET_STRING. * Both are 0x04. */ @@ -2192,8 +2194,6 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, /* Handle the non-DER encoded case. * Some curves are always pressumed to be non-DER. */ - - /* is the public key in uncompressed form? */ if (pubKey->u.ec.ecParams.type != ec_params_named || (pubKey->u.ec.publicValue.len == keyLen && pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED)) { @@ -2201,7 +2201,8 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, } /* handle the encoded case */ - if (pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING) { + if ((pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING) && + pubKey->u.ec.publicValue.len > keyLen) { SECItem publicValue; SECStatus rv; @@ -2209,36 +2210,17 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, SEC_ASN1_GET(SEC_OctetStringTemplate), &pubKey->u.ec.publicValue); /* nope, didn't decode correctly */ - if (rv != SECSuccess) { + if ((rv != SECSuccess) || (publicValue.len != keyLen)) { crv = CKR_ATTRIBUTE_VALUE_INVALID; break; } - - if (publicValue.len == keyLen && publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED) { - /* Received uncompressed point */ - pubKey->u.ec.publicValue = publicValue; - break; - } - - /* Trying to decompress */ - SECItem publicDecompressed = { siBuffer, NULL, 0 }; - (void)SECITEM_AllocItem(arena, &publicDecompressed, keyLen); - if (EC_DecompressPublicKey(&publicValue, &pubKey->u.ec.ecParams, &publicDecompressed) == SECFailure) { + /* we don't handle compressed points except in the case of ECCurve25519 */ + if (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) { crv = CKR_ATTRIBUTE_VALUE_INVALID; break; } - - /* replace our previous public key with the decoded decompressed key */ - pubKey->u.ec.publicValue = publicDecompressed; - - SECItem publicDecompressedEncoded = { siBuffer, NULL, 0 }; - (void)SEC_ASN1EncodeItem(arena, &publicDecompressedEncoded, &publicDecompressed, - SEC_ASN1_GET(SEC_OctetStringTemplate)); - if (CKR_OK != sftk_forceAttribute(object, CKA_EC_POINT, sftk_item_expand(&publicDecompressedEncoded))) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - + /* replace our previous with the decoded key */ + pubKey->u.ec.publicValue = publicValue; break; } crv = CKR_ATTRIBUTE_VALUE_INVALID; diff --git a/security/nss/moz.yaml b/security/nss/moz.yaml @@ -9,8 +9,8 @@ origin: description: nss url: https://hg-edge.mozilla.org/projects/nss - release: 18dcc6d128e0b6f2acc3276e81669ec5870b713e (2025-10-21T09:55:25Z). - revision: 18dcc6d128e0b6f2acc3276e81669ec5870b713e + release: f9041cc46f7495257b639e7e36fa8f2f0d50faa0 (2025-10-13T23:31:48Z). + revision: f9041cc46f7495257b639e7e36fa8f2f0d50faa0 license: MPL-2.0 license-file: COPYING