Bug 1339789, Upgrade to NSS 3.28.3 to fix binary compatibility issues, a=jcristau
authorKai Engert <kaie@kuix.de>
Mon, 20 Feb 2017 15:17:19 +0100
changeset 354344 b570b28bb0f5092d293de5a70bc4d4c840460ee0
parent 354343 42db8a0b3673b959560b0edc2ac89a44576bddd1
child 354345 346bcdd75fc230161035bf31c319ee170160e1fb
push id6897
push userryanvm@gmail.com
push dateTue, 21 Feb 2017 21:41:19 +0000
treeherdermozilla-esr52@0316bb85a29c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcristau
bugs1339789
milestone52.0
Bug 1339789, Upgrade to NSS 3.28.3 to fix binary compatibility issues, a=jcristau
old-configure.in
security/nss/TAG-INFO
security/nss/cmd/bltest/blapitest.c
security/nss/cmd/ecperf/ecperf.c
security/nss/cmd/fbectest/fbectest.c
security/nss/cmd/fipstest/fipstest.c
security/nss/coreconf/coreconf.dep
security/nss/lib/cryptohi/keyi.h
security/nss/lib/cryptohi/keythi.h
security/nss/lib/cryptohi/seckey.c
security/nss/lib/freebl/blapi.h
security/nss/lib/freebl/blapit.h
security/nss/lib/freebl/ec.c
security/nss/lib/freebl/ecdecode.c
security/nss/lib/freebl/ldvector.c
security/nss/lib/freebl/loader.c
security/nss/lib/freebl/loader.h
security/nss/lib/nss/nss.h
security/nss/lib/pk11wrap/pk11akey.c
security/nss/lib/pk11wrap/pk11skey.c
security/nss/lib/softoken/pkcs11.c
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/softoken/softkver.h
security/nss/lib/ssl/ssl3ecc.c
security/nss/lib/util/eccutil.h
security/nss/lib/util/nssutil.h
--- a/old-configure.in
+++ b/old-configure.in
@@ -2118,17 +2118,17 @@ dnl = If NSS was not detected in the sys
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
-    AM_PATH_NSS(3.28.1, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
+    AM_PATH_NSS(3.28.3, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_SYSTEM_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS="-I${DIST}/include/nss"
 fi
 
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_28_2_RTM
+NSS_3_28_3_RTM
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -1866,17 +1866,16 @@ bltest_ecdsa_init(bltestCipherInfo *ciph
         pubkey->ecParams.base.len = key->ecParams.base.len;
         pubkey->ecParams.base.data = key->ecParams.base.data;
         pubkey->ecParams.order.len = key->ecParams.order.len;
         pubkey->ecParams.order.data = key->ecParams.order.data;
         pubkey->ecParams.cofactor = key->ecParams.cofactor;
         pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
         pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
         pubkey->ecParams.name = key->ecParams.name;
-        pubkey->ecParams.pointSize = key->ecParams.pointSize;
         pubkey->publicValue.len = key->publicValue.len;
         pubkey->publicValue.data = key->publicValue.data;
         asymk->pubKey = pubkey;
         cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
     }
     return SECSuccess;
 }
 #endif
--- a/security/nss/cmd/ecperf/ecperf.c
+++ b/security/nss/cmd/ecperf/ecperf.c
@@ -558,17 +558,16 @@ ectest_curve_freebl(ECCurveName curve, i
     ecParams.name = curve;
     ecParams.type = ec_params_named;
     ecParams.curveOID.data = NULL;
     ecParams.curveOID.len = 0;
     ecParams.curve.seed.data = NULL;
     ecParams.curve.seed.len = 0;
     ecParams.DEREncoding.data = NULL;
     ecParams.DEREncoding.len = 0;
-    ecParams.pointSize = ecCurve_map[curve]->pointSize;
 
     ecParams.fieldID.size = ecCurve_map[curve]->size;
     ecParams.fieldID.type = fieldType;
     SECU_HexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
     SECU_HexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
     SECU_HexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
     genenc[0] = '0';
     genenc[1] = '4';
--- a/security/nss/cmd/fbectest/fbectest.c
+++ b/security/nss/cmd/fbectest/fbectest.c
@@ -67,17 +67,16 @@ init_params(ECParams *ecParams, ECCurveN
     ecParams->curve.seed.data = NULL;
     ecParams->curve.seed.len = 0;
     ecParams->DEREncoding.data = NULL;
     ecParams->DEREncoding.len = 0;
     ecParams->arena = *arena;
     ecParams->fieldID.size = ecCurve_map[curve]->size;
     ecParams->fieldID.type = type;
     ecParams->cofactor = ecCurve_map[curve]->cofactor;
-    ecParams->pointSize = ecCurve_map[curve]->pointSize;
 
     return SECSuccess;
 }
 
 SECStatus
 ectest_ecdh_kat(ECDH_KAT *kat)
 {
     ECCurveName curve = kat->curve;
--- a/security/nss/cmd/fipstest/fipstest.c
+++ b/security/nss/cmd/fipstest/fipstest.c
@@ -2518,17 +2518,17 @@ ecdsa_pkv_test(char *reqfn)
                 goto loser;
             }
             SECITEM_FreeItem(encodedparams, PR_TRUE);
             len = (ecparams->fieldID.size + 7) >> 3;
             if (pubkey.data != NULL) {
                 PORT_Free(pubkey.data);
                 pubkey.data = NULL;
             }
-            SECITEM_AllocItem(NULL, &pubkey, ecparams->pointSize);
+            SECITEM_AllocItem(NULL, &pubkey, EC_GetPointSize(ecparams));
             if (pubkey.data == NULL) {
                 goto loser;
             }
             pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
             fputs(buf, ecdsaresp);
             continue;
         }
         /* Qx = ... */
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
--- a/security/nss/lib/cryptohi/keyi.h
+++ b/security/nss/lib/cryptohi/keyi.h
@@ -12,18 +12,11 @@ SEC_BEGIN_PROTOS
 KeyType seckey_GetKeyType(SECOidTag pubKeyOid);
 
 /* extract the 'encryption' (could be signing) and hash oids from and
  * algorithm, key and parameters (parameters is the parameters field
  * of a algorithm ID structure (SECAlgorithmID)*/
 SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
                            const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg);
 
