diff -up openssl-1.1.1c/crypto/ec/ec_curve.c.fips-curves openssl-1.1.1c/crypto/ec/ec_curve.c --- openssl-1.1.1c/crypto/ec/ec_curve.c.fips-curves 2019-11-25 13:18:40.719532357 +0100 +++ openssl-1.1.1c/crypto/ec/ec_curve.c 2019-11-25 13:18:40.765531559 +0100 @@ -13,6 +13,7 @@ #include #include #include +#include #include "internal/nelem.h" typedef struct { @@ -237,6 +238,7 @@ static const struct { typedef struct _ec_list_element_st { int nid; + int fips_allowed; const EC_CURVE_DATA *data; const EC_METHOD *(*meth) (void); const char *comment; @@ -246,23 +248,23 @@ static const ec_list_element curve_list[ /* prime field curves */ /* secg curves */ #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, + {NID_secp224r1, 1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field"}, #else - {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, + {NID_secp224r1, 1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field"}, #endif - {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, + {NID_secp256k1, 0, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field"}, /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ - {NID_secp384r1, &_EC_NIST_PRIME_384.h, + {NID_secp384r1, 1, &_EC_NIST_PRIME_384.h, # if defined(S390X_EC_ASM) EC_GFp_s390x_nistp384_method, # else 0, # endif "NIST/SECG curve over a 384 bit prime field"}, - {NID_secp521r1, &_EC_NIST_PRIME_521.h, + {NID_secp521r1, 1, &_EC_NIST_PRIME_521.h, # if defined(S390X_EC_ASM) EC_GFp_s390x_nistp521_method, # elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) @@ -272,7 +274,7 @@ static const ec_list_element curve_list[ # endif "NIST/SECG curve over a 521 bit prime field"}, /* X9.62 curves */ - {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, + {NID_X9_62_prime256v1, 1, &_EC_X9_62_PRIME_256V1.h, #if defined(ECP_NISTZ256_ASM) EC_GFp_nistz256_method, # elif defined(S390X_EC_ASM) @@ -404,6 +406,10 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int for (i = 0; i < curve_list_length; i++) if (curve_list[i].nid == nid) { + if (!curve_list[i].fips_allowed && FIPS_mode()) { + ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_NOT_A_NIST_PRIME); + return NULL; + } ret = ec_group_new_from_data(curve_list[i]); break; } @@ -418,19 +424,31 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) { - size_t i, min; + size_t i, j, num; + int fips_mode = FIPS_mode(); - if (r == NULL || nitems == 0) - return curve_list_length; + num = curve_list_length; + if (fips_mode) + for (i = 0; i < curve_list_length; i++) { + if (!curve_list[i].fips_allowed) + --num; + } - min = nitems < curve_list_length ? nitems : curve_list_length; + if (r == NULL || nitems == 0) { + return num; + } - for (i = 0; i < min; i++) { - r[i].nid = curve_list[i].nid; - r[i].comment = curve_list[i].comment; + for (i = 0, j = 0; i < curve_list_length; i++) { + if (j >= nitems) + break; + if (!fips_mode || curve_list[i].fips_allowed) { + r[j].nid = curve_list[i].nid; + r[j].comment = curve_list[i].comment; + ++j; + } } - return curve_list_length; + return num; } /* Functions to translate between common NIST curve names and NIDs */ diff -up openssl-1.1.1c/ssl/t1_lib.c.fips-curves openssl-1.1.1c/ssl/t1_lib.c --- openssl-1.1.1c/ssl/t1_lib.c.fips-curves 2019-11-25 13:18:40.658533416 +0100 +++ openssl-1.1.1c/ssl/t1_lib.c 2019-11-26 17:57:15.014742428 +0100 @@ -20,6 +20,7 @@ #include "internal/nelem.h" #include "ssl_locl.h" #include +#include SSL3_ENC_METHOD const TLSv1_enc_data = { tls1_enc, @@ -676,6 +677,36 @@ static const uint16_t tls12_sigalgs[] = #endif }; +static const uint16_t tls12_fips_sigalgs[] = { +#ifndef OPENSSL_NO_EC + TLSEXT_SIGALG_ecdsa_secp256r1_sha256, + TLSEXT_SIGALG_ecdsa_secp384r1_sha384, + TLSEXT_SIGALG_ecdsa_secp521r1_sha512, +#endif + + TLSEXT_SIGALG_rsa_pss_pss_sha256, + TLSEXT_SIGALG_rsa_pss_pss_sha384, + TLSEXT_SIGALG_rsa_pss_pss_sha512, + TLSEXT_SIGALG_rsa_pss_rsae_sha256, + TLSEXT_SIGALG_rsa_pss_rsae_sha384, + TLSEXT_SIGALG_rsa_pss_rsae_sha512, + + TLSEXT_SIGALG_rsa_pkcs1_sha256, + TLSEXT_SIGALG_rsa_pkcs1_sha384, + TLSEXT_SIGALG_rsa_pkcs1_sha512, + +#ifndef OPENSSL_NO_EC + TLSEXT_SIGALG_ecdsa_sha224, +#endif + TLSEXT_SIGALG_rsa_pkcs1_sha224, +#ifndef OPENSSL_NO_DSA + TLSEXT_SIGALG_dsa_sha224, + TLSEXT_SIGALG_dsa_sha256, + TLSEXT_SIGALG_dsa_sha384, + TLSEXT_SIGALG_dsa_sha512, +#endif +}; + #ifndef OPENSSL_NO_EC static const uint16_t suiteb_sigalgs[] = { TLSEXT_SIGALG_ecdsa_secp256r1_sha256, @@ -890,8 +921,11 @@ static const SIGALG_LOOKUP *tls1_get_leg if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg)) return NULL; if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]); + const SIGALG_LOOKUP *lu; + if (FIPS_mode()) /* We do not allow SHA1 signatures in FIPS mode */ + return NULL; + lu = tls1_lookup_sigalg(tls_default_sigalg[idx]); if (!tls1_lookup_md(lu, NULL)) return NULL; return lu; @@ -945,6 +979,9 @@ size_t tls12_get_psigalgs(SSL *s, int se } else if (s->cert->conf_sigalgs) { *psigs = s->cert->conf_sigalgs; return s->cert->conf_sigalgslen; + } else if (FIPS_mode()) { + *psigs = tls12_fips_sigalgs; + return OSSL_NELEM(tls12_fips_sigalgs); } else { *psigs = tls12_sigalgs; return OSSL_NELEM(tls12_sigalgs); @@ -964,6 +1001,9 @@ int tls_check_sigalg_curve(const SSL *s, if (s->cert->conf_sigalgs) { sigs = s->cert->conf_sigalgs; siglen = s->cert->conf_sigalgslen; + } else if (FIPS_mode()) { + sigs = tls12_fips_sigalgs; + siglen = OSSL_NELEM(tls12_fips_sigalgs); } else { sigs = tls12_sigalgs; siglen = OSSL_NELEM(tls12_sigalgs); @@ -1582,6 +1622,8 @@ static int tls12_sigalg_allowed(SSL *s, if (lu->sig == NID_id_GostR3410_2012_256 || lu->sig == NID_id_GostR3410_2012_512 || lu->sig == NID_id_GostR3410_2001) { + if (FIPS_mode()) + return 0; /* We never allow GOST sig algs on the server with TLSv1.3 */ if (s->server && SSL_IS_TLS13(s)) return 0; @@ -2720,6 +2762,13 @@ int tls_choose_sigalg(SSL *s, int fatale const uint16_t *sent_sigs; size_t sent_sigslen; + if (fatalerrs && FIPS_mode()) { + /* There are no suitable legacy algorithms in FIPS mode */ + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_F_TLS_CHOOSE_SIGALG, + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); + return 0; + } if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1;