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@xxxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap