]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Update PKEX part to use crypto.h API
authorCedric Izoard <cedric.izoard@ceva-dsp.com>
Mon, 28 Jun 2021 16:25:28 +0000 (18:25 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 26 Oct 2021 20:20:57 +0000 (23:20 +0300)
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>
src/common/dpp_crypto.c
src/common/dpp_i.h
src/common/dpp_pkex.c
src/crypto/crypto.h
src/crypto/crypto_openssl.c

index 5c899b664440466ee67b2b753a7aa2a6f37cd5df..b6c2569f9d2d70bc3710ab492d82812078ace9a7 100644 (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)
-               goto fail;
-       group2 = EC_GROUP_dup(group);
-       if (!group2)
-               goto fail;
-       Qi = EC_POINT_new(group2);
-       if (!Qi) {
-               EC_GROUP_free(group2);
+       ec = crypto_ec_init(curve->ike_group);
+       if (!ec)
                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)
+
+       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;
-       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)
-               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);
-               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)
+
+       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;
-       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;
 }
index 87beade3d3bb6459e2d98c2e4eeb73de860d28b0..2aaaa7331d1dcb7feb15229187988ddb918bc13d 100644 (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,
index 873861c9453d0e3a015e4c66891ce25176bad8f1..06532b5457bd700a2c7d0bf776aafff9f4a6379d 100644 (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)
-               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;
+       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)
-               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 +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");
index e98d1d816224372a0acb81d974e1819a985b55ee..bd56fe8eaec404b4f52e9ef31eac342078cf2c8c 100644 (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 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()
index c640b0fa9a3575f6ee088817337f555b453a72ac..2da796d7186c5be8ad40a8a55bc4ea6e5ab0363e 100644 (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)
 {