diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c index 18a19f92fc..5f929284be 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -501,8 +501,8 @@ static struct crypto_ec_key *crypto_alloc_key(void) return (struct crypto_ec_key *)key; } -struct crypto_ec_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *group, - const u8 *buf, size_t len) +struct crypto_ec_key * crypto_ec_key_set_pub(const struct crypto_ec_group *group, + const u8 *buf, size_t len) { mbedtls_ecp_point *point = NULL; struct crypto_ec_key *pkey = NULL; @@ -557,13 +557,6 @@ fail: return pkey; } -void crypto_ec_free_key(struct crypto_ec_key *key) -{ - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - mbedtls_pk_free(pkey); - os_free(key); -} - struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key) { mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; @@ -820,8 +813,10 @@ fail: return ret; } -int crypto_edcsa_sign_verify(const unsigned char *hash, - const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_ec_key *csign, int hlen) +int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, + const unsigned char *hash, int hlen, + const u8 *r, size_t r_len, + const u8 *s, size_t s_len) { /* (mbedtls_ecdsa_context *) */ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)csign); @@ -829,35 +824,41 @@ int crypto_edcsa_sign_verify(const unsigned char *hash, return -1; } + struct crypto_bignum *rb = NULL, *sb = NULL; + rb = crypto_bignum_init_set(r, r_len); + sb = crypto_bignum_init_set(s, s_len); + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); mbedtls_ecp_point *ecp_kp_q = &ecp_kp->MBEDTLS_PRIVATE(Q); int ret = mbedtls_ecdsa_verify(ecp_kp_grp, hash, hlen, - ecp_kp_q, (mbedtls_mpi *)r, (mbedtls_mpi *)s); + ecp_kp_q, (mbedtls_mpi *)rb, (mbedtls_mpi *)sb); if (ret != 0) { wpa_printf(MSG_ERROR, "ecdsa verification failed"); + crypto_bignum_deinit(rb, 0); + crypto_bignum_deinit(sb, 0); return ret; } return ret; } -void crypto_ec_key_debug_print(const char *title, struct crypto_ec_key *key) +void crypto_ec_key_debug_print(struct crypto_ec_key *key, const char *title) { #ifdef DEBUG_PRINT mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(*pkey); u8 x[32], y[32], d[32]; - wpa_printf(MSG_ERROR, "curve: %s", + wpa_printf(MSG_INFO, "curve: %s", mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key))); - wpa_printf(MSG_ERROR, "prime len is %d", len); + wpa_printf(MSG_INFO, "prime len is %d", len); crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_key_get_public_key(key), x, y); crypto_bignum_to_bin(crypto_ec_key_get_private_key(key), - d, len, len); + d, len, len); wpa_hexdump(MSG_INFO, "Q_x:", x, 32); wpa_hexdump(MSG_INFO, "Q_y:", y, 32); - wpa_hexdump(MSG_INFO, "d: ", d , 32); + wpa_hexdump(MSG_INFO, "d: ", d, 32); #endif } @@ -1036,6 +1037,23 @@ int crypto_ec_write_pub_key(struct crypto_ec_key *key, unsigned char **key_buf) return len; } +struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) +{ + unsigned char *der = NULL; + struct wpabuf *ret = NULL; + int der_len; + + der_len = crypto_ec_write_pub_key(key, &der); + if (!der) { + wpa_printf(MSG_ERROR, "failed to get der for bootstrapping key\n"); + return NULL; + } + ret = wpabuf_alloc_copy(der, der_len); + + os_free(der); + return ret; +} + int crypto_mbedtls_get_grp_id(int group) { switch (group) { @@ -1188,7 +1206,7 @@ struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, os_memcpy(buf, px, len); os_memcpy(buf + len, py, len); - pkey = crypto_ec_set_pubkey_point((struct crypto_ec_group*)ACCESS_ECDH(&ctx, grp), buf, len); + pkey = crypto_ec_key_set_pub((struct crypto_ec_group*)ACCESS_ECDH(&ctx, grp), buf, len); if (!pkey) { wpa_printf(MSG_ERROR, "Failed to set point for peer's public key"); goto cleanup; @@ -1228,7 +1246,7 @@ cleanup: os_free(py); os_free(buf); os_free(secret); - crypto_ec_free_key(pkey); + crypto_ec_key_deinit(pkey); crypto_bignum_deinit(bn_x, 1); crypto_ec_point_deinit(ec_pt, 1); mbedtls_ctr_drbg_free(&ctr_drbg); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h index b8e4c280ef..d3dbc95c37 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h @@ -59,8 +59,7 @@ int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t chann esp_err_t esp_dpp_post_evt(uint32_t evt_id, uint32_t data); #ifdef CONFIG_TESTING_OPTIONS -int dpp_test_gen_invalid_key(struct wpabuf *msg, - const struct dpp_curve_params *curve); +int dpp_test_gen_invalid_key(struct wpabuf *msg, const struct dpp_curve_params *curve); char * dpp_corrupt_connector_signature(const char *connector); #endif /* CONFIG_TESTING_OPTIONS */ diff --git a/components/wpa_supplicant/src/common/dpp.c b/components/wpa_supplicant/src/common/dpp.c index 75bf205e13..7fa67d10fa 100644 --- a/components/wpa_supplicant/src/common/dpp.c +++ b/components/wpa_supplicant/src/common/dpp.c @@ -20,6 +20,8 @@ #include "crypto/aes_siv.h" #include "crypto/sha256.h" #include "dpp.h" +#include "dpp_i.h" +#include "esp_dpp_i.h" static const char * dpp_netrole_str(enum dpp_netrole netrole); @@ -30,7 +32,7 @@ size_t dpp_protocol_key_override_len = 0; u8 dpp_nonce_override[DPP_MAX_NONCE_LEN]; size_t dpp_nonce_override_len = 0; -static int dpp_test_gen_invalid_key(struct wpabuf *msg, +int dpp_test_gen_invalid_key(struct wpabuf *msg, const struct dpp_curve_params *curve); #endif /* CONFIG_TESTING_OPTIONS */ @@ -73,7 +75,7 @@ void dpp_debug_print_point(const char *title, struct crypto_ec *e, u8 x[64], y[64]; if (crypto_ec_point_to_bin(e, point, x, y) < 0) { - printf("error: failed to get coordinates\n"); + wpa_printf(MSG_ERROR, "Failed to get coordinates"); return; } @@ -198,7 +200,9 @@ void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info) return; os_free(info->uri); os_free(info->info); - crypto_ec_free_key(info->pubkey); + os_free(info->chan); + os_free(info->pk); + crypto_ec_key_deinit(info->pubkey); os_free(info); } @@ -349,68 +353,6 @@ static int dpp_parse_uri_pk(struct dpp_bootstrap_info *bi, const char *info) res = dpp_get_subject_public_key(bi, data, data_len); os_free(data); return res; -#if 0 - if (sha256_vector(1, (const u8 **) &data, &data_len, - bi->pubkey_hash) < 0) { - wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key"); - os_free(data); - return -1; - } - wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", - bi->pubkey_hash, SHA256_MAC_LEN); - - /* DER encoded ASN.1 SubjectPublicKeyInfo - * - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - * - * subjectPublicKey = compressed format public key per ANSI X9.63 - * algorithm = ecPublicKey (1.2.840.10045.2.1) - * parameters = shall be present and shall be OBJECT IDENTIFIER; e.g., - * prime256v1 (1.2.840.10045.3.1.7) - */ - - p = data; - - pkey = crypto_ec_parse_subpub_key((unsigned char *)p, data_len); - os_free(data); - - if (!pkey) { - wpa_printf(MSG_DEBUG, - "DPP: Could not parse URI public-key SubjectPublicKeyInfo"); - return -1; - } - - if (!crypto_is_ec_key(pkey)) { - wpa_printf(MSG_DEBUG, - "DPP: SubjectPublicKeyInfo does not describe an EC key"); - crypto_ec_free_key(pkey); - return -1; - } - - group = crypto_ec_get_group_from_key(pkey); - if (!group) { - return -1; - } - id = crypto_ec_get_curve_id(group); - bi->curve = dpp_get_curve_group_id(id); - if (!bi->curve) { - wpa_printf(MSG_DEBUG, - "DPP: Unsupported SubjectPublicKeyInfo curve"); - goto fail; - } - - bi->pubkey = pkey; - return 0; -fail: - crypto_ec_free_key(pkey); - return -1; -#endif } static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri) @@ -1073,11 +1015,40 @@ static int dpp_prepare_channel_list(struct dpp_authentication *auth, return 0; } +int dpp_gen_uri(struct dpp_bootstrap_info *bi) +{ + char macstr[ETH_ALEN * 2 + 10]; + size_t len; + + len = 4; /* "DPP:" */ + if (bi->chan) + len += 3 + os_strlen(bi->chan); /* C:...; */ + if (is_zero_ether_addr(bi->mac_addr)) + macstr[0] = '\0'; + else + os_snprintf(macstr, sizeof(macstr), "M:" MACSTR ";", MAC2STR(bi->mac_addr)); + len += os_strlen(macstr); /* M:...; */ + if (bi->info) + len += 3 + os_strlen(bi->info); /* I:...; */ + len += 4 + os_strlen(bi->pk); /* K:...;; */ + + os_free(bi->uri); + bi->uri = os_malloc(len + 1); + if (!bi->uri) + return -1; + os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%sK:%s;;", + bi->chan ? "C:" : "", bi->chan ? bi->chan : "", + bi->chan ? ";" : "", + macstr, + bi->info ? "I:" : "", bi->info ? bi->info : "", + bi->info ? ";" : "", + bi->pk); + return 0; +} + static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth) { struct dpp_bootstrap_info *bi; - char *pk = NULL; - size_t len; if (auth->own_bi) return 0; /* already generated */ @@ -1086,27 +1057,16 @@ static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth) if (!bi) return -1; bi->type = DPP_BOOTSTRAP_QR_CODE; - pk = dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0); - if (!pk) + if (dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0) < 0 || + dpp_gen_uri(bi) < 0) goto fail; - - len = 4; /* "DPP:" */ - len += 4 + os_strlen(pk); - bi->uri = os_malloc(len + 1); - if (!bi->uri) - goto fail; - os_snprintf(bi->uri, len + 1, "DPP:K:%s;;", pk); wpa_printf(MSG_DEBUG, "DPP: Auto-generated own bootstrapping key info: URI %s", bi->uri); - auth->tmp_own_bi = auth->own_bi = bi; - os_free(pk); - return 0; fail: - os_free(pk); dpp_bootstrap_info_free(bi); return -1; } @@ -1517,7 +1477,7 @@ static int dpp_auth_build_resp_ok(struct dpp_authentication *auth) #endif /* CONFIG_TESTING_OPTIONS */ wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len); - crypto_ec_free_key(auth->own_protocol_key); + crypto_ec_key_deinit(auth->own_protocol_key); #ifdef CONFIG_TESTING_OPTIONS if (dpp_protocol_key_override_len) { const struct dpp_curve_params *tmp_curve; @@ -1973,7 +1933,7 @@ not_compatible: return auth; fail: bin_clear_free(unwrapped, unwrapped_len); - crypto_ec_free_key(pi); + crypto_ec_key_deinit(pi); dpp_auth_deinit(auth); return NULL; } @@ -2411,7 +2371,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, dpp_auth_fail(auth, "Failed to derive ECDH shared secret"); goto fail; } - crypto_ec_free_key(auth->peer_protocol_key); + crypto_ec_key_deinit(auth->peer_protocol_key); auth->peer_protocol_key = pr; pr = NULL; @@ -2581,7 +2541,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, fail: bin_clear_free(unwrapped, unwrapped_len); bin_clear_free(unwrapped2, unwrapped2_len); - crypto_ec_free_key(pr); + crypto_ec_key_deinit(pr); return NULL; } @@ -3135,8 +3095,8 @@ void dpp_auth_deinit(struct dpp_authentication *auth) dpp_configuration_free(auth->conf2_ap); dpp_configuration_free(auth->conf_sta); dpp_configuration_free(auth->conf2_sta); - crypto_ec_free_key(auth->own_protocol_key); - crypto_ec_free_key(auth->peer_protocol_key); + crypto_ec_key_deinit(auth->own_protocol_key); + crypto_ec_key_deinit(auth->peer_protocol_key); wpabuf_free(auth->req_msg); wpabuf_free(auth->resp_msg); wpabuf_free(auth->conf_req); @@ -3979,7 +3939,7 @@ static struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk, a = os_zalloc(len); os_memcpy(a, wpabuf_head(x), wpabuf_len(x)); os_memcpy(a + wpabuf_len(x), wpabuf_head(y), wpabuf_len(y)); - pkey = crypto_ec_set_pubkey_point(group, a, len); + pkey = crypto_ec_key_set_pub(group, a, len); crypto_ec_deinit((struct crypto_ec *)group); *key_curve = curve; @@ -4161,7 +4121,7 @@ skip_groups: ret = 0; fail: - crypto_ec_free_key(key); + crypto_ec_key_deinit(key); json_free(root); return ret; } @@ -4262,7 +4222,7 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth, ret = 0; fail: - crypto_ec_free_key(csign_pub); + crypto_ec_key_deinit(csign_pub); os_free(info.payload); return ret; } @@ -4582,7 +4542,7 @@ void dpp_configurator_free(struct dpp_configurator *conf) { if (!conf) return; - crypto_ec_free_key(conf->csign); + crypto_ec_key_deinit(conf->csign); os_free(conf->kid); os_free(conf); } @@ -4944,9 +4904,9 @@ fail: os_memset(intro, 0, sizeof(*intro)); forced_memzero(Nx, sizeof(Nx)); os_free(info.payload); - crypto_ec_free_key(own_key); + crypto_ec_key_deinit(own_key); wpabuf_free(own_key_pub); - crypto_ec_free_key(peer_key); + crypto_ec_key_deinit(peer_key); json_free(root); json_free(own_root); return ret; @@ -5024,11 +4984,10 @@ struct dpp_bootstrap_info * dpp_add_nfc_uri(struct dpp_global *dpp, int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd) { - char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL; + char *mac = NULL, *info = NULL, *curve = NULL; char *key = NULL; u8 *privkey = NULL; size_t privkey_len = 0; - size_t len; int ret = -1; struct dpp_bootstrap_info *bi; @@ -5048,7 +5007,7 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd) else goto fail; - chan = get_param(cmd, " chan="); + bi->chan = get_param(cmd, " chan="); mac = get_param(cmd, " mac="); info = get_param(cmd, " info="); curve = get_param(cmd, " curve="); @@ -5063,44 +5022,19 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd) } wpa_hexdump(MSG_DEBUG, "private key", privkey, privkey_len); - pk = dpp_keygen(bi, curve, privkey, privkey_len); - if (!pk) + if (dpp_keygen(bi, curve, privkey, privkey_len) < 0 || + dpp_parse_uri_chan_list(bi, bi->chan) < 0 || + dpp_parse_uri_mac(bi, mac) < 0 || + dpp_parse_uri_info(bi, info) < 0 || + dpp_gen_uri(bi) < 0) goto fail; - len = 4; /* "DPP:" */ - if (chan) { - if (dpp_parse_uri_chan_list(bi, chan) < 0) - goto fail; - len += 3 + os_strlen(chan); /* C:...; */ - } - if (mac) { - if (dpp_parse_uri_mac(bi, mac) < 0) - goto fail; - len += 3 + os_strlen(mac); /* M:...; */ - } - if (info) { - if (dpp_parse_uri_info(bi, info) < 0) - goto fail; - len += 3 + os_strlen(info); /* I:...; */ - } - len += 4 + os_strlen(pk); - bi->uri = os_malloc(len + 1); - if (!bi->uri) - goto fail; - os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;", - chan ? "C:" : "", chan ? chan : "", chan ? ";" : "", - mac ? "M:" : "", mac ? mac : "", mac ? ";" : "", - info ? "I:" : "", info ? info : "", info ? ";" : "", - pk); - bi->id = dpp_next_id(dpp); dl_list_add(&dpp->bootstrap, &bi->list); ret = bi->id; bi = NULL; fail: os_free(curve); - os_free(pk); - os_free(chan); os_free(mac); os_free(info); str_clear_free(key); diff --git a/components/wpa_supplicant/src/common/dpp.h b/components/wpa_supplicant/src/common/dpp.h index fcf80f2faa..84a9416ae9 100644 --- a/components/wpa_supplicant/src/common/dpp.h +++ b/components/wpa_supplicant/src/common/dpp.h @@ -160,7 +160,9 @@ struct dpp_bootstrap_info { enum dpp_bootstrap_type type; char *uri; u8 mac_addr[ETH_ALEN]; + char *chan; char *info; + char *pk; unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ]; unsigned int num_freq; int own; @@ -441,13 +443,10 @@ extern size_t dpp_nonce_override_len; void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info); const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type); -int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi); int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi, const char *chan_list); int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac); int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info); -char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, - u8 *privkey, size_t privkey_len); struct hostapd_hw_modes; struct dpp_authentication * dpp_auth_init(void *msg_ctx, struct dpp_bootstrap_info *peer_bi, @@ -595,64 +594,5 @@ void dpp_global_deinit(struct dpp_global *dpp); int dpp_connect(uint8_t *bssid, bool pdr_done); esp_err_t esp_dpp_start_net_intro_protocol(uint8_t *bssid); -/* dpp_crypto.c */ - -struct dpp_signed_connector_info { - unsigned char *payload; - size_t payload_len; -}; - -const struct dpp_curve_params *dpp_get_curve_name(const char *name); -const struct dpp_curve_params *dpp_get_curve_jwk_crv(const char *name); -const struct dpp_curve_params * dpp_get_curve_group_id(int group_id); -void dpp_debug_print_key(const char *title, struct crypto_ec_key *key); -int dpp_hash_vector(const struct dpp_curve_params *curve, - size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); -int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len, - const char *label, u8 *out, size_t outlen); -int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len, - size_t num_elem, const u8 *addr[], - const size_t *len, u8 *mac); -int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len, - const u8 *data, size_t data_len, u8 *mac); -struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key, - const u8 *buf, size_t len); -struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve); -struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve, - const u8 *privkey, size_t privkey_len); -int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi); -char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, - u8 *privkey, size_t privkey_len); -int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, - unsigned int hash_len); -int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, - unsigned int hash_len); -int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer, - u8 *secret, size_t *secret_len); -struct wpabuf *dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve, - const u8 *prot_hdr, u16 prot_hdr_len, int *hash_func); -int dpp_check_pubkey_match(struct crypto_ec_key *pub, struct wpabuf *r_hash); -enum dpp_status_error dpp_process_signed_connector(struct dpp_signed_connector_info *info, - struct crypto_ec_key *csign_pub, const char *connector); -int dpp_gen_r_auth(struct dpp_authentication *auth, u8 *r_auth); -int dpp_gen_i_auth(struct dpp_authentication *auth, u8 *i_auth); -int dpp_auth_derive_l_responder(struct dpp_authentication *auth); -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); -int dpp_bn2bin_pad(const struct crypto_bignum *bn, u8 *pos, size_t len); -struct wpabuf * dpp_bootstrap_key_der(struct crypto_ec_key *key); -struct wpabuf * dpp_get_pubkey_point(struct crypto_ec_key *pkey, int prefix); -int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi, const u8 *data, size_t data_len); -int dpp_derive_bk_ke(struct dpp_authentication *auth); -enum dpp_status_error -dpp_check_signed_connector(struct dpp_signed_connector_info *info, - const u8 *csign_key, size_t csign_key_len, - const u8 *peer_connector, size_t peer_connector_len); - -/* dpp crypto apis */ - #endif /* CONFIG_DPP */ #endif /* DPP_H */ diff --git a/components/wpa_supplicant/src/common/dpp_crypto.c b/components/wpa_supplicant/src/common/dpp_crypto.c index 67dd44be02..b95584e8e1 100644 --- a/components/wpa_supplicant/src/common/dpp_crypto.c +++ b/components/wpa_supplicant/src/common/dpp_crypto.c @@ -1,7 +1,7 @@ /* - * DPP functionality shared between hostapd and wpa_supplicant + * DPP crypto functionality shared between hostapd and wpa_supplicant * Copyright (c) 2017, Qualcomm Atheros, Inc. - * Copyright (c) 2018-2019, The Linux Foundation + * Copyright (c) 2018-2024, The Linux Foundation * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -20,24 +20,30 @@ #include "crypto/aes_siv.h" #include "crypto/sha256.h" #include "dpp.h" -#include "esp_dpp_i.h" +#include "dpp_i.h" const struct dpp_curve_params dpp_curves[] = { /* The mandatory to support and the default NIST P-256 curve needs to * be the first entry on this list. */ { "secp256r1", 32, 32, 16, 32, "P-256", 19, "ES256" }, +#ifndef ESP_SUPPLICANT { "secp384r1", 48, 48, 24, 48, "P-384", 20, "ES384" }, { "secp521r1", 64, 64, 32, 66, "P-521", 21, "ES512" }, { "brainpoolP256r1", 32, 32, 16, 32, "BP-256", 28, "BS256" }, { "brainpoolP384r1", 48, 48, 24, 48, "BP-384", 29, "BS384" }, { "brainpoolP512r1", 64, 64, 32, 64, "BP-512", 30, "BS512" }, +#endif { NULL, 0, 0, 0, 0, NULL, 0, NULL } }; -const struct dpp_curve_params *dpp_get_curve_name(const char *name) + +const struct dpp_curve_params * dpp_get_curve_name(const char *name) { int i; + if (!name) + return &dpp_curves[0]; + for (i = 0; dpp_curves[i].name; i++) { if (os_strcmp(name, dpp_curves[i].name) == 0 || (dpp_curves[i].jwk_crv && @@ -47,7 +53,8 @@ const struct dpp_curve_params *dpp_get_curve_name(const char *name) return NULL; } -const struct dpp_curve_params *dpp_get_curve_jwk_crv(const char *name) + +const struct dpp_curve_params * dpp_get_curve_jwk_crv(const char *name) { int i; @@ -56,29 +63,28 @@ const struct dpp_curve_params *dpp_get_curve_jwk_crv(const char *name) os_strcmp(name, dpp_curves[i].jwk_crv) == 0) return &dpp_curves[i]; } - return NULL; } -const struct dpp_curve_params * dpp_get_curve_group_id(int group_id) + +const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group) { - unsigned int i; + int i; - if (!group_id) - return NULL; - - for (i = 0; dpp_curves[i].ike_group; i++) { - if (group_id == dpp_curves[i].ike_group) + for (i = 0; dpp_curves[i].name; i++) { + if (dpp_curves[i].ike_group == group) return &dpp_curves[i]; } return NULL; } + void dpp_debug_print_key(const char *title, struct crypto_ec_key *key) { - crypto_ec_key_debug_print(title, key); + crypto_ec_key_debug_print(key, title); } + int dpp_hash_vector(const struct dpp_curve_params *curve, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) @@ -94,8 +100,9 @@ int dpp_hash_vector(const struct dpp_curve_params *curve, return -1; } + int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len, - const char *label, u8 *out, size_t outlen) + const char *label, u8 *out, size_t outlen) { if (hash_len == 32) return hmac_sha256_kdf(secret, secret_len, NULL, @@ -114,9 +121,10 @@ int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len, return -1; } + int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len, - size_t num_elem, const u8 *addr[], - const size_t *len, u8 *mac) + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac) { if (hash_len == 32) return hmac_sha256_vector(key, key_len, num_elem, addr, len, @@ -132,6 +140,7 @@ int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len, return -1; } + int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac) { @@ -147,7 +156,7 @@ int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len, } struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key, - const u8 *buf, size_t len) + const u8 *buf, size_t len) { const struct crypto_ec_group *group; struct crypto_ec_key *pkey = NULL; @@ -157,115 +166,116 @@ struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key, group = crypto_ec_get_group_from_key(group_key); if (group) - pkey = crypto_ec_set_pubkey_point(group, buf, - len); + pkey = crypto_ec_key_set_pub(group, buf, len); else wpa_printf(MSG_ERROR, "DPP: Could not get EC group"); return pkey; } + struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) { - struct crypto_ec_key *key = crypto_ec_key_gen(curve->ike_group); + struct crypto_ec_key *key; wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); - dpp_debug_print_key("Own generated key", key); + + key = crypto_ec_key_gen(curve->ike_group); + if (key) + dpp_debug_print_key("Own generated key", key); return key; } -struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve, - const u8 *privkey, size_t privkey_len) -{ - struct crypto_ec_group *group; - struct crypto_ec_key *pkey = crypto_ec_key_parse_priv(privkey, privkey_len); - int id; +struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve, + const u8 *privkey, size_t privkey_len) +{ + struct crypto_ec_key *pkey; + int group; + + pkey = crypto_ec_key_parse_priv(privkey, privkey_len); if (!pkey) { wpa_printf(MSG_ERROR, "%s: failed to get pkey", __func__); return NULL; } - group = crypto_ec_get_group_from_key(pkey); - if (!group) { - crypto_ec_free_key(pkey); + + group = crypto_ec_key_group(pkey); + if (group < 0) { + crypto_ec_key_deinit(pkey); return NULL; } - id = crypto_ec_get_curve_id(group); - *curve = dpp_get_curve_group_id(id); + + *curve = dpp_get_curve_ike_group(group); if (!*curve) { wpa_printf(MSG_INFO, - "DPP: Unsupported curve (id=%d) in pre-assigned key", - id); - crypto_ec_free_key(pkey); + "DPP: Unsupported curve (group=%d) in pre-assigned key", + group); + crypto_ec_key_deinit(pkey); return NULL; } return pkey; } -struct wpabuf * dpp_bootstrap_key_der(struct crypto_ec_key *key) +int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi, + const u8 *data, size_t data_len) { - unsigned char *der = NULL; - struct wpabuf *ret = NULL; - int der_len; + const u8 *addr[2]; + size_t len[2]; - der_len = crypto_ec_write_pub_key(key, &der); - if (!der) { - printf("failed to get der for bootstrapping key\n"); - return NULL; - } - ret = wpabuf_alloc_copy(der, der_len); - - os_free(der); - return ret; + addr[0] = data; + len[0] = data_len; + if (sha256_vector(1, addr, len, bi->pubkey_hash) < 0) + return -1; + wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", + bi->pubkey_hash, SHA256_MAC_LEN); +#ifndef ESP_SUPPLICANT + addr[0] = (const u8 *) "chirp"; + len[0] = 5; + addr[1] = data; + len[1] = data_len; + if (sha256_vector(2, addr, len, bi->pubkey_hash_chirp) < 0) + return -1; + wpa_hexdump(MSG_DEBUG, "DPP: Public key hash (chirp)", + bi->pubkey_hash_chirp, SHA256_MAC_LEN); +#endif //ESP_SUPPLICANT + return 0; } + int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi) { struct wpabuf *der; int res; - const u8 *addr[1]; - size_t len[1]; - der = dpp_bootstrap_key_der(bi->pubkey); + der = crypto_ec_key_get_subject_public_key(bi->pubkey); if (!der) return -1; wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)", der); - - addr[0] = wpabuf_head(der); - len[0] = wpabuf_len(der); - res = sha256_vector(1, addr, len, bi->pubkey_hash); + res = dpp_bi_pubkey_hash(bi, wpabuf_head(der), wpabuf_len(der)); if (res < 0) wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key"); - else - wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", bi->pubkey_hash, - SHA256_MAC_LEN); wpabuf_free(der); return res; } -char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, + +int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, u8 *privkey, size_t privkey_len) { char *base64 = NULL; char *pos, *end; size_t len; struct wpabuf *der = NULL; - const u8 *addr[1]; - int res; - if (!curve) { - bi->curve = &dpp_curves[0]; - } else { - bi->curve = dpp_get_curve_name(curve); - if (!bi->curve) { - wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s", - curve); - return NULL; - } + bi->curve = dpp_get_curve_name(curve); + if (!bi->curve) { + wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s", curve); + return -1; } + if (privkey) bi->pubkey = dpp_set_keypair(&bi->curve, privkey, privkey_len); else @@ -274,21 +284,16 @@ char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, goto fail; bi->own = 1; - der = dpp_bootstrap_key_der(bi->pubkey); + der = crypto_ec_key_get_subject_public_key(bi->pubkey); if (!der) goto fail; wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)", der); - addr[0] = wpabuf_head(der); - len = wpabuf_len(der); - res = sha256_vector(1, addr, &len, bi->pubkey_hash); - if (res < 0) { + if (dpp_bi_pubkey_hash(bi, wpabuf_head(der), wpabuf_len(der)) < 0) { wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key"); goto fail; } - wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", bi->pubkey_hash, - SHA256_MAC_LEN); base64 = (char *)base64_encode(wpabuf_head(der), wpabuf_len(der), &len); wpabuf_free(der); @@ -303,15 +308,17 @@ char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, break; os_memmove(pos, pos + 1, end - pos); } - return base64; + os_free(bi->pk); + bi->pk = base64; + return 0; fail: os_free(base64); wpabuf_free(der); - return NULL; + return -1; } -int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, - unsigned int hash_len) + +int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, unsigned int hash_len) { u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN]; const char *info = "first intermediate key"; @@ -337,8 +344,8 @@ int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, return 0; } -int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, - unsigned int hash_len) + +int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, unsigned int hash_len) { u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN]; const char *info = "second intermediate key"; @@ -366,14 +373,16 @@ int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, } int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer, - u8 *secret, size_t *secret_len) + u8 *secret, size_t *secret_len) { return crypto_ecdh(own, peer, secret, secret_len); } + struct wpabuf * dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve, - const u8 *prot_hdr, u16 prot_hdr_len, int *hash_func) + const u8 *prot_hdr, u16 prot_hdr_len, + int *hash_func) { struct json_token *root, *token; struct wpabuf *kid = NULL; @@ -418,13 +427,22 @@ dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve, token->string, curve->jws_alg); goto fail; } - if (os_strcmp(token->string, "ES256") == 0 || os_strcmp(token->string, "BS256") == 0) { *hash_func = CRYPTO_HASH_ALG_SHA256; +#ifndef ESP_SUPPLICANT + } else if (os_strcmp(token->string, "ES384") == 0 || + os_strcmp(token->string, "BS384") == 0) { + *hash_func = CRYPTO_HASH_ALG_SHA384; + } else if (os_strcmp(token->string, "ES512") == 0 || + os_strcmp(token->string, "BS512") == 0) { + *hash_func = CRYPTO_HASH_ALG_SHA512; +#endif // ESP_SUPPLICANT } else { *hash_func = -1; - wpa_printf(MSG_ERROR, "Unsupported JWS Protected Header alg=%s", token->string); + wpa_printf(MSG_ERROR, "DPP : Unsupported JWS Protected Header alg=%s", + token->string); + goto fail; } kid = json_get_member_base64url(root, "kid"); @@ -440,41 +458,20 @@ fail: return kid; } -int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi, const u8 *data, size_t data_len) + +int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi, + const u8 *data, size_t data_len) { struct crypto_ec_key *pkey; const unsigned char *p; - struct crypto_ec_group *group; - int id; - if (sha256_vector(1, (const u8 **) &data, &data_len, - bi->pubkey_hash) < 0) { + if (dpp_bi_pubkey_hash(bi, data, data_len) < 0) { wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key"); return -1; } - wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", - bi->pubkey_hash, SHA256_MAC_LEN); - - /* DER encoded ASN.1 SubjectPublicKeyInfo - * - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - * - * subjectPublicKey = compressed format public key per ANSI X9.63 - * algorithm = ecPublicKey (1.2.840.10045.2.1) - * parameters = shall be present and shall be OBJECT IDENTIFIER; e.g., - * prime256v1 (1.2.840.10045.3.1.7) - */ p = data; - pkey = crypto_ec_parse_subpub_key((unsigned char *)p, data_len); - if (!pkey) { wpa_printf(MSG_DEBUG, "DPP: Could not parse URI public-key SubjectPublicKeyInfo"); @@ -484,32 +481,29 @@ int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi, const u8 *data, si if (!crypto_is_ec_key(pkey)) { wpa_printf(MSG_DEBUG, "DPP: SubjectPublicKeyInfo does not describe an EC key"); - crypto_ec_free_key(pkey); + crypto_ec_key_deinit(pkey); return -1; } - group = crypto_ec_get_group_from_key(pkey); - if (!group) { - return -1; - } - id = crypto_ec_get_curve_id(group); - bi->curve = dpp_get_curve_group_id(id); + bi->curve = dpp_get_curve_ike_group(crypto_ec_key_group(pkey)); if (!bi->curve) { wpa_printf(MSG_DEBUG, - "DPP: Unsupported SubjectPublicKeyInfo curve"); + "DPP: Unsupported SubjectPublicKeyInfo curve: group %d", + crypto_ec_key_group(pkey)); goto fail; } bi->pubkey = pkey; return 0; fail: - crypto_ec_free_key(pkey); + crypto_ec_key_deinit(pkey); return -1; } int dpp_derive_bk_ke(struct dpp_authentication *auth) { + unsigned int hash_len = auth->curve->hash_len; size_t nonce_len = auth->curve->nonce_len; u8 nonces[2 * DPP_MAX_NONCE_LEN]; const char *info_ke = "DPP Key"; @@ -518,7 +512,6 @@ int dpp_derive_bk_ke(struct dpp_authentication *auth) const u8 *addr[3]; size_t len[3]; size_t num_elem = 0; - unsigned int hash_len = auth->curve->hash_len; if (!auth->Mx_len || !auth->Nx_len) { wpa_printf(MSG_DEBUG, @@ -637,24 +630,19 @@ int dpp_check_pubkey_match(struct crypto_ec_key *pub, struct wpabuf *r_hash) enum dpp_status_error dpp_process_signed_connector(struct dpp_signed_connector_info *info, - struct crypto_ec_key *csign_pub, const char *connector) + struct crypto_ec_key *csign_pub, + const char *connector) { enum dpp_status_error ret = 255; const char *pos, *end, *signed_start, *signed_end; struct wpabuf *kid = NULL; unsigned char *prot_hdr = NULL, *signature = NULL; size_t prot_hdr_len = 0, signature_len = 0, signed_len; - struct crypto_bignum *r = NULL, *s = NULL; const struct dpp_curve_params *curve; - const struct crypto_ec_group *group; - int id, hash_func = -1; + int res, hash_func = -1; u8 *hash = NULL; - group = crypto_ec_get_group_from_key(csign_pub); - if (!group) - goto fail; - id = crypto_ec_get_curve_id(group); - curve = dpp_get_curve_group_id(id); + curve = dpp_get_curve_ike_group(crypto_ec_key_group(csign_pub)); if (!curve) goto fail; wpa_printf(MSG_DEBUG, "DPP: C-sign-key group: %s", curve->jwk_crv); @@ -713,7 +701,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info, signature = base64_url_decode(pos, os_strlen(pos), &signature_len); if (!signature) { wpa_printf(MSG_DEBUG, - "DPP: Failed to base64url decode signedConnector signature"); + "DPP: Failed to base64url decode signedConnector signature"); ret = DPP_STATUS_INVALID_CONNECTOR; goto fail; } @@ -733,11 +721,6 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info, goto fail; } - /* JWS Signature encodes the signature (r,s) as two octet strings. Need - * to convert that to DER encoded ECDSA_SIG for OpenSSL EVP routines. */ - r = crypto_bignum_init_set(signature, signature_len / 2); - s = crypto_bignum_init_set(signature + signature_len / 2, signature_len / 2); - signed_len = signed_end - signed_start + 1; hash = os_malloc(curve->hash_len); if (!hash) { @@ -753,8 +736,16 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info, goto fail; } - if ((crypto_edcsa_sign_verify((unsigned char *)hash, r, s, - csign_pub, curve->hash_len)) != 0) { + res = crypto_ec_key_verify_signature_r_s(csign_pub, + (unsigned char *)hash, curve->hash_len, + signature, signature_len / 2, + signature + signature_len / 2, + signature_len / 2); + if (res != 0) { + wpa_printf(MSG_DEBUG, + "DPP: signedConnector signature check failed (res=%d)", + res); + ret = DPP_STATUS_INVALID_CONNECTOR; goto fail; } @@ -766,8 +757,6 @@ fail: os_free(prot_hdr); wpabuf_free(kid); os_free(signature); - crypto_bignum_deinit(r, 0); - crypto_bignum_deinit(s, 0); return ret; } @@ -799,11 +788,12 @@ dpp_check_signed_connector(struct dpp_signed_connector_info *info, res = dpp_process_signed_connector(info, csign, signed_connector); fail: os_free(signed_connector); - crypto_ec_free_key(csign); + crypto_ec_key_deinit(csign); return res; } + int dpp_gen_r_auth(struct dpp_authentication *auth, u8 *r_auth) { struct wpabuf *pix, *prx, *bix, *brx; @@ -882,6 +872,7 @@ fail: return res; } + int dpp_gen_i_auth(struct dpp_authentication *auth, u8 *i_auth) { struct wpabuf *pix = NULL, *prx = NULL, *bix = NULL, *brx = NULL; @@ -975,10 +966,10 @@ int dpp_bn2bin_pad(const struct crypto_bignum *bn, u8 *pos, size_t len) int dpp_auth_derive_l_responder(struct dpp_authentication *auth) { struct crypto_ec_group *group; - struct crypto_ec_point *l = NULL; - struct crypto_ec_point *BI_point; + struct crypto_ec_point *L = NULL; + struct crypto_ec_point *BI; struct crypto_bignum *lx, *sum, *q; - struct crypto_bignum *bR_bn, *pR_bn; + struct crypto_bignum *bR, *pR; int ret = -1; /* L = ((bR + pR) modulo q) * BI */ @@ -989,21 +980,21 @@ int dpp_auth_derive_l_responder(struct dpp_authentication *auth) if (!sum || !q || !lx) goto fail; - BI_point = crypto_ec_key_get_public_key(auth->peer_bi->pubkey); + BI = crypto_ec_key_get_public_key(auth->peer_bi->pubkey); group = crypto_ec_get_group_from_key(auth->peer_bi->pubkey); - bR_bn = crypto_ec_key_get_private_key(auth->own_bi->pubkey); - pR_bn = crypto_ec_key_get_private_key(auth->own_protocol_key); + bR = crypto_ec_key_get_private_key(auth->own_bi->pubkey); + pR = crypto_ec_key_get_private_key(auth->own_protocol_key); - if (!bR_bn || !pR_bn) + if (!bR || !pR) goto fail; if ((crypto_get_order(group, q) != 0) || - (crypto_bignum_addmod(sum, bR_bn, pR_bn, q) != 0)) + (crypto_bignum_addmod(sum, bR, pR, q) != 0)) goto fail; - l = crypto_ec_point_init((struct crypto_ec *)group); - if (!l || (crypto_ec_point_mul((struct crypto_ec *)group, BI_point, sum, l) != 0) || - (crypto_ec_get_affine_coordinates((struct crypto_ec *)group, l, lx, NULL) != 0)) { + L = crypto_ec_point_init((struct crypto_ec *)group); + if (!L || (crypto_ec_point_mul((struct crypto_ec *)group, BI, sum, L) != 0) || + (crypto_ec_get_affine_coordinates((struct crypto_ec *)group, L, lx, NULL) != 0)) { wpa_printf(MSG_ERROR, "OpenSSL: failed: %s", __func__); goto fail; @@ -1014,7 +1005,7 @@ int dpp_auth_derive_l_responder(struct dpp_authentication *auth) auth->Lx_len = auth->secret_len; ret = 0; fail: - crypto_ec_point_deinit(l, 1); + crypto_ec_point_deinit(L, 1); crypto_bignum_deinit(lx, 0); crypto_bignum_deinit(sum, 0); crypto_bignum_deinit(q, 0); @@ -1022,10 +1013,11 @@ fail: return ret; } + int dpp_auth_derive_l_initiator(struct dpp_authentication *auth) { struct crypto_ec_group *group; - struct crypto_ec_point *l = NULL, *sum = NULL; + struct crypto_ec_point *L = NULL, *sum = NULL; struct crypto_ec_point *BR_point, *PR_point; struct crypto_bignum *lx; struct crypto_bignum *bI_bn; @@ -1044,11 +1036,11 @@ int dpp_auth_derive_l_initiator(struct dpp_authentication *auth) if (!group || !bI_bn) goto fail; sum = crypto_ec_point_init((struct crypto_ec *)group); - l = crypto_ec_point_init((struct crypto_ec *)group); - if (!sum || !l || + L = crypto_ec_point_init((struct crypto_ec *)group); + if (!sum || !L || crypto_ec_point_add((struct crypto_ec *)group, BR_point, PR_point, sum) != 0 || - crypto_ec_point_mul((struct crypto_ec *)group, sum, bI_bn, l) != 0 || - crypto_ec_get_affine_coordinates((struct crypto_ec *)group, l, lx, NULL) != 0) { + crypto_ec_point_mul((struct crypto_ec *)group, sum, bI_bn, L) != 0 || + crypto_ec_get_affine_coordinates((struct crypto_ec *)group, L, lx, NULL) != 0) { wpa_printf(MSG_ERROR, "OpenSSL: failed: %s", __func__); goto fail; @@ -1060,7 +1052,7 @@ int dpp_auth_derive_l_initiator(struct dpp_authentication *auth) auth->Lx_len = auth->secret_len; ret = 0; fail: - crypto_ec_point_deinit(l, 1); + crypto_ec_point_deinit(L, 1); crypto_ec_point_deinit(sum, 1); crypto_bignum_deinit(lx, 0); @@ -1068,8 +1060,8 @@ fail: return ret; } -int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, - unsigned int hash_len) + +int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, unsigned int hash_len) { u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN]; const char *info = "DPP PMK"; @@ -1095,8 +1087,10 @@ int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, return 0; } + int dpp_derive_pmkid(const struct dpp_curve_params *curve, - struct crypto_ec_key *own_key, struct crypto_ec_key *peer_key, u8 *pmkid) + struct crypto_ec_key *own_key, + struct crypto_ec_key *peer_key, u8 *pmkid) { struct wpabuf *nkx, *pkx; int ret = -1, res; @@ -1136,7 +1130,7 @@ fail: #ifdef CONFIG_TESTING_OPTIONS int dpp_test_gen_invalid_key(struct wpabuf *msg, - const struct dpp_curve_params *curve) + const struct dpp_curve_params *curve) { return 0; } diff --git a/components/wpa_supplicant/src/common/dpp_i.h b/components/wpa_supplicant/src/common/dpp_i.h new file mode 100644 index 0000000000..fc0d4acedb --- /dev/null +++ b/components/wpa_supplicant/src/common/dpp_i.h @@ -0,0 +1,79 @@ +/* + * DPP module internal definitions + * Copyright (c) 2017, Qualcomm Atheros, Inc. + * Copyright (c) 2018-2020, The Linux Foundation + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef ESP_DPP_I_H +#define ESP_DPP_I_H + +#include "esp_err.h" +#include "utils/includes.h" +#include "utils/common.h" +#include "common/dpp.h" +#include "esp_dpp.h" +#include "esp_wifi_driver.h" + +/* dpp_crypto.c */ + +struct dpp_signed_connector_info { + unsigned char *payload; + size_t payload_len; +}; + +const struct dpp_curve_params *dpp_get_curve_name(const char *name); +const struct dpp_curve_params *dpp_get_curve_jwk_crv(const char *name); +void dpp_debug_print_key(const char *title, struct crypto_ec_key *key); +int dpp_hash_vector(const struct dpp_curve_params *curve, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); +int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len, + const char *label, u8 *out, size_t outlen); +int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac); +int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mac); +struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key, + const u8 *buf, size_t len); +struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve); +struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve, + const u8 *privkey, size_t privkey_len); +int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi); +int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, + u8 *privkey, size_t privkey_len); +int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, + unsigned int hash_len); +int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, + unsigned int hash_len); +int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer, + u8 *secret, size_t *secret_len); +struct wpabuf *dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve, + const u8 *prot_hdr, u16 prot_hdr_len, int *hash_func); +int dpp_check_pubkey_match(struct crypto_ec_key *pub, struct wpabuf *r_hash); +enum dpp_status_error dpp_process_signed_connector(struct dpp_signed_connector_info *info, + struct crypto_ec_key *csign_pub, const char *connector); +int dpp_gen_r_auth(struct dpp_authentication *auth, u8 *r_auth); +int dpp_gen_i_auth(struct dpp_authentication *auth, u8 *i_auth); +int dpp_auth_derive_l_responder(struct dpp_authentication *auth); +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); +int dpp_bn2bin_pad(const struct crypto_bignum *bn, u8 *pos, size_t len); +struct wpabuf * dpp_bootstrap_key_der(struct crypto_ec_key *key); +struct wpabuf * dpp_get_pubkey_point(struct crypto_ec_key *pkey, int prefix); +int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi, const u8 *data, size_t data_len); +int dpp_derive_bk_ke(struct dpp_authentication *auth); +enum dpp_status_error +dpp_check_signed_connector(struct dpp_signed_connector_info *info, + const u8 *csign_key, size_t csign_key_len, + const u8 *peer_connector, size_t peer_connector_len); + +/* dpp crypto apis */ + +#endif /* ESP_DPP_I_H */ diff --git a/components/wpa_supplicant/src/crypto/crypto.h b/components/wpa_supplicant/src/crypto/crypto.h index f665e21713..183cbf590f 100644 --- a/components/wpa_supplicant/src/crypto/crypto.h +++ b/components/wpa_supplicant/src/crypto/crypto.h @@ -1005,16 +1005,20 @@ int crypto_ecdsa_get_sign(unsigned char *hash, struct crypto_ec_key *csign, int hash_len); /** - * crypto_edcsa_sign_verify: verify crypto ecdsa signed hash + * crypto_ec_key_verify_signature_r_s: verify ec key signature + * @csign: csign * @hash: signed hash + * @hlen: length of hash * @r: ecdsa r * @s: ecdsa s - * @csign: csign - * @hlen: length of hash + * @r_len: Length of @r buffer + * @s_len: Length of @s buffer * Return: 0 if success else negative value */ -int crypto_edcsa_sign_verify(const unsigned char *hash, const struct crypto_bignum *r, - const struct crypto_bignum *s, struct crypto_ec_key *csign, int hlen); +int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, + const unsigned char *hash, int hlen, + const u8 *r, size_t r_len, + const u8 *s, size_t s_len); /** * crypto_ec_parse_subpub_key: get EC key context from sub public key @@ -1047,26 +1051,28 @@ struct crypto_ec_key * crypto_ec_key_gen(u16 ike_group); int crypto_ec_write_pub_key(struct crypto_ec_key *key, unsigned char **key_buf); /** - * crypto_ec_set_pubkey_point: set bignum point on ec curve + * crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for an EC key + * @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen() + * Returns: Buffer with DER encoding of ASN.1 SubjectPublicKeyInfo or %NULL on failure + */ +struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key); + +/** + * crypto_ec_key_set_pub: set bignum point on ec curve * @group: ec group * @buf: x,y coordinate * @len: length of x and y coordinate - * Return : crypto key + * Return : crypto key or NULL on failure */ -struct crypto_ec_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *group, +struct crypto_ec_key * crypto_ec_key_set_pub(const struct crypto_ec_group *group, const u8 *buf, size_t len); -/** - * crypto_ec_free_key: free crypto key - * Return : None - */ -void crypto_ec_free_key(struct crypto_ec_key *key); /** * crypto_ec_key_debug_print: print ec key - * @title: title * @key: crypto key + * @title: title * Return: None */ -void crypto_ec_key_debug_print(const char *title, struct crypto_ec_key *key); +void crypto_ec_key_debug_print(struct crypto_ec_key *key, const char *title); /** * crypto_ec_key_get_public_key: Public key from crypto key