DPP: Update PKEX part to use crypto.h API

Rewrite EC point/bignum computation done in PKEX protocol using EC
point/bignum primitives already defined in crypto.h and couple of small
new helper functions.

Signed-off-by: Cedric Izoard <cedric.izoard@ceva-dsp.com>
This commit is contained in:
Cedric Izoard 2021-06-28 18:25:28 +02:00 committed by Jouni Malinen
parent 50708770f0
commit 0d1d74107b
5 changed files with 240 additions and 244 deletions

View file

@ -1751,22 +1751,20 @@ dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
}
EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
const u8 *mac_init, const char *code,
const char *identifier, BN_CTX *bnctx,
EC_GROUP **ret_group)
struct crypto_ec_point *
dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init,
const char *code, const char *identifier,
struct crypto_ec **ret_ec)
{
u8 hash[DPP_MAX_HASH_LEN];
const u8 *addr[3];
size_t len[3];
unsigned int num_elem = 0;
EC_POINT *Qi = NULL;
struct crypto_ec_key *Pi = NULL;
const EC_KEY *Pi_ec;
const EC_POINT *Pi_point;
BIGNUM *hash_bn = NULL;
const EC_GROUP *group = NULL;
EC_GROUP *group2 = NULL;
struct crypto_ec_point *Qi = NULL;
struct crypto_ec_key *Pi_key = NULL;
const struct crypto_ec_point *Pi = NULL;
struct crypto_bignum *hash_bn = NULL;
struct crypto_ec *ec = NULL;
/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
@ -1790,66 +1788,55 @@ EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
wpa_hexdump_key(MSG_DEBUG,
"DPP: H(MAC-Initiator | [identifier |] code)",
hash, curve->hash_len);
Pi = dpp_pkex_get_role_elem(curve, 1);
if (!Pi)
Pi_key = dpp_pkex_get_role_elem(curve, 1);
if (!Pi_key)
goto fail;
dpp_debug_print_key("DPP: Pi", Pi);
Pi_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) Pi);
if (!Pi_ec)
goto fail;
Pi_point = EC_KEY_get0_public_key(Pi_ec);
dpp_debug_print_key("DPP: Pi", Pi_key);
group = EC_KEY_get0_group(Pi_ec);
if (!group)
ec = crypto_ec_init(curve->ike_group);
if (!ec)
goto fail;
group2 = EC_GROUP_dup(group);
if (!group2)
Pi = crypto_ec_key_get_public_key(Pi_key);
Qi = crypto_ec_point_init(ec);
hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
if (!Pi || !Qi || !hash_bn || crypto_ec_point_mul(ec, Pi, hash_bn, Qi))
goto fail;
Qi = EC_POINT_new(group2);
if (!Qi) {
EC_GROUP_free(group2);
goto fail;
}
hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
if (!hash_bn ||
EC_POINT_mul(group2, Qi, NULL, Pi_point, hash_bn, bnctx) != 1)
goto fail;
if (EC_POINT_is_at_infinity(group, Qi)) {
if (crypto_ec_point_is_at_infinity(ec, Qi)) {
wpa_printf(MSG_INFO, "DPP: Qi is the point-at-infinity");
goto fail;
}
dpp_debug_print_point("DPP: Qi", group, Qi);
crypto_ec_point_debug_print(ec, Qi, "DPP: Qi");
out:
crypto_ec_key_deinit(Pi);
BN_clear_free(hash_bn);
if (ret_group && Qi)
*ret_group = group2;
crypto_ec_key_deinit(Pi_key);
crypto_bignum_deinit(hash_bn, 1);
if (ret_ec && Qi)
*ret_ec = ec;
else
EC_GROUP_free(group2);
crypto_ec_deinit(ec);
return Qi;
fail:
EC_POINT_free(Qi);
crypto_ec_point_deinit(Qi, 1);
Qi = NULL;
goto out;
}
EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
const u8 *mac_resp, const char *code,
const char *identifier, BN_CTX *bnctx,
EC_GROUP **ret_group)
struct crypto_ec_point *
dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
const char *code, const char *identifier,
struct crypto_ec **ret_ec)
{
u8 hash[DPP_MAX_HASH_LEN];
const u8 *addr[3];
size_t len[3];
unsigned int num_elem = 0;
EC_POINT *Qr = NULL;
struct crypto_ec_key *Pr = NULL;
const EC_KEY *Pr_ec;
const EC_POINT *Pr_point;
BIGNUM *hash_bn = NULL;
const EC_GROUP *group = NULL;
EC_GROUP *group2 = NULL;
struct crypto_ec_point *Qr = NULL;
struct crypto_ec_key *Pr_key = NULL;
const struct crypto_ec_point *Pr = NULL;
struct crypto_bignum *hash_bn = NULL;
struct crypto_ec *ec = NULL;
/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
@ -1873,45 +1860,37 @@ EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
wpa_hexdump_key(MSG_DEBUG,
"DPP: H(MAC-Responder | [identifier |] code)",
hash, curve->hash_len);
Pr = dpp_pkex_get_role_elem(curve, 0);
if (!Pr)
Pr_key = dpp_pkex_get_role_elem(curve, 0);
if (!Pr_key)
goto fail;
dpp_debug_print_key("DPP: Pr", Pr);
Pr_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) Pr);
if (!Pr_ec)
goto fail;
Pr_point = EC_KEY_get0_public_key(Pr_ec);
dpp_debug_print_key("DPP: Pr", Pr_key);
group = EC_KEY_get0_group(Pr_ec);
if (!group)
ec = crypto_ec_init(curve->ike_group);
if (!ec)
goto fail;
group2 = EC_GROUP_dup(group);
if (!group2)
Pr = crypto_ec_key_get_public_key(Pr_key);
Qr = crypto_ec_point_init(ec);
hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr))
goto fail;
Qr = EC_POINT_new(group2);
if (!Qr) {
EC_GROUP_free(group2);
goto fail;
}
hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
if (!hash_bn ||
EC_POINT_mul(group2, Qr, NULL, Pr_point, hash_bn, bnctx) != 1)
goto fail;
if (EC_POINT_is_at_infinity(group, Qr)) {
if (crypto_ec_point_is_at_infinity(ec, Qr)) {
wpa_printf(MSG_INFO, "DPP: Qr is the point-at-infinity");
goto fail;
}
dpp_debug_print_point("DPP: Qr", group, Qr);
crypto_ec_point_debug_print(ec, Qr, "DPP: Qr");
out:
crypto_ec_key_deinit(Pr);
BN_clear_free(hash_bn);
if (ret_group && Qr)
*ret_group = group2;
crypto_ec_key_deinit(Pr_key);
crypto_bignum_deinit(hash_bn, 1);
if (ret_ec && Qr)
*ret_ec = ec;
else
EC_GROUP_free(group2);
crypto_ec_deinit(ec);
return Qr;
fail:
EC_POINT_free(Qr);
crypto_ec_point_deinit(Qr, 1);
Qr = NULL;
goto out;
}

View file

@ -113,14 +113,14 @@ int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, unsigned int hash_len);
int dpp_derive_pmkid(const struct dpp_curve_params *curve,
struct crypto_ec_key *own_key,
struct crypto_ec_key *peer_key, u8 *pmkid);
EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
const u8 *mac_init, const char *code,
const char *identifier, BN_CTX *bnctx,
EC_GROUP **ret_group);
EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
const u8 *mac_resp, const char *code,
const char *identifier, BN_CTX *bnctx,
EC_GROUP **ret_group);
struct crypto_ec_point *
dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init,
const char *code, const char *identifier,
struct crypto_ec **ret_ec);
struct crypto_ec_point *
dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
const char *code, const char *identifier,
struct crypto_ec **ret_ec);
int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
const u8 *Mx, size_t Mx_len,
const u8 *Nx, size_t Nx_len,

View file

@ -8,8 +8,6 @@
*/
#include "utils/includes.h"
#include <openssl/opensslv.h>
#include <openssl/err.h>
#include "utils/common.h"
#include "common/wpa_ctrl.h"
@ -27,30 +25,13 @@ u8 dpp_pkex_ephemeral_key_override[600];
size_t dpp_pkex_ephemeral_key_override_len = 0;
#endif /* CONFIG_TESTING_OPTIONS */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER < 0x20700000L)
/* Compatibility wrappers for older versions. */
static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_EC)
return NULL;
return pkey->pkey.ec;
}
#endif
static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
{
const EC_KEY *X_ec;
const EC_POINT *X_point;
BN_CTX *bnctx = NULL;
EC_GROUP *group = NULL;
EC_POINT *Qi = NULL, *M = NULL;
struct wpabuf *M_buf = NULL;
BIGNUM *Mx = NULL, *My = NULL;
struct crypto_ec *ec = NULL;
const struct crypto_ec_point *X;
struct crypto_ec_point *Qi = NULL, *M = NULL;
u8 *Mx, *My;
struct wpabuf *msg = NULL;
size_t attr_len;
const struct dpp_curve_params *curve = pkex->own_bi->curve;
@ -58,11 +39,8 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request");
/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
bnctx = BN_CTX_new();
if (!bnctx)
goto fail;
Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code,
pkex->identifier, bnctx, &group);
pkex->identifier, &ec);
if (!Qi)
goto fail;
@ -86,21 +64,15 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
goto fail;
/* M = X + Qi */
X_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) pkex->x);
if (!X_ec)
X = crypto_ec_key_get_public_key(pkex->x);
M = crypto_ec_point_init(ec);
if (!X || !M)
goto fail;
X_point = EC_KEY_get0_public_key(X_ec);
if (!X_point)
crypto_ec_point_debug_print(ec, X, "DPP: X");
if (crypto_ec_point_add(ec, X, Qi, M))
goto fail;
dpp_debug_print_point("DPP: X", group, X_point);
M = EC_POINT_new(group);
Mx = BN_new();
My = BN_new();
if (!M || !Mx || !My ||
EC_POINT_add(group, M, X_point, Qi, bnctx) != 1 ||
EC_POINT_get_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1)
goto fail;
dpp_debug_print_point("DPP: M", group, M);
crypto_ec_point_debug_print(ec, M, "DPP: M");
/* Initiator -> Responder: group, [identifier,] M */
attr_len = 4 + 2;
@ -154,21 +126,17 @@ skip_finite_cyclic_group:
}
#endif /* CONFIG_TESTING_OPTIONS */
if (dpp_bn2bin_pad(Mx, wpabuf_put(msg, curve->prime_len),
curve->prime_len) < 0 ||
dpp_bn2bin_pad(Mx, pkex->Mx, curve->prime_len) < 0 ||
dpp_bn2bin_pad(My, wpabuf_put(msg, curve->prime_len),
curve->prime_len) < 0)
Mx = wpabuf_put(msg, curve->prime_len);
My = wpabuf_put(msg, curve->prime_len);
if (crypto_ec_point_to_bin(ec, M, Mx, My))
goto fail;
os_memcpy(pkex->Mx, Mx, curve->prime_len);
out:
wpabuf_free(M_buf);
EC_POINT_free(M);
EC_POINT_free(Qi);
BN_clear_free(Mx);
BN_clear_free(My);
BN_CTX_free(bnctx);
EC_GROUP_free(group);
crypto_ec_point_deinit(M, 1);
crypto_ec_point_deinit(Qi, 1);
crypto_ec_deinit(ec);
return msg;
fail:
wpa_printf(MSG_INFO, "DPP: Failed to build PKEX Exchange Request");
@ -227,7 +195,7 @@ fail:
static struct wpabuf *
dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex,
enum dpp_status_error status,
const BIGNUM *Nx, const BIGNUM *Ny)
const u8 *Nx, const u8 *Ny)
{
struct wpabuf *msg = NULL;
size_t attr_len;
@ -291,12 +259,9 @@ skip_status:
}
#endif /* CONFIG_TESTING_OPTIONS */
if (dpp_bn2bin_pad(Nx, wpabuf_put(msg, curve->prime_len),
curve->prime_len) < 0 ||
dpp_bn2bin_pad(Nx, pkex->Nx, curve->prime_len) < 0 ||
dpp_bn2bin_pad(Ny, wpabuf_put(msg, curve->prime_len),
curve->prime_len) < 0)
goto fail;
wpabuf_put_data(msg, Nx, curve->prime_len);
wpabuf_put_data(msg, Ny, curve->prime_len);
os_memcpy(pkex->Nx, Nx, curve->prime_len);
skip_encrypted_key:
if (status == DPP_STATUS_BAD_GROUP) {
@ -352,14 +317,11 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
const struct dpp_curve_params *curve = bi->curve;
u16 ike_group;
struct dpp_pkex *pkex = NULL;
EC_POINT *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL, *N = NULL;
BN_CTX *bnctx = NULL;
EC_GROUP *group = NULL;
BIGNUM *Mx = NULL, *My = NULL;
const EC_KEY *Y_ec;
EC_KEY *X_ec = NULL;
const EC_POINT *Y_point;
BIGNUM *Nx = NULL, *Ny = NULL;
struct crypto_ec_point *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL,
*N = NULL;
struct crypto_ec *ec = NULL;
const struct crypto_ec_point *Y;
u8 *x_coord = NULL, *y_coord = NULL;
u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
size_t Kx_len;
int res;
@ -424,34 +386,27 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
}
/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
bnctx = BN_CTX_new();
if (!bnctx)
goto fail;
Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, bnctx,
&group);
Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, &ec);
if (!Qi)
goto fail;
/* X' = M - Qi */
X = EC_POINT_new(group);
M = EC_POINT_new(group);
Mx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
My = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
if (!X || !M || !Mx || !My ||
EC_POINT_set_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1 ||
EC_POINT_is_at_infinity(group, M) ||
!EC_POINT_is_on_curve(group, M, bnctx) ||
EC_POINT_invert(group, Qi, bnctx) != 1 ||
EC_POINT_add(group, X, M, Qi, bnctx) != 1 ||
EC_POINT_is_at_infinity(group, X) ||
!EC_POINT_is_on_curve(group, X, bnctx)) {
X = crypto_ec_point_init(ec);
M = crypto_ec_point_from_bin(ec, attr_key);
if (!X || !M ||
crypto_ec_point_is_at_infinity(ec, M) ||
!crypto_ec_point_is_on_curve(ec, M) ||
crypto_ec_point_invert(ec, Qi) ||
crypto_ec_point_add(ec, M, Qi, X) ||
crypto_ec_point_is_at_infinity(ec, X) ||
!crypto_ec_point_is_on_curve(ec, X)) {
wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
"Invalid Encrypted Key value");
bi->pkex_t++;
goto fail;
}
dpp_debug_print_point("DPP: M", group, M);
dpp_debug_print_point("DPP: X'", group, X);
crypto_ec_point_debug_print(ec, M, "DPP: M");
crypto_ec_point_debug_print(ec, X, "DPP: X'");
pkex = os_zalloc(sizeof(*pkex));
if (!pkex)
@ -472,18 +427,19 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
os_memcpy(pkex->Mx, attr_key, attr_key_len / 2);
X_ec = EC_KEY_new();
if (!X_ec ||
EC_KEY_set_group(X_ec, group) != 1 ||
EC_KEY_set_public_key(X_ec, X) != 1)
x_coord = os_malloc(curve->prime_len);
y_coord = os_malloc(curve->prime_len);
if (!x_coord || !y_coord ||
crypto_ec_point_to_bin(ec, X, x_coord, y_coord))
goto fail;
pkex->x = (struct crypto_ec_key *) EVP_PKEY_new();
if (!pkex->x ||
EVP_PKEY_set1_EC_KEY((EVP_PKEY *) pkex->x, X_ec) != 1)
pkex->x = crypto_ec_key_set_pub(curve->ike_group, x_coord,
y_coord, crypto_ec_prime_len(ec));
if (!pkex->x)
goto fail;
/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, bnctx, NULL);
Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, NULL);
if (!Qr)
goto fail;
@ -507,24 +463,20 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
goto fail;
/* N = Y + Qr */
Y_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) pkex->y);
if (!Y_ec)
Y = crypto_ec_key_get_public_key(pkex->y);
if (!Y)
goto fail;
Y_point = EC_KEY_get0_public_key(Y_ec);
if (!Y_point)
crypto_ec_point_debug_print(ec, Y, "DPP: Y");
N = crypto_ec_point_init(ec);
if (!N ||
crypto_ec_point_add(ec, Y, Qr, N) ||
crypto_ec_point_to_bin(ec, N, x_coord, y_coord))
goto fail;
dpp_debug_print_point("DPP: Y", group, Y_point);
N = EC_POINT_new(group);
Nx = BN_new();
Ny = BN_new();
if (!N || !Nx || !Ny ||
EC_POINT_add(group, N, Y_point, Qr, bnctx) != 1 ||
EC_POINT_get_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1)
goto fail;
dpp_debug_print_point("DPP: N", group, N);
crypto_ec_point_debug_print(ec, N, "DPP: N");
pkex->exchange_resp = dpp_pkex_build_exchange_resp(pkex, DPP_STATUS_OK,
Nx, Ny);
x_coord, y_coord);
if (!pkex->exchange_resp)
goto fail;
@ -548,18 +500,14 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
pkex->exchange_done = 1;
out:
BN_CTX_free(bnctx);
EC_POINT_free(Qi);
EC_POINT_free(Qr);
BN_free(Mx);
BN_free(My);
BN_free(Nx);
BN_free(Ny);
EC_POINT_free(M);
EC_POINT_free(N);
EC_POINT_free(X);
EC_KEY_free(X_ec);
EC_GROUP_free(group);
os_free(x_coord);
os_free(y_coord);
crypto_ec_point_deinit(Qi, 1);
crypto_ec_point_deinit(Qr, 1);
crypto_ec_point_deinit(M, 1);
crypto_ec_point_deinit(N, 1);
crypto_ec_point_deinit(X, 1);
crypto_ec_deinit(ec);
return pkex;
fail:
wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request processing failed");
@ -688,13 +636,11 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
{
const u8 *attr_status, *attr_id, *attr_key, *attr_group;
u16 attr_status_len, attr_id_len, attr_key_len, attr_group_len;
EC_GROUP *group = NULL;
BN_CTX *bnctx = NULL;
struct crypto_ec *ec = NULL;
struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
const struct dpp_curve_params *curve = pkex->own_bi->curve;
EC_POINT *Qr = NULL, *Y = NULL, *N = NULL;
BIGNUM *Nx = NULL, *Ny = NULL;
EC_KEY *Y_ec = NULL;
struct crypto_ec_point *Qr = NULL, *Y = NULL, *N = NULL;
u8 *x_coord = NULL, *y_coord = NULL;
size_t Jx_len, Kx_len;
u8 Jx[DPP_MAX_SHARED_SECRET_LEN], Kx[DPP_MAX_SHARED_SECRET_LEN];
const u8 *addr[4];
@ -765,45 +711,39 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
}
/* Qr = H(MAC-Responder | [identifier |] code) * Pr */
bnctx = BN_CTX_new();
if (!bnctx)
goto fail;
Qr = dpp_pkex_derive_Qr(curve, pkex->peer_mac, pkex->code,
pkex->identifier, bnctx, &group);
pkex->identifier, &ec);
if (!Qr)
goto fail;
/* Y' = N - Qr */
Y = EC_POINT_new(group);
N = EC_POINT_new(group);
Nx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
Ny = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
if (!Y || !N || !Nx || !Ny ||
EC_POINT_set_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1 ||
EC_POINT_is_at_infinity(group, N) ||
!EC_POINT_is_on_curve(group, N, bnctx) ||
EC_POINT_invert(group, Qr, bnctx) != 1 ||
EC_POINT_add(group, Y, N, Qr, bnctx) != 1 ||
EC_POINT_is_at_infinity(group, Y) ||
!EC_POINT_is_on_curve(group, Y, bnctx)) {
Y = crypto_ec_point_init(ec);
N = crypto_ec_point_from_bin(ec, attr_key);
if (!Y || !N ||
crypto_ec_point_is_at_infinity(ec, N) ||
!crypto_ec_point_is_on_curve(ec, N) ||
crypto_ec_point_invert(ec, Qr) ||
crypto_ec_point_add(ec, N, Qr, Y) ||
crypto_ec_point_is_at_infinity(ec, Y) ||
!crypto_ec_point_is_on_curve(ec, Y)) {
dpp_pkex_fail(pkex, "Invalid Encrypted Key value");
pkex->t++;
goto fail;
}
dpp_debug_print_point("DPP: N", group, N);
dpp_debug_print_point("DPP: Y'", group, Y);
crypto_ec_point_debug_print(ec, N, "DPP: N");
crypto_ec_point_debug_print(ec, Y, "DPP: Y'");
pkex->exchange_done = 1;
/* ECDH: J = a * Y' */
Y_ec = EC_KEY_new();
if (!Y_ec ||
EC_KEY_set_group(Y_ec, group) != 1 ||
EC_KEY_set_public_key(Y_ec, Y) != 1)
x_coord = os_malloc(curve->prime_len);
y_coord = os_malloc(curve->prime_len);
if (!x_coord || !y_coord ||
crypto_ec_point_to_bin(ec, Y, x_coord, y_coord))
goto fail;
pkex->y = (struct crypto_ec_key *) EVP_PKEY_new();
if (!pkex->y ||
EVP_PKEY_set1_EC_KEY((EVP_PKEY *) pkex->y, Y_ec) != 1)
pkex->y = crypto_ec_key_set_pub(curve->ike_group, x_coord, y_coord,
curve->prime_len);
if (!pkex->y)
goto fail;
if (dpp_ecdh(pkex->own_bi->pubkey, pkex->y, Jx, &Jx_len) < 0)
goto fail;
@ -855,14 +795,12 @@ out:
wpabuf_free(A_pub);
wpabuf_free(X_pub);
wpabuf_free(Y_pub);
EC_POINT_free(Qr);
EC_POINT_free(Y);
EC_POINT_free(N);
BN_free(Nx);
BN_free(Ny);
EC_KEY_free(Y_ec);
BN_CTX_free(bnctx);
EC_GROUP_free(group);
os_free(x_coord);
os_free(y_coord);
crypto_ec_point_deinit(Qr, 1);
crypto_ec_point_deinit(Y, 1);
crypto_ec_point_deinit(N, 1);
crypto_ec_deinit(ec);
return msg;
fail:
wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed");

View file

@ -920,6 +920,16 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
const struct crypto_ec_point *a,
const struct crypto_ec_point *b);
/**
* crypto_ec_point_debug_print - Dump EC point to debug log
* @e: EC context from crypto_ec_init()
* @p: EC point
* @title: Name of the EC point in the trace
*/
void crypto_ec_point_debug_print(const struct crypto_ec *e,
const struct crypto_ec_point *p,
const char *title);
/**
* struct crypto_ecdh - Elliptic curve DiffieHellman context
*
@ -1048,6 +1058,22 @@ struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
int prefix);
/**
* crypto_ec_key_get_public_key - Get EC public key as an EC point
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
* Returns: Public key as an EC point or %NULL on failure
*/
const struct crypto_ec_point *
crypto_ec_key_get_public_key(struct crypto_ec_key *key);
/**
* crypto_ec_key_get_private_key - Get EC private key as a bignum
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
* Returns: Private key as a bignum or %NULL on failure
*/
const struct crypto_bignum *
crypto_ec_key_get_private_key(struct crypto_ec_key *key);
/**
* crypto_ec_key_sign - Sign a buffer with an EC key
* @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()

View file

@ -1960,6 +1960,35 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
}
void crypto_ec_point_debug_print(const struct crypto_ec *e,
const struct crypto_ec_point *p,
const char *title)
{
BIGNUM *x, *y;
char *x_str = NULL, *y_str = NULL;
x = BN_new();
y = BN_new();
if (!x || !y ||
EC_POINT_get_affine_coordinates_GFp(e->group, (const EC_POINT *) p,
x, y, e->bnctx) != 1)
goto fail;
x_str = BN_bn2hex(x);
y_str = BN_bn2hex(y);
if (!x_str || !y_str)
goto fail;
wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
fail:
OPENSSL_free(x_str);
OPENSSL_free(y_str);
BN_free(x);
BN_free(y);
}
struct crypto_ecdh {
struct crypto_ec *ec;
EVP_PKEY *pkey;
@ -2475,6 +2504,30 @@ struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
}
const struct crypto_ec_point *
crypto_ec_key_get_public_key(struct crypto_ec_key *key)
{
EC_KEY *eckey;
eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
if (!eckey)
return NULL;
return (const struct crypto_ec_point *) EC_KEY_get0_public_key(eckey);
}
const struct crypto_bignum *
crypto_ec_key_get_private_key(struct crypto_ec_key *key)
{
EC_KEY *eckey;
eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
if (!eckey)
return NULL;
return (const struct crypto_bignum *) EC_KEY_get0_private_key(eckey);
}
struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
size_t len)
{