diff options
author | slontis <shane.lontis@oracle.com> | 2024-07-26 10:23:57 +1000 |
---|---|---|
committer | Neil Horman <nhorman@openssl.org> | 2024-08-15 15:21:14 -0400 |
commit | e3a453c83810e6f7a128d2f472b8c71b7eceedb6 (patch) | |
tree | 80caedf086da9b745174b812532332ff3f8076db | |
parent | 8781087a69934cf45e201ac425d593b0e12a1538 (diff) |
Restrict FIPS EC Keygen to only allow curves with a security strength
>=112 bits
Add a FIPS indicator to EC keygen
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/25008)
-rw-r--r-- | doc/man7/EVP_PKEY-EC.pod | 24 | ||||
-rw-r--r-- | doc/man7/provider-keymgmt.pod | 12 | ||||
-rw-r--r-- | providers/implementations/keymgmt/ec_kmgmt.c | 48 |
3 files changed, 81 insertions, 3 deletions
diff --git a/doc/man7/EVP_PKEY-EC.pod b/doc/man7/EVP_PKEY-EC.pod index 318f2cc8b2..e098348b12 100644 --- a/doc/man7/EVP_PKEY-EC.pod +++ b/doc/man7/EVP_PKEY-EC.pod @@ -19,7 +19,7 @@ Explicit parameters are supported for backwards compatibility reasons, but they are not compliant with multiple standards (including RFC5915) which only allow named curves. -The following KeyGen/Gettable/Import/Export types are available for the +The following Key generation/Gettable/Import/Export types are available for the built-in EC algorithm: =over 4 @@ -187,6 +187,28 @@ that m > k3 > k2 > k1 > 0 =back +The following key generation settable parameter is also available for the +OpenSSL FIPS provider's EC algorithm: + +=over 4 + +=item "key-check" (B<OSSL_PKEY_PARAM_FIPS_KEY_CHECK>) <integer> + +See L<provider-keymgmt(7)/Common Information Parameters> for further information. + +=back + +The following key generation Gettable parameter is available for the OpenSSL +FIPS provider's EC algorithm: + +=over 4 + +=item "fips-indicator" (B<OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR>) <integer> + +See L<provider-keymgmt(7)/Common Information Parameters> for further information. + +=back + =head2 EC key validation For EC keys, L<EVP_PKEY_param_check(3)> behaves in the following way: diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod index 59f023bc78..0f4e0edd31 100644 --- a/doc/man7/provider-keymgmt.pod +++ b/doc/man7/provider-keymgmt.pod @@ -436,6 +436,16 @@ its argument I<mdname>. This signifies that no digest has to be specified with the corresponding signature operation, but may be specified as an option. +=item "key-check" (B<OSSL_PKEY_PARAM_FIPS_KEY_CHECK>) <integer> + +If required this parameter should be set using OSSL_FUNC_keymgmt_gen_set_params() +or OSSL_FUNC_keymgmt_gen_init(). +The default value of 1 causes an error during the init if the key is not FIPS +approved (e.g. The key has a security strength of less than 112 bits). Setting +this to 0 will ignore the error and set the approved "fips-indicator" to 0. +This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if +set to 0. + =item "sign-check" (B<OSSL_PKEY_PARAM_FIPS_SIGN_CHECK>) <int> If required this parameter should be set before the OSSL_FUNC_keymgmt_gen() @@ -450,7 +460,7 @@ set to 0. A getter that returns 1 if the operation is FIPS approved, or 0 otherwise. This may be used after calling OSSL_FUNC_keymgmt_gen() function. It may -return 0 if either the "digest-check", "key-check", or "sign-check" are set to 0. +return 0 if either the "key-check", or "sign-check" are set to 0. This option is used by the OpenSSL FIPS provider. =back diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index 9390935394..8539b05a62 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -25,6 +25,8 @@ #include "prov/implementations.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" +#include "prov/securitycheck.h" +#include "prov/fipsindicator.h" #include "internal/param_build_set.h" #ifndef FIPS_MODULE @@ -38,6 +40,8 @@ static OSSL_FUNC_keymgmt_gen_init_fn ec_gen_init; static OSSL_FUNC_keymgmt_gen_set_template_fn ec_gen_set_template; static OSSL_FUNC_keymgmt_gen_set_params_fn ec_gen_set_params; static OSSL_FUNC_keymgmt_gen_settable_params_fn ec_gen_settable_params; +static OSSL_FUNC_keymgmt_gen_get_params_fn ec_gen_get_params; +static OSSL_FUNC_keymgmt_gen_gettable_params_fn ec_gen_gettable_params; static OSSL_FUNC_keymgmt_gen_fn ec_gen; static OSSL_FUNC_keymgmt_gen_cleanup_fn ec_gen_cleanup; static OSSL_FUNC_keymgmt_load_fn ec_load; @@ -991,6 +995,7 @@ struct ec_gen_ctx { EC_GROUP *gen_group; unsigned char *dhkem_ikm; size_t dhkem_ikmlen; + OSSL_FIPS_IND_DECLARE }; static void *ec_gen_init(void *provctx, int selection, @@ -1006,6 +1011,7 @@ static void *ec_gen_init(void *provctx, int selection, gctx->libctx = libctx; gctx->selection = selection; gctx->ecdh_mode = 0; + OSSL_FIPS_IND_INIT(gctx) if (!ec_gen_set_params(gctx, params)) { OPENSSL_free(gctx); gctx = NULL; @@ -1105,6 +1111,10 @@ static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) const OSSL_PARAM *p; EC_GROUP *group = NULL; + if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params, + OSSL_PKEY_PARAM_FIPS_KEY_CHECK)) + goto err; + COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode); COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name); @@ -1226,12 +1236,35 @@ static const OSSL_PARAM *ec_gen_settable_params(ossl_unused void *genctx, OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0), + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_KEY_CHECK) OSSL_PARAM_END }; - return settable; } +static const OSSL_PARAM *ec_gen_gettable_params(ossl_unused void *genctx, + ossl_unused void *provctx) +{ + static const OSSL_PARAM known_ec_gen_gettable_ctx_params[] = { + OSSL_FIPS_IND_GETTABLE_CTX_PARAM() + OSSL_PARAM_END + }; + return known_ec_gen_gettable_ctx_params; +} + +static int ec_gen_get_params(void *genctx, OSSL_PARAM *params) +{ + struct ec_gen_ctx *gctx = genctx; + + if (gctx == NULL) + return 0; + + if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params)) + return 0; + + return 1; +} + static int ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group) { if (group == NULL) { @@ -1274,6 +1307,16 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) EC_GROUP_set_point_conversion_form(gctx->gen_group, format); } } +#ifdef FIPS_MODULE + if (!ossl_ec_check_security_strength(gctx->gen_group, 1)) { + if (!OSSL_FIPS_IND_ON_UNAPPROVED(gctx, OSSL_FIPS_IND_SETTABLE0, + gctx->libctx, "EC KeyGen", "key size", + ossl_securitycheck_enabled)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + goto err; + } + } +#endif /* We must always assign a group, no matter what */ ret = ec_gen_assign_group(ec, gctx->gen_group); @@ -1426,6 +1469,9 @@ const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))ec_gen_settable_params }, + { OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))ec_gen_get_params }, + { OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS, + (void (*)(void))ec_gen_gettable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ec_load }, |