File nss-CC-approved_crypto-ECs.patch of Package mozilla-nss.972
# HG changeset patch
# Parent d9a01714b36cd0410dbe6b2d1c3c3bb8fe4b7805
Disable non-approved elliptic curves in FIPS mode - return errors when one of
them is requested and do not offer these curves in SSL/TLS negotiation.
Approved curves for FIPS-140-2 are: NIST P-224, P-256, P-384, P-521.
bsc#924307
diff --git a/lib/freebl/ecdecode.c b/lib/freebl/ecdecode.c
--- a/lib/freebl/ecdecode.c
+++ b/lib/freebl/ecdecode.c
@@ -9,19 +9,27 @@
#endif
#include "blapi.h"
#include "secoid.h"
#include "secitem.h"
#include "secerr.h"
#include "ec.h"
#include "ecl-curve.h"
+#include "fips.h"
#define CHECK_OK(func) if (func == NULL) goto cleanup
#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
+#define DISABLED_IF(x) \
+ do { \
+ if (x) { \
+ rv = SECFailure; \
+ goto cleanup; \
+ } \
+ } while (0)
/*
* Initializes a SECItem from a hexadecimal string
*
* Warning: This function ignores leading 00's, so any leading 00's
* in the hexadecimal string must be optional.
*/
static SECItem *
@@ -197,350 +205,400 @@ EC_FillParams(PLArenaPool *arena, const
printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
#endif
switch (tag) {
/* Binary curves */
case SEC_OID_ANSIX962_EC_C2PNB163V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb163v1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB163V2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb163v2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB163V3:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb163v3 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB176V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb176v1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB191V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb191v1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB191V2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb191v2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB191V3:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb191v3 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB208W1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb208w1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB239V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb239v1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB239V2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb239v2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB239V3:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb239v3 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB272W1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb272w1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB304W1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb304w1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB359V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb359v1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2PNB368W1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2pnb368w1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
params) );
break;
case SEC_OID_ANSIX962_EC_C2TNB431R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for c2tnb431r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT113R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect113r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT113R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect113r2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT131R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect131r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT131R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect131r2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT163K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect163k1
* (the NIST K-163 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT163R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect163r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT163R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect163r2
* (the NIST B-163 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT193R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect193r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT193R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect193r2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT233K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect233k1
* (the NIST K-233 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT233R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect233r1
* (the NIST B-233 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT239K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect239k1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT283K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect283k1
* (the NIST K-283 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT283R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect283r1
* (the NIST B-283 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT409K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect409k1
* (the NIST K-409 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT409R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect409r1
* (the NIST B-409 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT571K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect571k1
* (the NIST K-571 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
params) );
break;
case SEC_OID_SECG_EC_SECT571R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for sect571r1
* (the NIST B-571 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
params) );
break;
/* Prime curves */
case SEC_OID_ANSIX962_EC_PRIME192V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for prime192v1 aka secp192r1
* (the NIST P-192 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
params) );
break;
case SEC_OID_ANSIX962_EC_PRIME192V2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for prime192v2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
params) );
break;
case SEC_OID_ANSIX962_EC_PRIME192V3:
+ DISABLED_IF(FIPS_mode());
/* Populate params for prime192v3 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
params) );
break;
case SEC_OID_ANSIX962_EC_PRIME239V1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for prime239v1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
params) );
break;
case SEC_OID_ANSIX962_EC_PRIME239V2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for prime239v2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
params) );
break;
case SEC_OID_ANSIX962_EC_PRIME239V3:
+ DISABLED_IF(FIPS_mode());
/* Populate params for prime239v3 */
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
params) );
break;
case SEC_OID_ANSIX962_EC_PRIME256V1:
/* Populate params for prime256v1 aka secp256r1
* (the NIST P-256 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP112R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp112r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP112R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp112r2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP128R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp128r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP128R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp128r2 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP160K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp160k1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP160R1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp160r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP160R2:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp160r1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP192K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp192k1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP224K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp224k1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP224R1:
/* Populate params for secp224r1
* (the NIST P-224 curve)
*/
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP256K1:
+ DISABLED_IF(FIPS_mode());
/* Populate params for secp256k1 */
CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
params) );
break;
case SEC_OID_SECG_EC_SECP384R1:
/* Populate params for secp384r1
* (the NIST P-384 curve)
diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c
--- a/lib/ssl/ssl3ecc.c
+++ b/lib/ssl/ssl3ecc.c
@@ -1139,20 +1139,24 @@ ssl3_SendSupportedCurvesXtn(
}
}
return ecListSize;
}
PRUint32
ssl3_GetSupportedECCurveMask(sslSocket *ss)
{
+ PRUint32 mask = SSL3_ALL_SUPPORTED_CURVES_MASK;
if (ssl3_SuiteBOnly(ss)) {
- return SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
+ mask = SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
}
- return SSL3_ALL_SUPPORTED_CURVES_MASK;
+ if (PK11_IsFIPS()) {
+ mask &= SSL3_FIPS_SUPPORTED_CURVES_MASK;
+ }
+ return mask;
}
/* Send our "canned" (precompiled) Supported Point Formats extension,
* which says that we only support uncompressed points.
*/
PRInt32
ssl3_SendSupportedPointFormatsXtn(
sslSocket * ss,
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -141,16 +141,18 @@ typedef enum { SSLAppOpRead = 0,
#define SSL_MAX_CACHED_CERT_LEN 4060
#define NUM_MIXERS 9
/* Mask of the 25 named curves we support. */
#define SSL3_ALL_SUPPORTED_CURVES_MASK 0x3fffffe
/* Mask of only 3 curves, suite B */
#define SSL3_SUITE_B_SUPPORTED_CURVES_MASK 0x3800000
+/* Mask of the curces supported in FIPS: P-224, P-256, P-384, P-521 */
+#define SSL3_FIPS_SUPPORTED_CURVES_MASK 0x3a00000
#ifndef BPB
#define BPB 8 /* Bits Per Byte */
#endif
#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
/* The minimum server key sizes accepted by the clients.
diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
--- a/lib/ssl/sslsock.c
+++ b/lib/ssl/sslsock.c
@@ -12,16 +12,17 @@
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "nspr.h"
#include "private/pprio.h"
#ifndef NO_PKCS11_BYPASS
#include "blapi.h"
#endif
+#include "pk11pub.h"
#include "nss.h"
#define SET_ERROR_CODE /* reminder */
static const sslSocketOps ssl_default_ops = { /* No SSL. */
ssl_DefConnect,
NULL,
ssl_DefBind,
@@ -2979,16 +2980,21 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
ss->pkcs11PinArg = NULL;
ss->ephemeralECDHKeyPair = NULL;
ssl_ChooseOps(ss);
ssl2_InitSocketPolicy(ss);
ssl3_InitSocketPolicy(ss);
PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
+ /* cannot cresate step down keys in fips mode */
+ if (!ss->opt.noStepDown && PK11_IsFIPS()) {
+ ss->opt.noStepDown = PR_TRUE;
+ }
+
if (makeLocks) {
status = ssl_MakeLocks(ss);
if (status != SECSuccess)
goto loser;
}
status = ssl_CreateSecurityInfo(ss);
if (status != SECSuccess)
goto loser;