summaryrefslogtreecommitdiffstats
path: root/crypto/ec
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-10-15 13:41:59 +1000
committerTomas Mraz <tomas@openssl.org>2021-01-26 15:22:14 +0100
commit5b5eea4b60b682009d2b15587c9ceeae5e9c73f8 (patch)
tree4a3261cb27a582770270a07b40ecf05ecb71c89a /crypto/ec
parent98dbf2c1c8143c0cc6dd05be7950d90bc6792064 (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.c219
-rw-r--r--crypto/ec/ec_key.c2
-rw-r--r--crypto/ec/ec_lib.c86
-rw-r--r--crypto/ec/eck_prn.c8
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 */