feat(esp_wifi): Add esp-idf specific changes

Added esp-idf implementation specific changes on top of the upstream updates.
This commit is contained in:
aditi
2024-07-26 16:41:56 +05:30
committed by BOT
parent fbde07c953
commit beda284524
7 changed files with 358 additions and 388 deletions

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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