-/*
- * Set the point encoding of a SECKEYPublicKey from the OID.
- * This has to be called on any SECKEYPublicKey holding a SECKEYECPublicKey
- * before it can be used. The encoding is used to dermine the public key size.
- */
-SECStatus seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey);
-
 SEC_END_PROTOS
 
 #endif /* _KEYHI_H_ */
--- a/security/nss/lib/cryptohi/keythi.h
+++ b/security/nss/lib/cryptohi/keythi.h
@@ -120,19 +120,19 @@ typedef struct SECKEYDHPublicKeyStr SECK
 ** Elliptic curve Public Key structure
 ** The PKCS#11 layer needs DER encoding of ANSI X9.62
 ** parameters value
 */
 typedef SECItem SECKEYECParams;
 
 struct SECKEYECPublicKeyStr {
     SECKEYECParams DEREncodedParams;
-    int size;            /* size in bits */
-    SECItem publicValue; /* encoded point */
-    ECPointEncoding encoding;
+    int size;                 /* size in bits */
+    SECItem publicValue;      /* encoded point */
+    ECPointEncoding encoding; /* deprecated, ignored */
 };
 typedef struct SECKEYECPublicKeyStr SECKEYECPublicKey;
 
 /*
 ** FORTEZZA Public Key structures
 */
 struct SECKEYFortezzaPublicKeyStr {
     int KEAversion;
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -542,16 +542,33 @@ seckey_GetKeyType(SECOidTag tag)
 
 /* Function used to determine what kind of cert we are dealing with. */
 KeyType
 CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki)
 {
     return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm));
 }
 
