diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-10-15 13:41:59 +1000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-01-26 15:22:14 +0100 |
commit | 5b5eea4b60b682009d2b15587c9ceeae5e9c73f8 (patch) | |
tree | 4a3261cb27a582770270a07b40ecf05ecb71c89a /crypto/ec | |
parent | 98dbf2c1c8143c0cc6dd05be7950d90bc6792064 (diff) |
Deprecate EC_KEY + Update ec apps to use EVP_PKEY
Co-author: Richard Levitte <levitte@openssl.org>
Co-author: Tomas Mraz <tmraz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13139)
Diffstat (limited to 'crypto/ec')
-rw-r--r-- | crypto/ec/ec_backend.c | 219 | ||||
-rw-r--r-- | crypto/ec/ec_key.c | 2 | ||||
-rw-r--r-- | crypto/ec/ec_lib.c | 86 | ||||
-rw-r--r-- | crypto/ec/eck_prn.c | 8 |
4 files changed, 270 insertions, 45 deletions
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index f950657173..06acb7d607 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Low level APIs related to EC_KEY are deprecated for public use, + * but still ok for internal use. + */ +#include "internal/deprecated.h" + #include <openssl/core_names.h> #include <openssl/objects.h> #include <openssl/params.h> @@ -23,6 +29,18 @@ static const OSSL_ITEM encoding_nameid_map[] = { { OPENSSL_EC_NAMED_CURVE, OSSL_PKEY_EC_ENCODING_GROUP }, }; +static const OSSL_ITEM check_group_type_nameid_map[] = { + { 0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT }, + { EC_FLAG_CHECK_NAMED_GROUP, OSSL_PKEY_EC_GROUP_CHECK_NAMED }, + { EC_FLAG_CHECK_NAMED_GROUP_NIST, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST }, +}; + +static const OSSL_ITEM format_nameid_map[] = { + { (int)POINT_CONVERSION_UNCOMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED }, + { (int)POINT_CONVERSION_COMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED }, + { (int)POINT_CONVERSION_HYBRID, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID }, +}; + int ec_encoding_name2id(const char *name) { size_t i, sz; @@ -49,13 +67,95 @@ static char *ec_param_encoding_id2name(int id) return NULL; } +char *ec_check_group_type_id2name(int id) +{ + size_t i, sz; + + for (i = 0, sz = OSSL_NELEM(check_group_type_nameid_map); i < sz; i++) { + if (id == (int)check_group_type_nameid_map[i].id) + return check_group_type_nameid_map[i].ptr; + } + return NULL; +} + +static int ec_check_group_type_name2id(const char *name) +{ + size_t i, sz; + + /* Return the default value if there is no name */ + if (name == NULL) + return 0; + + for (i = 0, sz = OSSL_NELEM(check_group_type_nameid_map); i < sz; i++) { + if (strcasecmp(name, check_group_type_nameid_map[i].ptr) == 0) + return check_group_type_nameid_map[i].id; + } + return -1; +} + +int ec_set_check_group_type_from_name(EC_KEY *ec, const char *name) +{ + int flags = ec_check_group_type_name2id(name); + + if (flags == -1) + return 0; + EC_KEY_clear_flags(ec, EC_FLAG_CHECK_NAMED_GROUP_MASK); + EC_KEY_set_flags(ec, flags); + return 1; +} + +static int ec_set_check_group_type_from_param(EC_KEY *ec, const OSSL_PARAM *p) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) + return ec_set_check_group_type_from_name(ec, name); + return 0; +} + +int ec_pt_format_name2id(const char *name) +{ + size_t i, sz; + + /* Return the default value if there is no name */ + if (name == NULL) + return (int)POINT_CONVERSION_UNCOMPRESSED; + + for (i = 0, sz = OSSL_NELEM(format_nameid_map); i < sz; i++) { + if (strcasecmp(name, format_nameid_map[i].ptr) == 0) + return format_nameid_map[i].id; + } + return -1; +} + +char *ec_pt_format_id2name(int id) +{ + size_t i, sz; + + for (i = 0, sz = OSSL_NELEM(format_nameid_map); i < sz; i++) { + if (id == (int)format_nameid_map[i].id) + return format_nameid_map[i].ptr; + } + return NULL; +} + int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, OSSL_PARAM params[], OSSL_LIB_CTX *libctx, const char *propq, BN_CTX *bnctx, unsigned char **genbuf) { int ret = 0, curve_nid, encoding_flag; - const char *field_type, *encoding_name; + const char *field_type, *encoding_name, *pt_form_name; const BIGNUM *cofactor, *order; BIGNUM *p = NULL, *a = NULL, *b = NULL; point_conversion_form_t genform; @@ -68,6 +168,15 @@ int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, return 0; } + genform = EC_GROUP_get_point_conversion_form(group); + pt_form_name = ec_pt_format_id2name(genform); + if (pt_form_name == NULL + || !ossl_param_build_set_utf8_string( + tmpl, params, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, pt_form_name)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE; encoding_name = ec_param_encoding_id2name(encoding_flag); if (encoding_name == NULL @@ -115,7 +224,6 @@ int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); goto err; } - genform = EC_GROUP_get_point_conversion_form(group); genbuf_len = EC_POINT_point2buf(group, genpt, genform, genbuf, bnctx); if (genbuf_len == 0) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); @@ -336,17 +444,50 @@ int ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) if (!EC_KEY_set_group(ec, group)) goto err; - - /* - * TODO(3.0): if the group has changed, should we invalidate the private and - * public key? - */ ok = 1; err: EC_GROUP_free(group); return ok; } +static int ec_key_point_format_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + int format = -1; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); + if (p != NULL) { + if (!ec_pt_format_param2id(p, &format)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } + EC_KEY_set_conv_form(ec, format); + } + return 1; +} + +static int ec_key_group_check_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE); + if (p != NULL) + return ec_set_check_group_type_from_param(ec, p); + return 1; +} + +static int ec_set_include_public(EC_KEY *ec, int include) +{ + int flags = EC_KEY_get_enc_flags(ec); + + if (!include) + flags |= EC_PKEY_NO_PUBKEY; + else + flags &= ~EC_PKEY_NO_PUBKEY; + EC_KEY_set_enc_flags(ec, flags); + return 1; +} + int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) { const OSSL_PARAM *p; @@ -363,5 +504,69 @@ int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return 0; } + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC); + if (p != NULL) { + int include = 1; + + if (!OSSL_PARAM_get_int(p, &include) + || !ec_set_include_public(ec, include)) + return 0; + } + if (!ec_key_point_format_fromdata(ec, params)) + return 0; + if (!ec_key_group_check_fromdata(ec, params)) + return 0; return 1; } + +int ec_encoding_param2id(const OSSL_PARAM *p, int *id) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) { + int i = ec_encoding_name2id(name); + + if (i >= 0) { + *id = i; + return 1; + } + } + return 0; +} + +int ec_pt_format_param2id(const OSSL_PARAM *p, int *id) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) { + int i = ec_pt_format_name2id(name); + + if (i >= 0) { + *id = i; + return 1; + } + } + return 0; +} diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index d03c75e8aa..d354fd484e 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -9,7 +9,7 @@ */ /* - * ECDSA low level APIs are deprecated for public use, but still ok for + * EC_KEY low level APIs are deprecated for public use, but still ok for * internal use. */ #include "internal/deprecated.h" diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 678b77047d..e1b92f7c33 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -9,7 +9,7 @@ */ /* - * ECDSA low level APIs are deprecated for public use, but still ok for + * EC_GROUP low level APIs are deprecated for public use, but still ok for * internal use. */ #include "internal/deprecated.h" @@ -1461,32 +1461,6 @@ err: return NULL; } -static int ec_encoding_param2id(const OSSL_PARAM *p, int *id) -{ - const char *name = NULL; - int status = 0; - - switch (p->data_type) { - case OSSL_PARAM_UTF8_STRING: - /* The OSSL_PARAM functions have no support for this */ - name = p->data; - status = (name != NULL); - break; - case OSSL_PARAM_UTF8_PTR: - status = OSSL_PARAM_get_utf8_ptr(p, &name); - break; - } - if (status) { - int i = ec_encoding_name2id(name); - - if (i >= 0) { - *id = i; - return 1; - } - } - return 0; -} - static EC_GROUP *group_new_from_name(const OSSL_PARAM *p, OSSL_LIB_CTX *libctx, const char *propq) { @@ -1516,6 +1490,42 @@ static EC_GROUP *group_new_from_name(const OSSL_PARAM *p, return NULL; } +/* These parameters can be set directly into an EC_GROUP */ +int ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]) +{ + int encoding_flag = -1, format = -1; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); + if (p != NULL) { + if (!ec_pt_format_param2id(p, &format)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } + EC_GROUP_set_point_conversion_form(group, format); + } + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); + if (p != NULL) { + if (!ec_encoding_param2id(p, &encoding_flag)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } + EC_GROUP_set_asn1_flag(group, encoding_flag); + } + /* Optional seed */ + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + if (p != NULL) { + /* The seed is allowed to be NULL */ + if (p->data_type != OSSL_PARAM_OCTET_STRING + || !EC_GROUP_set_seed(group, p->data, p->data_size)) { + ECerr(0, EC_R_INVALID_SEED); + return 0; + } + } + return 1; +} + EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], OSSL_LIB_CTX *libctx, const char *propq) { @@ -1530,19 +1540,19 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], const unsigned char *buf = NULL; int encoding_flag = -1; - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); - if (ptmp != NULL && !ec_encoding_param2id(ptmp, &encoding_flag)) { - ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); - return 0; - } - + /* This is the simple named group case */ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); if (ptmp != NULL) { group = group_new_from_name(ptmp, libctx, propq); - if (group != NULL) - EC_GROUP_set_asn1_flag(group, encoding_flag); + if (group != NULL) { + if (!ec_group_set_params(group, params)) { + EC_GROUP_free(group); + group = NULL; + } + } return group; } + /* If it gets here then we are trying explicit parameters */ bnctx = BN_CTX_new_ex(libctx); if (bnctx == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); @@ -1690,6 +1700,12 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], * If we did not find a named group then the encoding should be explicit * if it was specified */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); + if (ptmp != NULL + && !ec_encoding_param2id(ptmp, &encoding_flag)) { + ECerr(0, EC_R_INVALID_ENCODING); + return 0; + } if (encoding_flag == OPENSSL_EC_NAMED_CURVE) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; diff --git a/crypto/ec/eck_prn.c b/crypto/ec/eck_prn.c index 20c6065a31..e731d7c369 100644 --- a/crypto/ec/eck_prn.c +++ b/crypto/ec/eck_prn.c @@ -8,13 +8,16 @@ * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include <stdio.h> #include "internal/cryptlib.h" #include <openssl/evp.h> #include <openssl/ec.h> #include <openssl/bn.h> -#ifndef OPENSSL_NO_STDIO +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef OPENSSL_NO_STDIO int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) { BIO *b; @@ -59,7 +62,7 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x) BIO_free(b); return ret; } -#endif +#endif /* OPENSSL_NO_STDIO */ static int print_bin(BIO *fp, const char *str, const unsigned char *num, size_t len, int off); @@ -256,3 +259,4 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf, return 1; } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ |