diff --git a/crypto/ec/ec_check.c b/crypto/ec/ec_check.c index 097d7e1cc5..315b9fd4df 100644 --- a/crypto/ec/ec_check.c +++ b/crypto/ec/ec_check.c @@ -22,6 +22,13 @@ int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only) int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) { +#ifdef FIPS_MODE + /* + * ECC domain parameter validation. + * See SP800-56A R3 5.5.2 "Assurances of Domain-Parameter Validity" Part 1b. + */ + return EC_GROUP_check_named_curve(group, 1) >= 0 ? 1 : 0; +#else int ret = 0; const BIGNUM *order; BN_CTX *new_ctx = NULL; @@ -84,4 +91,5 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) BN_CTX_free(new_ctx); EC_POINT_free(point); return ret; +#endif /* FIPS_MODE */ } diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 1ea85946d6..8b44c251ba 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -2800,6 +2800,70 @@ typedef struct _ec_list_element_st { const char *comment; } ec_list_element; +#ifdef FIPS_MODE +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, + "NIST/SECG curve over a 224 bit prime field"}, +# else + {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, + "NIST/SECG curve over a 224 bit prime field"}, +# endif + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + "NIST/SECG curve over a 384 bit prime field"}, + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, + "NIST/SECG curve over a 521 bit prime field"}, +# else + {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, + "NIST/SECG curve over a 521 bit prime field"}, +# endif + + /* X9.62 curves */ + {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, + "NIST/X9.62/SECG curve over a 192 bit prime field"}, + {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, +# if defined(ECP_NISTZ256_ASM) + EC_GFp_nistz256_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp256_method, +# else + 0, +# endif + "X9.62/SECG curve over a 256 bit prime field"}, + +# ifndef OPENSSL_NO_EC2M + /* characteristic two field curves */ + /* NIST/SECG curves */ + {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, + "NIST/SECG/WTLS curve over a 163 bit binary field"}, + {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, + "NIST/SECG curve over a 163 bit binary field"}, + {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, + {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, +# endif +}; + +#else + static const ec_list_element curve_list[] = { /* prime field curves */ /* secg curves */ @@ -2822,25 +2886,25 @@ static const ec_list_element curve_list[] = { "SECG curve over a 192 bit prime field"}, {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field"}, -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field"}, -#else +# else {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field"}, -#endif +# endif {NID_secp256k1, &_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, 0, "NIST/SECG curve over a 384 bit prime field"}, -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field"}, -#else +# else {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field"}, -#endif +# endif /* X9.62 curves */ {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field"}, @@ -2855,15 +2919,15 @@ static const ec_list_element curve_list[] = { {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field"}, {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, -#if defined(ECP_NISTZ256_ASM) +# if defined(ECP_NISTZ256_ASM) EC_GFp_nistz256_method, -#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) EC_GFp_nistp256_method, -#else +# else 0, -#endif +# endif "X9.62/SECG curve over a 256 bit prime field"}, -#ifndef OPENSSL_NO_EC2M +# ifndef OPENSSL_NO_EC2M /* characteristic two field curves */ /* NIST/SECG curves */ {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, @@ -2947,7 +3011,7 @@ static const ec_list_element curve_list[] = { "SECG curve over a 113 bit binary field"}, {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"}, -#endif +# endif {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"}, {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, @@ -2956,15 +3020,15 @@ static const ec_list_element curve_list[] = { "WTLS curve over a 112 bit prime field"}, {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field"}, -#ifndef OPENSSL_NO_EC2M +# ifndef OPENSSL_NO_EC2M {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"}, {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"}, -#endif +# endif {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curve over a 224 bit prime field"}, -#ifndef OPENSSL_NO_EC2M +# ifndef OPENSSL_NO_EC2M /* IPSec curves */ {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" @@ -2972,7 +3036,7 @@ static const ec_list_element curve_list[] = { {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, -#endif +# endif /* brainpool curves */ {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, "RFC 5639 curve over a 160 bit prime field"}, @@ -3002,11 +3066,12 @@ static const ec_list_element curve_list[] = { "RFC 5639 curve over a 512 bit prime field"}, {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, "RFC 5639 curve over a 512 bit prime field"}, -#ifndef OPENSSL_NO_SM2 +# ifndef OPENSSL_NO_SM2 {NID_sm2, &_EC_sm2p256v1.h, 0, "SM2 curve over a 256 bit prime field"}, -#endif +# endif }; +#endif /* FIPS_MODE */ #define curve_list_length OSSL_NELEM(curve_list) @@ -3125,6 +3190,15 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) if (nid <= 0) return NULL; +#ifdef FIPS_MODE + /* + * Only use approved NIST curves in FIPS. + * NOTE: "B-163", "K-163" & "P-192" can only be used for legacy use + * (i.e- ECDSA signature verification). + */ + if (EC_curve_nid2nist(nid) == NULL) + return NULL; +#endif /* FIPS_MODE */ for (i = 0; i < curve_list_length; i++) if (curve_list[i].nid == nid) { ret = ec_group_new_from_data(curve_list[i]); diff --git a/test/ecdsatest.c b/test/ecdsatest.c index 761832ff81..a62efad1cf 100644 --- a/test/ecdsatest.c +++ b/test/ecdsatest.c @@ -118,6 +118,11 @@ static int x9_62_tests(int n) TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid)); +#ifdef FIPS_MODE + if (EC_curve_nid2nist(nid) == NULL) + return TEST_skip("skip non approved curves"); +#endif /* FIPS_MODE */ + if (!TEST_ptr(mctx = EVP_MD_CTX_new()) /* get the message digest */ || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len)) diff --git a/test/ectest.c b/test/ectest.c index 3f7747e5e7..50f8c63f0a 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -1820,7 +1820,7 @@ static int parameter_test(void) unsigned char *buf = NULL; int r = 0, len; - if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1)) + if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp224r1)) || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL)) || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters)) || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0)) diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 5bf4a8c1f3..48376a7951 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -599,7 +599,7 @@ static int test_EVP_PKCS82PKEY(void) } #endif -#ifndef OPENSSL_NO_SM2 +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODE) static int test_EVP_SM2_verify(void) { @@ -1238,7 +1238,7 @@ int setup_tests(void) #ifndef OPENSSL_NO_EC ADD_TEST(test_EVP_PKCS82PKEY); #endif -#ifndef OPENSSL_NO_SM2 +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODE) ADD_TEST(test_EVP_SM2); ADD_TEST(test_EVP_SM2_verify); #endif diff --git a/test/evp_pkey_dparams_test.c b/test/evp_pkey_dparams_test.c index e11d225b59..f1d528eb27 100644 --- a/test/evp_pkey_dparams_test.c +++ b/test/evp_pkey_dparams_test.c @@ -85,7 +85,7 @@ static const unsigned char dsaparam_bin[] = { #ifndef OPENSSL_NO_EC static const unsigned char ecparam_bin[] = { -0x06,0x05,0x2b,0x81,0x04,0x00,0x0a +0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07 }; #endif diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t index 5dbed9835c..83804d69ad 100644 --- a/test/recipes/20-test_pkeyutl.t +++ b/test/recipes/20-test_pkeyutl.t @@ -10,7 +10,7 @@ use strict; use warnings; use File::Spec; -use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips/; use OpenSSL::Test::Utils; setup("test_pkeyutl"); @@ -24,13 +24,13 @@ SKIP: { if disabled("ec") || disabled("sm2") || disabled("sm3"); # SM2 - ok(run(app(([ 'openssl', 'pkeyutl', '-sign', + ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-sign', '-in', srctop_file('test', 'certs', 'sm2.pem'), '-inkey', srctop_file('test', 'certs', 'sm2.key'), '-out', 'signature.dat', '-rawin', '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))), "Sign a piece of data using SM2"); - ok(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', + ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', '-in', srctop_file('test', 'certs', 'sm2.pem'), '-inkey', srctop_file('test', 'certs', 'sm2.pem'), '-sigfile', 'signature.dat', '-rawin', diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t index 96bfd03e2c..915c902b15 100644 --- a/test/recipes/25-test_verify.t +++ b/test/recipes/25-test_verify.t @@ -11,7 +11,7 @@ use strict; use warnings; use File::Spec::Functions qw/canonpath/; -use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips/; use OpenSSL::Test::Utils; setup("test_verify"); @@ -379,9 +379,9 @@ SKIP: { if disabled("sm2"); # Test '-sm2-id' and '-sm2-hex-id' option - ok(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-id", "1234567812345678"), + ok_nofips(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-id", "1234567812345678"), "SM2 ID test"); - ok(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-hex-id", + ok_nofips(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-hex-id", "31323334353637383132333435363738"), "SM2 hex ID test"); }