+/* Ensure pubKey contains an OID */
+static SECStatus
+seckey_HasCurveOID(const SECKEYPublicKey *pubKey)
+{
+    SECItem oid;
+    SECStatus rv;
+    PORTCheapArenaPool tmpArena;
+
+    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+    /* If we can decode it, an OID is available. */
+    rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid,
+                                SEC_ASN1_GET(SEC_ObjectIDTemplate),
+                                &pubKey->u.ec.DEREncodedParams);
+    PORT_DestroyCheapArena(&tmpArena);
+    return rv;
+}
+
 static SECKEYPublicKey *
 seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
 {
     SECKEYPublicKey *pubk;
     SECItem os, newOs, newParms;
     SECStatus rv;
     PLArenaPool *arena;
     SECOidTag tag;
@@ -634,17 +651,18 @@ seckey_ExtractPublicKey(const CERTSubjec
                                       &spki->algorithm.parameters);
                 if (rv != SECSuccess) {
                     break;
                 }
                 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
                 if (rv != SECSuccess) {
                     break;
                 }
-                rv = seckey_SetPointEncoding(arena, pubk);
+                pubk->u.ec.encoding = ECPoint_Undefined;
+                rv = seckey_HasCurveOID(pubk);
                 if (rv == SECSuccess) {
                     return pubk;
                 }
                 break;
 
             default:
                 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
                 break;
@@ -1157,26 +1175,26 @@ SECKEY_CopyPublicKey(const SECKEYPublicK
             rv = SECITEM_CopyItem(arena, &copyk->u.dh.base, &pubk->u.dh.base);
             if (rv != SECSuccess)
                 break;
             rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
                                   &pubk->u.dh.publicValue);
             break;
         case ecKey:
             copyk->u.ec.size = pubk->u.ec.size;
+            rv = seckey_HasCurveOID(pubk);
+            if (rv != SECSuccess) {
+                break;
+            }
             rv = SECITEM_CopyItem(arena, &copyk->u.ec.DEREncodedParams,
                                   &pubk->u.ec.DEREncodedParams);
             if (rv != SECSuccess) {
                 break;
             }
-            rv = seckey_SetPointEncoding(arena, copyk);
-            if (rv != SECSuccess) {
-                break;
-            }
-            PORT_Assert(copyk->u.ec.encoding == pubk->u.ec.encoding);
+            copyk->u.ec.encoding = ECPoint_Undefined;
             rv = SECITEM_CopyItem(arena, &copyk->u.ec.publicValue,
                                   &pubk->u.ec.publicValue);
             break;
         case nullKey:
             return copyk;
         default:
             PORT_SetError(SEC_ERROR_INVALID_KEY);
             rv = SECFailure;
@@ -1938,44 +1956,8 @@ SECKEY_GetECCOid(const SECKEYECParams *p
         return 0;
     oid.len = params->len - 2;
     oid.data = params->data + 2;
     if ((oidData = SECOID_FindOID(&oid)) == NULL)
         return 0;
 
     return oidData->offset;
 }
-
-/* Set curve encoding in SECKEYECPublicKey in pubKey from OID.
- * If the encoding is not set, determining the key size of EC public keys will
- * fail.
- */
-SECStatus
-seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey)
-{
-    SECItem oid;
-    SECOidTag tag;
-    SECStatus rv;
-
-    /* decode the OID tag */
-    rv = SEC_QuickDERDecodeItem(arena, &oid, SEC_ASN1_GET(SEC_ObjectIDTemplate),
-                                &pubKey->u.ec.DEREncodedParams);
-    if (rv != SECSuccess) {
-        return SECFailure;
-    }
-
-    tag = SECOID_FindOIDTag(&oid);
-    switch (tag) {
-        case SEC_OID_CURVE25519:
-            pubKey->u.ec.encoding = ECPoint_XOnly;
-            break;
-        case SEC_OID_SECG_EC_SECP256R1:
-        /* fall through */
-        case SEC_OID_SECG_EC_SECP384R1:
-        /* fall through */
-        case SEC_OID_SECG_EC_SECP521R1:
-        /* fall through */
-        default:
-            /* unknown curve, default to uncompressed */
-            pubKey->u.ec.encoding = ECPoint_Uncompressed;
-    }
-    return SECSuccess;
-}
--- a/security/nss/lib/freebl/blapi.h
+++ b/security/nss/lib/freebl/blapi.h
@@ -1594,23 +1594,26 @@ PRBool BLAPI_SHVerifyFile(const char *sh
  **************************************************************************/
 PRBool BLAPI_VerifySelf(const char *name);
 
 /*********************************************************************/
 extern const SECHashObject *HASH_GetRawHashObject(HASH_HashType hashType);
 
 extern void BL_SetForkState(PRBool forked);
 
-#ifndef NSS_DISABLE_ECC
 /*
 ** pepare an ECParam structure from DEREncoded params
  */
 extern SECStatus EC_FillParams(PLArenaPool *arena,
                                const SECItem *encodedParams, ECParams *params);
 extern SECStatus EC_DecodeParams(const SECItem *encodedParams,
                                  ECParams **ecparams);
 extern SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
                                const ECParams *srcParams);
-#endif
+
+/*
+ * use the internal table to get the size in bytes of a single EC point
+ */
+extern int EC_GetPointSize(const ECParams *params);
 
 SEC_END_PROTOS
 
 #endif /* _BLAPI_H_ */
--- a/security/nss/lib/freebl/blapit.h
+++ b/security/nss/lib/freebl/blapit.h
@@ -372,17 +372,16 @@ struct ECParamsStr {
     ECFieldID fieldID;
     ECCurve curve;
     SECItem base;
     SECItem order;
     int cofactor;
     SECItem DEREncoding;
     ECCurveName name;
     SECItem curveOID;
-    int pointSize;
 };
 typedef struct ECParamsStr ECParams;
 
 struct ECPublicKeyStr {
     ECParams ecParams;
     SECItem publicValue; /* elliptic curve point encoded as
                 * octet stream.
                 */
--- a/security/nss/lib/freebl/ec.c
+++ b/security/nss/lib/freebl/ec.c
@@ -228,17 +228,16 @@ ec_NewKey(ECParams *ecParams, ECPrivateK
 
     /* Copy all of the fields from the ECParams argument to the
      * ECParams structure within the private key.
      */
     key->ecParams.arena = arena;
     key->ecParams.type = ecParams->type;
     key->ecParams.fieldID.size = ecParams->fieldID.size;
     key->ecParams.fieldID.type = ecParams->fieldID.type;
-    key->ecParams.pointSize = ecParams->pointSize;
     if (ecParams->fieldID.type == ec_field_GFp ||
         ecParams->fieldID.type == ec_field_plain) {
         CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
                                       &ecParams->fieldID.u.prime));
     } else {
         CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
                                       &ecParams->fieldID.u.poly));
     }
@@ -257,17 +256,17 @@ ec_NewKey(ECParams *ecParams, ECPrivateK
                                   &ecParams->order));
     key->ecParams.cofactor = ecParams->cofactor;
     CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
                                   &ecParams->DEREncoding));
     key->ecParams.name = ecParams->name;
     CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
                                   &ecParams->curveOID));
 
