[PATCH 11/21] dpp: Update pkex part to use crypto.h API
Cedric Izoard
cedric.izoard at ceva-dsp.com
Mon Jun 28 09:25:28 PDT 2021
Rewrite EC point/bignum computation done in PKEX protocol using EC
point/bignum primitives already defined in crypto.h
Signed-off-by: Cedric Izoard <cedric.izoard at ceva-dsp.com>
---
src/common/dpp_crypto.c | 137 +++++++++-----------
src/common/dpp_i.h | 16 +--
src/common/dpp_pkex.c | 252 ++++++++++++++----------------------
src/crypto/crypto.h | 24 ++++
src/crypto/crypto_openssl.c | 49 +++++++
5 files changed, 236 insertions(+), 242 deletions(-)
diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c
index 2e4a9a27a..c1dffdb6f 100644
--- a/src/common/dpp_crypto.c
+++ b/src/common/dpp_crypto.c
@@ -1656,22 +1656,20 @@ static struct crypto_ec_key * dpp_pkex_get_role_elem(const struct dpp_curve_para
}
-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 */
@@ -1695,66 +1693,58 @@ 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)
- goto fail;
- Qi = EC_POINT_new(group2);
- if (!Qi) {
- EC_GROUP_free(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)
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)
+
+ if (crypto_ec_point_mul(ec, Pi, hash_bn, Qi))
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 */
@@ -1778,45 +1768,40 @@ 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)
- goto fail;
- dpp_debug_print_key("DPP: Pr", Pr);
- Pr_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)Pr);
- if (!Pr_ec)
+ Pr_key = dpp_pkex_get_role_elem(curve, 0);
+ if (!Pr_key)
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)
- goto fail;
- group2 = EC_GROUP_dup(group);
- if (!group2)
+ ec = crypto_ec_init(curve->ike_group);
+ if (!ec)
goto fail;
- Qr = EC_POINT_new(group2);
- if (!Qr) {
- EC_GROUP_free(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)
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)
+
+ if (crypto_ec_point_mul(ec, Pr, hash_bn, Qr))
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;
}
diff --git a/src/common/dpp_i.h b/src/common/dpp_i.h
index 06560a3d5..4686fb02b 100644
--- a/src/common/dpp_i.h
+++ b/src/common/dpp_i.h
@@ -109,14 +109,14 @@ int dpp_auth_derive_l_initiator(struct dpp_authentication *auth);
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,
diff --git a/src/common/dpp_pkex.c b/src/common/dpp_pkex.c
index 24f7536a8..c6bfafaae 100644
--- a/src/common/dpp_pkex.c
+++ b/src/common/dpp_pkex.c
@@ -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 = NULL;
+ 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)
- 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)
+ 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: 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;
+ os_memcpy(wpabuf_put(msg, curve->prime_len), Nx, curve->prime_len);
+ os_memcpy(wpabuf_put(msg, curve->prime_len), Ny, curve->prime_len);
+ os_memcpy(pkex->Nx, Nx, curve->prime_len);
skip_encrypted_key:
if (status == DPP_STATUS_BAD_GROUP) {
@@ -352,14 +317,10 @@ 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 = NULL;
+ u8 *x_coord = NULL, *y_coord = NULL;
u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
size_t Kx_len;
int res;
@@ -424,34 +385,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 +426,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 +462,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)
- 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)
+ 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: 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 +499,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 +635,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 +710,38 @@ 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 +793,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");
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 3473b3519..7c2bc82e2 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -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
+ * @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
*
@@ -1045,6 +1055,20 @@ 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 a an EC point and %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 and %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()
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 275ec6252..308bab908 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1951,6 +1951,33 @@ 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;
@@ -2494,6 +2521,28 @@ struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int pr
}
+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)
{
--
2.17.0
More information about the Hostap
mailing list