/*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
*/
#include "internal/deprecated.h"
-#include "e_os.h" /* strcasecmp */
#include <string.h>
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
if (p != NULL || tmpl != NULL) {
/* convert pub_point to a octet string according to the SECG standard */
+ point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
+
if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
- POINT_CONVERSION_COMPRESSED,
+ format,
pub_key, bnctx)) == 0
|| !ossl_param_build_set_octet_string(tmpl, p,
OSSL_PKEY_PARAM_PUB_KEY,
goto err;
}
if (px != NULL || py != NULL) {
- if (px != NULL)
+ if (px != NULL) {
x = BN_CTX_get(bnctx);
- if (py != NULL)
+ if (x == NULL)
+ goto err;
+ }
+ if (py != NULL) {
y = BN_CTX_get(bnctx);
+ if (y == NULL)
+ goto err;
+ }
if (!EC_POINT_get_affine_coordinates(ecg, pub_point, x, y, bnctx))
goto err;
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
ok = ok && group_a != NULL && group_b != NULL
&& EC_GROUP_cmp(group_a, group_b, ctx) == 0;
- if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
- const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
- const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
+ if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+ int key_checked = 0;
- ok = ok && BN_cmp(pa, pb) == 0;
- }
- if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
- const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
- const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
+ const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
- ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
+ if (pa != NULL && pb != NULL) {
+ ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
+ key_checked = 1;
+ }
+ }
+ if (!key_checked
+ && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
+ const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
+
+ if (pa != NULL && pb != NULL) {
+ ok = ok && BN_cmp(pa, pb) == 0;
+ key_checked = 1;
+ }
+ }
+ ok = ok && key_checked;
}
BN_CTX_free(ctx);
return ok;
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
&& (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
return 0;
- if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
- && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
- return 0;
tmpl = OSSL_PARAM_BLD_new();
if (tmpl == NULL)
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
ok = ok && otherparams_to_params(ec, tmpl, NULL);
- if (ok && (params = OSSL_PARAM_BLD_to_param(tmpl)) != NULL)
- ok = param_cb(params, cbarg);
-end:
+ if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
+ ok = 0;
+ goto end;
+ }
+
+ ok = param_cb(params, cbarg);
OSSL_PARAM_free(params);
+end:
OSSL_PARAM_BLD_free(tmpl);
OPENSSL_free(pub_key);
OPENSSL_free(genbuf);
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), \
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), \
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_EC_SEED, NULL, 0), \
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL)
# define EC_IMEXPORTABLE_PUBLIC_KEY \
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
BN_CTX *bnctx = NULL;
ecg = EC_KEY_get0_group(eck);
- if (ecg == NULL)
+ if (ecg == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
return 0;
+ }
libctx = ossl_ec_key_get_libctx(eck);
propq = ossl_ec_key_get0_propq(eck);
}
if ((p = OSSL_PARAM_locate(params,
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {
- p->return_size = EC_POINT_point2oct(EC_KEY_get0_group(key),
- EC_KEY_get0_public_key(key),
+ const EC_POINT *ecp = EC_KEY_get0_public_key(key);
+
+ if (ecp == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+ goto err;
+ }
+ p->return_size = EC_POINT_point2oct(ecg, ecp,
POINT_CONVERSION_UNCOMPRESSED,
- p->data, p->return_size, bnctx);
+ p->data, p->data_size, bnctx);
if (p->return_size == 0)
goto err;
}
if ((flags & EC_FLAG_CHECK_NAMED_GROUP) != 0)
ok = ok && EC_GROUP_check_named_curve(EC_KEY_get0_group(eck),
- (flags & EC_FLAG_CHECK_NAMED_GROUP_NIST) != 0, ctx);
+ (flags & EC_FLAG_CHECK_NAMED_GROUP_NIST) != 0, ctx) > 0;
else
ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
}
int selection;
int ecdh_mode;
EC_GROUP *gen_group;
+ unsigned char *dhkem_ikm;
+ size_t dhkem_ikmlen;
};
static void *ec_gen_init(void *provctx, int selection,
gctx->libctx = libctx;
gctx->selection = selection;
gctx->ecdh_mode = 0;
- }
- if (!ec_gen_set_params(gctx, params)) {
- OPENSSL_free(gctx);
- gctx = NULL;
+ if (!ec_gen_set_params(gctx, params)) {
+ OPENSSL_free(gctx);
+ gctx = NULL;
+ }
}
return gctx;
}
return gctx;
if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL)
return gctx;
- ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ec_gen_cleanup(gctx);
}
return NULL;
COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen,
gctx->gen_len);
+ COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_DHKEM_IKM, gctx->dhkem_ikm,
+ gctx->dhkem_ikmlen);
+
ret = 1;
err:
EC_GROUP_free(group);
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),
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_PARAM_END
};
ret = ec_gen_assign_group(ec, gctx->gen_group);
/* Whether you want it or not, you get a keypair, not just one half */
- if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
- ret = ret && EC_KEY_generate_key(ec);
+ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+#ifndef FIPS_MODULE
+ if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0)
+ ret = ret && ossl_ec_generate_key_dhkem(ec, gctx->dhkem_ikm,
+ gctx->dhkem_ikmlen);
+ else
+#endif
+ ret = ret && EC_KEY_generate_key(ec);
+ }
if (gctx->ecdh_mode != -1)
ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode);
if (gctx->group_check != NULL)
- ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check);
+ ret = ret && ossl_ec_set_check_group_type_from_name(ec,
+ gctx->group_check);
if (ret)
return ec;
err:
if (gctx == NULL)
return;
+ OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
EC_GROUP_free(gctx->gen_group);
BN_free(gctx->p);
BN_free(gctx->a);
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))ec_query_operation_name },
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
- { 0, NULL }
+ OSSL_DISPATCH_END
};
#ifndef FIPS_MODULE
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))sm2_query_operation_name },
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
- { 0, NULL }
+ OSSL_DISPATCH_END
};
# endif
#endif