-    SECITEM_AllocItem(arena, &key->publicValue, ecParams->pointSize);
+    SECITEM_AllocItem(arena, &key->publicValue, EC_GetPointSize(ecParams));
     len = ecParams->order.len;
     SECITEM_AllocItem(arena, &key->privateValue, len);
 
     /* Copy private key */
     if (privKeyLen >= len) {
         memcpy(key->privateValue.data, privKeyBytes, len);
     } else {
         memset(key->privateValue.data, 0, (len - privKeyLen));
@@ -565,17 +564,17 @@ ECDH_Derive(SECItem *publicValue,
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     /* Perform curve specific multiplication using ECMethod */
     if (ecParams->fieldID.type == ec_field_plain) {
         const ECMethod *method;
         memset(derivedSecret, 0, sizeof(*derivedSecret));
-        derivedSecret = SECITEM_AllocItem(NULL, derivedSecret, ecParams->pointSize);
+        derivedSecret = SECITEM_AllocItem(NULL, derivedSecret, EC_GetPointSize(ecParams));
         if (derivedSecret == NULL) {
             PORT_SetError(SEC_ERROR_NO_MEMORY);
             return SECFailure;
         }
         method = ec_get_method_from_name(ecParams->name);
         if (method == NULL || method->validate == NULL ||
             method->mul == NULL) {
             PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
@@ -595,18 +594,18 @@ ECDH_Derive(SECItem *publicValue,
     if (ec_point_at_infinity(publicValue)) {
         PORT_SetError(SEC_ERROR_BAD_KEY);
         return SECFailure;
     }
 
     MP_DIGITS(&k) = 0;
     memset(derivedSecret, 0, sizeof *derivedSecret);
     len = (ecParams->fieldID.size + 7) >> 3;
-    pointQ.len = ecParams->pointSize;
-    if ((pointQ.data = PORT_Alloc(ecParams->pointSize)) == NULL)
+    pointQ.len = EC_GetPointSize(ecParams);
+    if ((pointQ.data = PORT_Alloc(pointQ.len)) == NULL)
         goto cleanup;
 
     CHECK_MPI_OK(mp_init(&k));
     CHECK_MPI_OK(mp_read_unsigned_octets(&k, privateValue->data,
                                          (mp_size)privateValue->len));
 
     if (withCofactor && (ecParams->cofactor != 1)) {
         /* multiply k with the cofactor */
@@ -643,17 +642,17 @@ ECDH_Derive(SECItem *publicValue,
 cleanup:
     mp_clear(&k);
 
     if (err) {
         MP_TO_SEC_ERROR(err);
     }
 
     if (pointQ.data) {
-        PORT_ZFree(pointQ.data, ecParams->pointSize);
+        PORT_ZFree(pointQ.data, pointQ.len);
     }
 #else
     PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
 #endif /* NSS_DISABLE_ECC */
 
     return rv;
 }
 
@@ -758,18 +757,18 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *k
         CHECK_MPI_OK(mp_add(&k, &n, &k));
     }
 
     /*
     ** ANSI X9.62, Section 5.3.2, Step 2
     **
     ** Compute kG
     */
-    kGpoint.len = ecParams->pointSize;
-    kGpoint.data = PORT_Alloc(ecParams->pointSize);
+    kGpoint.len = EC_GetPointSize(ecParams);
+    kGpoint.data = PORT_Alloc(kGpoint.len);
     if ((kGpoint.data == NULL) ||
         (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint) != SECSuccess))
         goto cleanup;
 
     /*
     ** ANSI X9.62, Section 5.3.3, Step 1
     **
     ** Extract the x co-ordinate of kG into x1
@@ -878,17 +877,17 @@ cleanup:
     mp_clear(&n);
     mp_clear(&t);
 
     if (t2) {
         PORT_Free(t2);
     }
 
     if (kGpoint.data) {
-        PORT_ZFree(kGpoint.data, ecParams->pointSize);
+        PORT_ZFree(kGpoint.data, kGpoint.len);
     }
 
     if (err) {
         MP_TO_SEC_ERROR(err);
         rv = SECFailure;
     }
 
 #if EC_DEBUG
@@ -997,17 +996,17 @@ ECDSA_VerifyDigest(ECPublicKey *key, con
     olen = ecParams->order.len;
     if (signature->len == 0 || signature->len % 2 != 0 ||
         signature->len > 2 * olen) {
         PORT_SetError(SEC_ERROR_INPUT_LEN);
         goto cleanup;
     }
     slen = signature->len / 2;
 
-    SECITEM_AllocItem(NULL, &pointC, ecParams->pointSize);
+    SECITEM_AllocItem(NULL, &pointC, EC_GetPointSize(ecParams));
     if (pointC.data == NULL)
         goto cleanup;
 
     CHECK_MPI_OK(mp_init(&r_));
     CHECK_MPI_OK(mp_init(&s_));
     CHECK_MPI_OK(mp_init(&c));
     CHECK_MPI_OK(mp_init(&u1));
     CHECK_MPI_OK(mp_init(&u2));
--- a/security/nss/lib/freebl/ecdecode.c
+++ b/security/nss/lib/freebl/ecdecode.c
@@ -80,17 +80,16 @@ EC_CopyParams(PLArenaPool *arena, ECPara
               const ECParams *srcParams)
 {
     SECStatus rv = SECFailure;
 
     dstParams->arena = arena;
     dstParams->type = srcParams->type;
     dstParams->fieldID.size = srcParams->fieldID.size;
     dstParams->fieldID.type = srcParams->fieldID.type;
-    dstParams->pointSize = srcParams->pointSize;
     if (srcParams->fieldID.type == ec_field_GFp ||
         srcParams->fieldID.type == ec_field_plain) {
         CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime,
                                       &srcParams->fieldID.u.prime));
     } else {
         CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly,
                                       &srcParams->fieldID.u.poly));
     }
@@ -130,17 +129,16 @@ gf_populate_params(ECCurveName name, ECF
 
     if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve))
         goto cleanup;
     params->name = name;
     curveParams = ecCurve_map[params->name];
     CHECK_OK(curveParams);
     params->fieldID.size = curveParams->size;
     params->fieldID.type = field_type;
-    params->pointSize = curveParams->pointSize;
     if (field_type == ec_field_GFp ||
         field_type == ec_field_plain) {
         CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
                                    curveParams->irr));
     } else {
         CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly,
                                    curveParams->irr));
     }
@@ -289,9 +287,25 @@ EC_DecodeParams(const SECItem *encodedPa
         return SECFailure;
     } else {
         *ecparams = params;
         ;
         return SECSuccess;
     }
 }
 
+int
+EC_GetPointSize(const ECParams *params)
+{
+    ECCurveName name = params->name;
+    const ECCurveParams *curveParams;
+
+    if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) ||
+        ((curveParams = ecCurve_map[name]) == NULL)) {
+        /* unknown curve, calculate point size from params. assume standard curves with 2 points 
+         * and a point compression indicator byte */
+        int sizeInBytes = (params->fieldID.size + 7) / 8;
+        return sizeInBytes * 2 + 1;
+    }
+    return curveParams->pointSize;
+}
+
 #endif /* NSS_DISABLE_ECC */
--- a/security/nss/lib/freebl/ldvector.c
+++ b/security/nss/lib/freebl/ldvector.c
@@ -289,19 +289,23 @@ static const struct FREEBLVectorStr vect
       EC_CopyParams,
 
       /* End of Version 3.017 */
 
       ChaCha20Poly1305_InitContext,
       ChaCha20Poly1305_CreateContext,
       ChaCha20Poly1305_DestroyContext,
       ChaCha20Poly1305_Seal,
-      ChaCha20Poly1305_Open
+      ChaCha20Poly1305_Open,
 
       /* End of Version 3.018 */
+
+      EC_GetPointSize
+
+      /* End of Version 3.019 */
     };
 
 const FREEBLVector*
 FREEBL_GetVector(void)
 {
 #ifdef FREEBL_NO_DEPEND
     SECStatus rv;
 #endif
--- a/security/nss/lib/freebl/loader.c
+++ b/security/nss/lib/freebl/loader.c
@@ -2111,8 +2111,16 @@ ChaCha20Poly1305_Open(const ChaCha20Poly
                       const unsigned char *ad, unsigned int adLen)
 {
     if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
         return SECFailure;
     return (vector->p_ChaCha20Poly1305_Open)(
         ctx, output, outputLen, maxOutputLen, input, inputLen,
         nonce, nonceLen, ad, adLen);
 }
+
+int
+EC_GetPointSize(const ECParams *params)
+{
+    if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+        return SECFailure;
+    return (vector->p_EC_GetPointSize)(params);
+}
--- a/security/nss/lib/freebl/loader.h
+++ b/security/nss/lib/freebl/loader.h
@@ -5,17 +5,17 @@
  * 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/. */
 
 #ifndef _LOADER_H_
 #define _LOADER_H_ 1
 
 #include "blapi.h"
 
-#define FREEBL_VERSION 0x0312
+#define FREEBL_VERSION 0x0313
 
 struct FREEBLVectorStr {
 
     unsigned short length;  /* of this struct in bytes */
     unsigned short version; /* of this struct. */
 
     RSAPrivateKey *(*p_RSA_NewKey)(int keySizeInBits,
                                    SECItem *publicExponent);
@@ -727,16 +727,20 @@ struct FREEBLVectorStr {
         const ChaCha20Poly1305Context *ctx, unsigned char *output,
         unsigned int *outputLen, unsigned int maxOutputLen,
         const unsigned char *input, unsigned int inputLen,
         const unsigned char *nonce, unsigned int nonceLen,
         const unsigned char *ad, unsigned int adLen);
 
     /* Version 3.018 came to here */
 
+    int (*p_EC_GetPointSize)(const ECParams *);
+
+    /* Version 3.019 came to here */
+
     /* Add new function pointers at the end of this struct and bump
      * FREEBL_VERSION at the beginning of this file. */
 };
 
 typedef struct FREEBLVectorStr FREEBLVector;
 
 #ifdef FREEBL_LOWHASH
 #include "nsslowhash.h"
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -17,20 +17,20 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION "3.28.1" _NSS_CUSTOMIZED
+#define NSS_VERSION "3.28.3" _NSS_CUSTOMIZED
 #define NSS_VMAJOR 3
 #define NSS_VMINOR 28
-#define NSS_VPATCH 1
+#define NSS_VPATCH 3
 #define NSS_VBUILD 0
 #define NSS_BETA PR_FALSE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -760,22 +760,20 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
                 crv = CKR_OBJECT_HANDLE_INVALID;
                 break;
             }
 
             crv = pk11_Attr2SecItem(arena, ecparams,
                                     &pubKey->u.ec.DEREncodedParams);
             if (crv != CKR_OK)
                 break;
+            pubKey->u.ec.encoding = ECPoint_Undefined;
             crv = pk11_get_Decoded_ECPoint(arena,
                                            &pubKey->u.ec.DEREncodedParams, value,
                                            &pubKey->u.ec.publicValue);
-            if (seckey_SetPointEncoding(arena, pubKey) != SECSuccess) {
-                crv |= CKR_GENERAL_ERROR;
-            }
             break;
         case fortezzaKey:
         case nullKey:
         default:
             crv = CKR_OBJECT_HANDLE_INVALID;
             break;
     }
 
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -2032,27 +2032,62 @@ PK11_PubDerive(SECKEYPrivateKey *privKey
             PORT_SetError(PK11_MapError(crv));
         }
     }
 
     PK11_FreeSymKey(symKey);
     return NULL;
 }
 
