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:
parent
50708770f0
commit
0d1d74107b
5 changed files with 240 additions and 244 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 Diffie–Hellman 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()
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue