DPP: Move dpp_set_pubkey_point_group() to crypto.h
Move code of dpp_set_pubkey_point_group() into crypto.h API. This function initializes an EC public key using coordinates of the EC point in binary format. Signed-off-by: Cedric Izoard <cedric.izoard@ceva-dsp.com>
This commit is contained in:
parent
e84b143e1a
commit
9c1632908d
5 changed files with 107 additions and 111 deletions
|
@ -2167,8 +2167,7 @@ struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
|
||||||
struct json_token *token;
|
struct json_token *token;
|
||||||
const struct dpp_curve_params *curve;
|
const struct dpp_curve_params *curve;
|
||||||
struct wpabuf *x = NULL, *y = NULL;
|
struct wpabuf *x = NULL, *y = NULL;
|
||||||
EC_GROUP *group;
|
struct crypto_ec_key *key = NULL;
|
||||||
struct crypto_ec_key *pkey = NULL;
|
|
||||||
|
|
||||||
token = json_get_member(jwk, "kty");
|
token = json_get_member(jwk, "kty");
|
||||||
if (!token || token->type != JSON_STRING) {
|
if (!token || token->type != JSON_STRING) {
|
||||||
|
@ -2221,22 +2220,18 @@ struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
|
key = crypto_ec_key_set_pub(curve->ike_group, wpabuf_head(x),
|
||||||
if (!group) {
|
wpabuf_head(y), wpabuf_len(x));
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Could not prepare group for JWK");
|
if (!key)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
pkey = dpp_set_pubkey_point_group(group, wpabuf_head(x), wpabuf_head(y),
|
|
||||||
wpabuf_len(x));
|
|
||||||
EC_GROUP_free(group);
|
|
||||||
*key_curve = curve;
|
*key_curve = curve;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
wpabuf_free(x);
|
wpabuf_free(x);
|
||||||
wpabuf_free(y);
|
wpabuf_free(y);
|
||||||
|
|
||||||
return pkey;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -374,101 +374,20 @@ int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct crypto_ec_key * dpp_set_pubkey_point_group(const EC_GROUP *group,
|
|
||||||
const u8 *buf_x,
|
|
||||||
const u8 *buf_y,
|
|
||||||
size_t len)
|
|
||||||
{
|
|
||||||
EC_KEY *eckey = NULL;
|
|
||||||
BN_CTX *ctx;
|
|
||||||
EC_POINT *point = NULL;
|
|
||||||
BIGNUM *x = NULL, *y = NULL;
|
|
||||||
EVP_PKEY *pkey = NULL;
|
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
|
||||||
if (!ctx) {
|
|
||||||
wpa_printf(MSG_ERROR, "DPP: Out of memory");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
point = EC_POINT_new(group);
|
|
||||||
x = BN_bin2bn(buf_x, len, NULL);
|
|
||||||
y = BN_bin2bn(buf_y, len, NULL);
|
|
||||||
if (!point || !x || !y) {
|
|
||||||
wpa_printf(MSG_ERROR, "DPP: Out of memory");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
|
|
||||||
wpa_printf(MSG_ERROR,
|
|
||||||
"DPP: OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EC_POINT_is_on_curve(group, point, ctx) ||
|
|
||||||
EC_POINT_is_at_infinity(group, point)) {
|
|
||||||
wpa_printf(MSG_ERROR, "DPP: Invalid point");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
dpp_debug_print_point("DPP: dpp_set_pubkey_point_group", group, point);
|
|
||||||
|
|
||||||
eckey = EC_KEY_new();
|
|
||||||
if (!eckey ||
|
|
||||||
EC_KEY_set_group(eckey, group) != 1 ||
|
|
||||||
EC_KEY_set_public_key(eckey, point) != 1) {
|
|
||||||
wpa_printf(MSG_ERROR,
|
|
||||||
"DPP: Failed to set EC_KEY: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
|
|
||||||
|
|
||||||
pkey = EVP_PKEY_new();
|
|
||||||
if (!pkey || EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) {
|
|
||||||
wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
BN_free(x);
|
|
||||||
BN_free(y);
|
|
||||||
EC_KEY_free(eckey);
|
|
||||||
EC_POINT_free(point);
|
|
||||||
BN_CTX_free(ctx);
|
|
||||||
return (struct crypto_ec_key *) pkey;
|
|
||||||
fail:
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
pkey = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
|
struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
|
||||||
const u8 *buf, size_t len)
|
const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
const EC_KEY *eckey;
|
int ike_group = crypto_ec_key_group(group_key);
|
||||||
const EC_GROUP *group;
|
|
||||||
struct crypto_ec_key *pkey = NULL;
|
|
||||||
|
|
||||||
if (len & 1)
|
if (len & 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) group_key);
|
if (ike_group < 0) {
|
||||||
if (!eckey) {
|
wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
|
||||||
wpa_printf(MSG_ERROR,
|
|
||||||
"DPP: Could not get EC_KEY from group_key");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
group = EC_KEY_get0_group(eckey);
|
return crypto_ec_key_set_pub(ike_group, buf, buf + len / 2, len / 2);
|
||||||
if (group)
|
|
||||||
pkey = dpp_set_pubkey_point_group(group, buf, buf + len / 2,
|
|
||||||
len / 2);
|
|
||||||
else
|
|
||||||
wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
|
|
||||||
|
|
||||||
return pkey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1914,10 +1833,7 @@ static const u8 pkex_resp_y_bp_p512r1[64] = {
|
||||||
static struct crypto_ec_key *
|
static struct crypto_ec_key *
|
||||||
dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
|
dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
|
||||||
{
|
{
|
||||||
EC_GROUP *group;
|
|
||||||
size_t len = curve->prime_len;
|
|
||||||
const u8 *x, *y;
|
const u8 *x, *y;
|
||||||
struct crypto_ec_key *res;
|
|
||||||
|
|
||||||
switch (curve->ike_group) {
|
switch (curve->ike_group) {
|
||||||
case 19:
|
case 19:
|
||||||
|
@ -1948,12 +1864,7 @@ dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
|
return crypto_ec_key_set_pub(curve->ike_group, x, y, curve->prime_len);
|
||||||
if (!group)
|
|
||||||
return NULL;
|
|
||||||
res = dpp_set_pubkey_point_group(group, x, y, len);
|
|
||||||
EC_GROUP_free(group);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,10 +78,6 @@ const struct dpp_curve_params * dpp_get_curve_nid(int nid);
|
||||||
const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group);
|
const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group);
|
||||||
int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
|
int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
|
||||||
const u8 *data, size_t data_len);
|
const u8 *data, size_t data_len);
|
||||||
struct crypto_ec_key * dpp_set_pubkey_point_group(const EC_GROUP *group,
|
|
||||||
const u8 *buf_x,
|
|
||||||
const u8 *buf_y,
|
|
||||||
size_t len);
|
|
||||||
struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
|
struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
|
||||||
const u8 *buf, size_t len);
|
const u8 *buf, size_t len);
|
||||||
int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len);
|
int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len);
|
||||||
|
|
|
@ -994,6 +994,20 @@ struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len);
|
||||||
*/
|
*/
|
||||||
struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len);
|
struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crypto_ec_key_set_pub - Initialize an EC public key from EC point coordinates
|
||||||
|
* @group: Identifying number for the ECC group
|
||||||
|
* @x: X coordinate of the public key
|
||||||
|
* @y: Y coordinate of the public key
|
||||||
|
* @len: Length of @x and @y buffer
|
||||||
|
* Returns: EC key or %NULL on failure
|
||||||
|
*
|
||||||
|
* This function initialize an EC key from public key coordinates, in big endian
|
||||||
|
* byte order padded to the length of the prime defining the group.
|
||||||
|
*/
|
||||||
|
struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
|
||||||
|
const u8 *y, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_key_gen - Generate EC key pair
|
* crypto_ec_key_gen - Generate EC key pair
|
||||||
* @group: Identifying number for the ECC group
|
* @group: Identifying number for the ECC group
|
||||||
|
@ -1009,7 +1023,7 @@ void crypto_ec_key_deinit(struct crypto_ec_key *key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for an EC key
|
* crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for an EC key
|
||||||
* @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen()
|
* @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
|
||||||
* Returns: Buffer with DER encoding of ASN.1 SubjectPublicKeyInfo or %NULL on failure
|
* Returns: Buffer with DER encoding of ASN.1 SubjectPublicKeyInfo or %NULL on failure
|
||||||
*/
|
*/
|
||||||
struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key);
|
struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key);
|
||||||
|
@ -1046,7 +1060,7 @@ struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_key_verify_signature - Verify ECDSA signature
|
* crypto_ec_key_verify_signature - Verify ECDSA signature
|
||||||
* @key: EC key from crypto_ec_key_parse_pub() or crypto_ec_key_gen()
|
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_gen()
|
||||||
* @data: Data to be signed
|
* @data: Data to be signed
|
||||||
* @len: Length of @data buffer
|
* @len: Length of @data buffer
|
||||||
* @sig: DER encoding of ASN.1 Ecdsa-Sig-Value
|
* @sig: DER encoding of ASN.1 Ecdsa-Sig-Value
|
||||||
|
@ -1058,7 +1072,7 @@ int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_key_group - Get IANA group identifier for an EC key
|
* crypto_ec_key_group - Get IANA group identifier for an EC key
|
||||||
* @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen()
|
* @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
|
||||||
* Returns: IANA group identifier and -1 on failure
|
* Returns: IANA group identifier and -1 on failure
|
||||||
*/
|
*/
|
||||||
int crypto_ec_key_group(struct crypto_ec_key *key);
|
int crypto_ec_key_group(struct crypto_ec_key *key);
|
||||||
|
|
|
@ -2242,6 +2242,86 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *buf_x,
|
||||||
|
const u8 *buf_y, size_t len)
|
||||||
|
{
|
||||||
|
EC_KEY *eckey = NULL;
|
||||||
|
EVP_PKEY *pkey = NULL;
|
||||||
|
EC_GROUP *ec_group = NULL;
|
||||||
|
BN_CTX *ctx;
|
||||||
|
EC_POINT *point = NULL;
|
||||||
|
BIGNUM *x = NULL, *y = NULL;
|
||||||
|
int nid;
|
||||||
|
|
||||||
|
if (!buf_x || !buf_y)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
nid = crypto_ec_group_2_nid(group);
|
||||||
|
if (nid < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = BN_CTX_new();
|
||||||
|
if (!ctx)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ec_group = EC_GROUP_new_by_curve_name(nid);
|
||||||
|
if (!ec_group)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
x = BN_bin2bn(buf_x, len, NULL);
|
||||||
|
y = BN_bin2bn(buf_y, len, NULL);
|
||||||
|
point = EC_POINT_new(ec_group);
|
||||||
|
if (!x || !y || !point)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!EC_POINT_set_affine_coordinates_GFp(ec_group, point, x, y, ctx)) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EC_POINT_is_on_curve(ec_group, point, ctx) ||
|
||||||
|
EC_POINT_is_at_infinity(ec_group, point)) {
|
||||||
|
wpa_printf(MSG_ERROR, "OpenSSL: Invalid point");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
eckey = EC_KEY_new();
|
||||||
|
if (!eckey ||
|
||||||
|
EC_KEY_set_group(eckey, ec_group) != 1 ||
|
||||||
|
EC_KEY_set_public_key(eckey, point) != 1) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"OpenSSL: Failed to set EC_KEY: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
|
||||||
|
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
|
||||||
|
wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
EC_GROUP_free(ec_group);
|
||||||
|
BN_free(x);
|
||||||
|
BN_free(y);
|
||||||
|
EC_POINT_free(point);
|
||||||
|
BN_CTX_free(ctx);
|
||||||
|
return (struct crypto_ec_key *) pkey;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
EC_KEY_free(eckey);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
pkey = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct crypto_ec_key * crypto_ec_key_gen(int group)
|
struct crypto_ec_key * crypto_ec_key_gen(int group)
|
||||||
{
|
{
|
||||||
EVP_PKEY_CTX *kctx = NULL;
|
EVP_PKEY_CTX *kctx = NULL;
|
||||||
|
|
Loading…
Reference in a new issue