+/* Test for curves that are known to use a special encoding.
+ * Extend this function when additional curves are added. */
+static ECPointEncoding
+pk11_ECGetPubkeyEncoding(const SECKEYPublicKey *pubKey)
+{
+    SECItem oid;
+    SECStatus rv;
+    PORTCheapArenaPool tmpArena;
+    ECPointEncoding encoding = ECPoint_Undefined;
+
+    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+
+    /* decode the OID tag */
+    rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid,
+                                SEC_ASN1_GET(SEC_ObjectIDTemplate),
+                                &pubKey->u.ec.DEREncodedParams);
+    if (rv == SECSuccess) {
+        SECOidTag tag = SECOID_FindOIDTag(&oid);
+        switch (tag) {
+            case SEC_OID_CURVE25519:
+                encoding = ECPoint_XOnly;
+                break;
+            case SEC_OID_SECG_EC_SECP256R1:
+            case SEC_OID_SECG_EC_SECP384R1:
+            case SEC_OID_SECG_EC_SECP521R1:
+            default:
+                /* unknown curve, default to uncompressed */
+                encoding = ECPoint_Uncompressed;
+        }
+    }
+    PORT_DestroyCheapArena(&tmpArena);
+    return encoding;
+}
+
 /* Returns the size of the public key, or 0 if there
  * is an error. */
 static CK_ULONG
 pk11_ECPubKeySize(SECKEYPublicKey *pubKey)
 {
     SECItem *publicValue = &pubKey->u.ec.publicValue;
 
-    if (pubKey->u.ec.encoding == ECPoint_XOnly) {
+    ECPointEncoding encoding = pk11_ECGetPubkeyEncoding(pubKey);
+    if (encoding == ECPoint_XOnly) {
         return publicValue->len;
     }
-    if (publicValue->data[0] == 0x04) {
+    if (encoding == ECPoint_Uncompressed) {
         /* key encoded in uncompressed form */
         return ((publicValue->len - 1) / 2);
     }
     /* key encoding not recognized */
     return 0;
 }
 
 static PK11SymKey *
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -1790,17 +1790,17 @@ sftk_GetPubKey(SFTKObject *object, CK_KE
                               &pubKey->u.ec.ecParams) != SECSuccess) {
                 crv = CKR_DOMAIN_PARAMS_INVALID;
                 break;
             }
 
             crv = sftk_Attribute2SSecItem(arena, &pubKey->u.ec.publicValue,
                                           object, CKA_EC_POINT);
             if (crv == CKR_OK) {
-                unsigned int keyLen = pubKey->u.ec.ecParams.pointSize;
+                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. */
 
                 /* Handle the non-DER encoded case.
                  * Some curves are always pressumed to be non-DER.
                  */
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -7215,17 +7215,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
             }
 
             /* Now we are working with a non-NULL private key */
             SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue);
 
             ecPoint.data = mechParams->pPublicData;
             ecPoint.len = mechParams->ulPublicDataLen;
 
-            pubKeyLen = privKey->u.ec.ecParams.pointSize;
+            pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams);
 
             /* if the len is too small, can't be a valid point */
             if (ecPoint.len < pubKeyLen) {
                 goto ec_loser;
             }
             /* if the len is too large, must be an encoded point (length is
              * equal case just falls through */
             if (ecPoint.len > pubKeyLen) {
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -16,16 +16,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION "3.28.1" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.28.3" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR 3
 #define SOFTOKEN_VMINOR 28
-#define SOFTOKEN_VPATCH 1
+#define SOFTOKEN_VPATCH 3
 #define SOFTOKEN_VBUILD 0
 #define SOFTOKEN_BETA PR_FALSE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/ssl3ecc.c
+++ b/security/nss/lib/ssl/ssl3ecc.c
@@ -298,17 +298,17 @@ ssl3_HandleECDHClientKeyExchange(sslSock
     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
 
     clntPubKey.keyType = ecKey;
     clntPubKey.u.ec.DEREncodedParams.len =
         serverKeyPair->pubKey->u.ec.DEREncodedParams.len;
     clntPubKey.u.ec.DEREncodedParams.data =
         serverKeyPair->pubKey->u.ec.DEREncodedParams.data;
-    clntPubKey.u.ec.encoding = serverKeyPair->pubKey->u.ec.encoding;
+    clntPubKey.u.ec.encoding = ECPoint_Undefined;
 
     rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
                                        1, &b, &length);
     if (rv != SECSuccess) {
         PORT_SetError(errCode);
         return SECFailure;
     }
 
@@ -382,21 +382,17 @@ ssl_ImportECDHKeyShare(sslSocket *ss, SE
     peerKey->keyType = ecKey;
     /* Set up the encoded params */
     rv = ssl_NamedGroup2ECParams(peerKey->arena, ecGroup,
                                  &peerKey->u.ec.DEREncodedParams);
     if (rv != SECSuccess) {
         ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
         return SECFailure;
     }
-    if (ecGroup->name == ssl_grp_ec_curve25519) {
-        peerKey->u.ec.encoding = ECPoint_XOnly;
-    } else {
-        peerKey->u.ec.encoding = ECPoint_Uncompressed;
-    }
+    peerKey->u.ec.encoding = ECPoint_Undefined;
 
     /* copy publicValue in peerKey */
     ecPoint.data = b;
     ecPoint.len = length;
 
     rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.ec.publicValue, &ecPoint);
     if (rv != SECSuccess) {
         return SECFailure;
--- a/security/nss/lib/util/eccutil.h
+++ b/security/nss/lib/util/eccutil.h
@@ -1,14 +1,15 @@
 /* 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/. */
 
 #ifndef _FREEBL_H_
 #define _FREEBL_H_
 
-/* point encoding type */
+/* deprecated */
 typedef enum {
     ECPoint_Uncompressed,
-    ECPoint_XOnly
+    ECPoint_XOnly,
+    ECPoint_Undefined
 } ECPointEncoding;
 
 #endif /* _FREEBL_H_ */
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,20 +14,20 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION "3.28.1"
+#define NSSUTIL_VERSION "3.28.3"
 #define NSSUTIL_VMAJOR 3
 #define NSSUTIL_VMINOR 28
-#define NSSUTIL_VPATCH 1
+#define NSSUTIL_VPATCH 3
 #define NSSUTIL_VBUILD 0
 #define NSSUTIL_BETA PR_FALSE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */