diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2021-04-15 18:25:17 +1000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-04-26 19:52:11 +0200 |
commit | f1ffaaeece5efb7d2f4859a59e3164edf9b4b769 (patch) | |
tree | a125dfda9f44ef0702f8bae025ccec829eb33652 /crypto/evp | |
parent | 6c9bc258d2e9e7b500236a1c696da1f384f0b907 (diff) |
Fixes related to separation of DH and DHX types
Fix dh_rfc5114 option in genpkey.
Fixes #14145
Fixes #13956
Fixes #13952
Fixes #13871
Fixes #14054
Fixes #14444
Updated documentation for app to indicate what options are available for
DH and DHX keys.
DH and DHX now have different keymanager gen_set_params() methods.
Added CHANGES entry to indicate the breaking change.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14883)
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/ctrl_params_translate.c | 104 | ||||
-rw-r--r-- | crypto/evp/dh_support.c | 29 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 33 |
3 files changed, 112 insertions, 54 deletions
diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c index 8f4ffd3bc4..f48e723c33 100644 --- a/crypto/evp/ctrl_params_translate.c +++ b/crypto/evp/ctrl_params_translate.c @@ -977,7 +977,7 @@ static int fix_oid(enum state state, return ret; } -/* EVP_PKEY_CTRL_DH_NID, ...??? */ +/* EVP_PKEY_CTRL_DH_NID */ static int fix_dh_nid(enum state state, const struct translation_st *translation, struct translation_ctx_st *ctx) @@ -987,7 +987,7 @@ static int fix_dh_nid(enum state state, if ((ret = default_check(state, translation, ctx)) <= 0) return ret; - /* This is currently only settable */ + /* This is only settable */ if (ctx->action_type != SET) return 0; @@ -997,16 +997,30 @@ static int fix_dh_nid(enum state state, ctx->p1 = 0; } - if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return default_fixup_args(state, translation, ctx); +} + +/* EVP_PKEY_CTRL_DH_RFC5114 */ +static int fix_dh_nid5114(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) return ret; - if (state == PRE_PARAMS_TO_CTRL) { - ctx->p1 = - ossl_ffc_named_group_get_uid(ossl_ffc_name_to_dh_named_group(ctx->p2)); - ctx->p2 = NULL; + /* This is only settable */ + if (ctx->action_type != SET) + return 0; + + if (state == PRE_CTRL_STR_TO_PARAMS) { + ctx->p2 = (char *)ossl_ffc_named_group_get_name + (ossl_ffc_uid_to_dh_named_group(atoi(ctx->p2))); + ctx->p1 = 0; } - return ret; + return default_fixup_args(state, translation, ctx); } /* EVP_PKEY_CTRL_DH_PARAMGEN_TYPE */ @@ -1019,24 +1033,16 @@ static int fix_dh_paramgen_type(enum state state, if ((ret = default_check(state, translation, ctx)) <= 0) return ret; - /* This is currently only settable */ + /* This is only settable */ if (ctx->action_type != SET) return 0; - if (state == PRE_CTRL_TO_PARAMS) { - ctx->p2 = (char *)ossl_dh_gen_type_id2name(ctx->p1); - ctx->p1 = 0; - } - - if ((ret = default_fixup_args(state, translation, ctx)) <= 0) - return ret; - - if (state == PRE_PARAMS_TO_CTRL) { - ctx->p1 = ossl_dh_gen_type_name2id(ctx->p2); - ctx->p2 = NULL; + if (state == PRE_CTRL_STR_TO_PARAMS) { + ctx->p2 = (char *)ossl_dh_gen_type_id2name(atoi(ctx->p2)); + ctx->p1 = strlen(ctx->p2); } - return ret; + return default_fixup_args(state, translation, ctx); } /* EVP_PKEY_CTRL_EC_PARAM_ENC */ @@ -1927,35 +1933,47 @@ static const struct translation_st evp_pkey_ctx_translations[] = { EVP_PKEY_CTRL_GET_DH_KDF_OID, NULL, NULL, OSSL_KDF_PARAM_CEK_ALG, OSSL_PARAM_UTF8_STRING, fix_oid }, - { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_DH_PAD, "dh_pad", NULL, - OSSL_EXCHANGE_PARAM_PAD, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + /* DHX Keygen Parameters that are shared with DH */ + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL, + OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, "dh_paramgen_prime_len", NULL, + OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_NID, "dh_param", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, NULL }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid5114 }, + /* DH Keygen Parameters that are shared with DHX */ + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL, + OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type }, + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, "dh_paramgen_prime_len", NULL, + OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_DH_NID, "dh_param", NULL, OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid }, - { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, NULL, NULL, - OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, - { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, "dh_paramgen_subprime_len", NULL, - OSSL_PKEY_PARAM_FFC_QBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid5114 }, + + /* DH specific Keygen Parameters */ { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, "dh_paramgen_generator", NULL, OSSL_PKEY_PARAM_DH_GENERATOR, OSSL_PARAM_INTEGER, NULL }, - { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL, - OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type }, - /* - * This is know to be incorrect, will be fixed and enabled when the - * underlying code is corrected. - * Until then, we simply don't support it here. - */ -#if 0 - { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL, - OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_INTEGER, NULL }, -#endif + + /* DHX specific Keygen Parameters */ + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, "dh_paramgen_subprime_len", NULL, + OSSL_PKEY_PARAM_FFC_QBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_PAD, "dh_pad", NULL, + OSSL_EXCHANGE_PARAM_PAD, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, /*- * DSA diff --git a/crypto/evp/dh_support.c b/crypto/evp/dh_support.c index 7e0256bd00..87296ffbee 100644 --- a/crypto/evp/dh_support.c +++ b/crypto/evp/dh_support.c @@ -15,14 +15,25 @@ typedef struct dh_name2id_st{ const char *name; int id; + int type; } DH_GENTYPE_NAME2ID; -static const DH_GENTYPE_NAME2ID dhtype2id[]= +/* Indicates that the paramgen_type can be used for either DH or DHX */ +#define TYPE_ANY -1 +#ifndef OPENSSL_NO_DH +# define TYPE_DH DH_FLAG_TYPE_DH +# define TYPE_DHX DH_FLAG_TYPE_DHX +#else +# define TYPE_DH 0 +# define TYPE_DHX 0 +#endif + +static const DH_GENTYPE_NAME2ID dhtype2id[] = { - { "fips186_4", DH_PARAMGEN_TYPE_FIPS_186_4 }, - { "fips186_2", DH_PARAMGEN_TYPE_FIPS_186_2 }, - { "group", DH_PARAMGEN_TYPE_GROUP }, - { "generator", DH_PARAMGEN_TYPE_GENERATOR } + { "group", DH_PARAMGEN_TYPE_GROUP, TYPE_ANY }, + { "generator", DH_PARAMGEN_TYPE_GENERATOR, TYPE_DH }, + { "fips186_4", DH_PARAMGEN_TYPE_FIPS_186_4, TYPE_DHX }, + { "fips186_2", DH_PARAMGEN_TYPE_FIPS_186_2, TYPE_DHX }, }; const char *ossl_dh_gen_type_id2name(int id) @@ -36,13 +47,17 @@ const char *ossl_dh_gen_type_id2name(int id) return NULL; } -int ossl_dh_gen_type_name2id(const char *name) +#ifndef OPENSSL_NO_DH +int ossl_dh_gen_type_name2id(const char *name, int type) { size_t i; for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { - if (strcmp(dhtype2id[i].name, name) == 0) + if ((dhtype2id[i].type == TYPE_ANY + || type == dhtype2id[i].type) + && strcmp(dhtype2id[i].name, name) == 0) return dhtype2id[i].id; } return -1; } +#endif diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index daa0f617d8..3af7e17bee 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -890,13 +890,38 @@ IMPLEMENT_ECX_VARIANT(ED448) # if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0) -int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey) { - int type = DH_get0_q(key) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX; - int ret = EVP_PKEY_assign(pkey, type, key); + int ret, type; + + /* + * ossl_dh_is_named_safe_prime_group() returns 1 for named safe prime groups + * related to ffdhe and modp (which cache q = (p - 1) / 2), + * and returns 0 for all other dh parameter generation types including + * RFC5114 named groups. + * + * The EVP_PKEY_DH type is used for dh parameter generation types: + * - named safe prime groups related to ffdhe and modp + * - safe prime generator + * + * The type EVP_PKEY_DHX is used for dh parameter generation types + * - fips186-4 and fips186-2 + * - rfc5114 named groups. + * + * The EVP_PKEY_DH type is used to save PKCS#3 data than can be stored + * without a q value. + * The EVP_PKEY_DHX type is used to save X9.42 data that requires the + * q value to be stored. + */ + if (ossl_dh_is_named_safe_prime_group(dhkey)) + type = EVP_PKEY_DH; + else + type = DH_get0_q(dhkey) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX; + + ret = EVP_PKEY_assign(pkey, type, dhkey); if (ret) - DH_up_ref(key); + DH_up_ref(dhkey); return ret; } |