DPP: Move Authentication Response building into a separate function
This cleans up old dpp_auth_build_resp() (now dpp_auth_build_resp_ok()) a bit by separating initialization steps for a DPP authentication session from the code needed to build the frame. This allows dpp_auth_build_resp_status() to share the helper function instead of having to maintain a duplicated message construction implementation. In addition, this makes it easier to remove some of the attributes for protocol testing purposes. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
0e7cb8c6c1
commit
a03406dbe2
1 changed files with 183 additions and 229 deletions
414
src/common/dpp.c
414
src/common/dpp.c
|
@ -1479,6 +1479,159 @@ skip_wrapped_data:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
|
||||||
|
enum dpp_status_error status,
|
||||||
|
const struct wpabuf *pr,
|
||||||
|
size_t nonce_len,
|
||||||
|
const u8 *r_pubkey_hash,
|
||||||
|
const u8 *i_pubkey_hash,
|
||||||
|
const u8 *r_nonce, const u8 *i_nonce,
|
||||||
|
const u8 *wrapped_r_auth,
|
||||||
|
size_t wrapped_r_auth_len,
|
||||||
|
const u8 *siv_key)
|
||||||
|
{
|
||||||
|
struct wpabuf *msg;
|
||||||
|
#define DPP_AUTH_RESP_CLEAR_LEN 2 * (4 + DPP_MAX_NONCE_LEN) + 4 + 1 + \
|
||||||
|
4 + 4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE
|
||||||
|
u8 clear[DPP_AUTH_RESP_CLEAR_LEN];
|
||||||
|
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE];
|
||||||
|
const u8 *addr[2];
|
||||||
|
size_t len[2], siv_len, attr_len;
|
||||||
|
u8 *attr_start, *attr_end, *pos;
|
||||||
|
|
||||||
|
/* Build DPP Authentication Response frame attributes */
|
||||||
|
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
||||||
|
4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data);
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
|
||||||
|
attr_len += 4;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
|
||||||
|
if (!msg)
|
||||||
|
return NULL;
|
||||||
|
wpabuf_free(auth->resp_msg);
|
||||||
|
|
||||||
|
attr_start = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
|
/* DPP Status */
|
||||||
|
if (status >= 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: Status %d", status);
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
||||||
|
wpabuf_put_le16(msg, 1);
|
||||||
|
wpabuf_put_u8(msg, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responder Bootstrapping Key Hash */
|
||||||
|
if (r_pubkey_hash) {
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
|
||||||
|
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
||||||
|
wpabuf_put_data(msg, r_pubkey_hash, SHA256_MAC_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initiator Bootstrapping Key Hash */
|
||||||
|
if (i_pubkey_hash) {
|
||||||
|
/* Mutual authentication */
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
|
||||||
|
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
||||||
|
wpabuf_put_data(msg, i_pubkey_hash, SHA256_MAC_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responder Protocol Key */
|
||||||
|
if (pr) {
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY);
|
||||||
|
wpabuf_put_le16(msg, wpabuf_len(pr));
|
||||||
|
wpabuf_put_buf(msg, pr);
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_end = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
|
/* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
|
||||||
|
pos = clear;
|
||||||
|
|
||||||
|
if (r_nonce) {
|
||||||
|
/* R-nonce */
|
||||||
|
WPA_PUT_LE16(pos, DPP_ATTR_R_NONCE);
|
||||||
|
pos += 2;
|
||||||
|
WPA_PUT_LE16(pos, nonce_len);
|
||||||
|
pos += 2;
|
||||||
|
os_memcpy(pos, r_nonce, nonce_len);
|
||||||
|
pos += nonce_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i_nonce) {
|
||||||
|
/* I-nonce */
|
||||||
|
WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
|
||||||
|
pos += 2;
|
||||||
|
WPA_PUT_LE16(pos, nonce_len);
|
||||||
|
pos += 2;
|
||||||
|
os_memcpy(pos, i_nonce, nonce_len);
|
||||||
|
pos += nonce_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* R-capabilities */
|
||||||
|
WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES);
|
||||||
|
pos += 2;
|
||||||
|
WPA_PUT_LE16(pos, 1);
|
||||||
|
pos += 2;
|
||||||
|
auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
|
||||||
|
DPP_CAPAB_ENROLLEE;
|
||||||
|
*pos++ = auth->r_capab;
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
|
||||||
|
wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
|
||||||
|
pos[-1] = 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
if (wrapped_r_auth) {
|
||||||
|
/* {R-auth}ke */
|
||||||
|
WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA);
|
||||||
|
pos += 2;
|
||||||
|
WPA_PUT_LE16(pos, wrapped_r_auth_len);
|
||||||
|
pos += 2;
|
||||||
|
os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
|
||||||
|
pos += wrapped_r_auth_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
||||||
|
addr[0] = wpabuf_head_u8(msg) + 2;
|
||||||
|
len[0] = 3 + 1 + 1 + 1;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
|
||||||
|
/* Attributes before Wrapped Data */
|
||||||
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_end - attr_start;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
|
|
||||||
|
siv_len = pos - clear;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
||||||
|
if (aes_siv_encrypt(siv_key, auth->curve->hash_len, clear, siv_len,
|
||||||
|
2, addr, len, wrapped_data) < 0) {
|
||||||
|
wpabuf_free(msg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
siv_len += AES_BLOCK_SIZE;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
|
wrapped_data, siv_len);
|
||||||
|
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
||||||
|
wpabuf_put_le16(msg, siv_len);
|
||||||
|
wpabuf_put_data(msg, wrapped_data, siv_len);
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
|
||||||
|
wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_TESTING);
|
||||||
|
wpabuf_put_le16(msg, 0);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
wpa_hexdump_buf(MSG_DEBUG,
|
||||||
|
"DPP: Authentication Response frame attributes", msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dpp_authentication * dpp_auth_init(void *msg_ctx,
|
struct dpp_authentication * dpp_auth_init(void *msg_ctx,
|
||||||
struct dpp_bootstrap_info *peer_bi,
|
struct dpp_bootstrap_info *peer_bi,
|
||||||
struct dpp_bootstrap_info *own_bi,
|
struct dpp_bootstrap_info *own_bi,
|
||||||
|
@ -1974,7 +2127,7 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
static int dpp_auth_build_resp_ok(struct dpp_authentication *auth)
|
||||||
{
|
{
|
||||||
size_t nonce_len;
|
size_t nonce_len;
|
||||||
EVP_PKEY_CTX *ctx = NULL;
|
EVP_PKEY_CTX *ctx = NULL;
|
||||||
|
@ -1982,15 +2135,9 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
||||||
struct wpabuf *msg, *pr = NULL;
|
struct wpabuf *msg, *pr = NULL;
|
||||||
u8 r_auth[4 + DPP_MAX_HASH_LEN];
|
u8 r_auth[4 + DPP_MAX_HASH_LEN];
|
||||||
u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE];
|
u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE];
|
||||||
#define DPP_AUTH_RESP_CLEAR_LEN 2 * (4 + DPP_MAX_NONCE_LEN) + 4 + 1 + \
|
|
||||||
4 + sizeof(wrapped_r_auth)
|
|
||||||
size_t wrapped_r_auth_len;
|
size_t wrapped_r_auth_len;
|
||||||
u8 clear[DPP_AUTH_RESP_CLEAR_LEN];
|
int ret = -1;
|
||||||
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE];
|
const u8 *r_pubkey_hash, *i_pubkey_hash;
|
||||||
u8 *pos;
|
|
||||||
const u8 *addr[2];
|
|
||||||
size_t len[2], siv_len, attr_len;
|
|
||||||
u8 *attr_start, *attr_end;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
||||||
|
|
||||||
|
@ -2053,242 +2200,49 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: {R-auth}ke",
|
wpa_hexdump(MSG_DEBUG, "DPP: {R-auth}ke",
|
||||||
wrapped_r_auth, wrapped_r_auth_len);
|
wrapped_r_auth, wrapped_r_auth_len);
|
||||||
|
|
||||||
/* Build DPP Authentication Response frame attributes */
|
r_pubkey_hash = auth->own_bi->pubkey_hash;
|
||||||
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
if (auth->peer_bi)
|
||||||
4 + wpabuf_len(pr) + 4 + sizeof(wrapped_data);
|
i_pubkey_hash = auth->peer_bi->pubkey_hash;
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
else
|
||||||
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
|
i_pubkey_hash = NULL;
|
||||||
attr_len += 4;
|
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
msg = dpp_auth_build_resp(auth, DPP_STATUS_OK, pr, nonce_len,
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
|
r_pubkey_hash, i_pubkey_hash,
|
||||||
|
auth->r_nonce, auth->i_nonce,
|
||||||
|
wrapped_r_auth, wrapped_r_auth_len,
|
||||||
|
auth->k2);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto fail;
|
goto fail;
|
||||||
wpabuf_free(auth->resp_msg);
|
|
||||||
auth->resp_msg = msg;
|
auth->resp_msg = msg;
|
||||||
|
ret = 0;
|
||||||
attr_start = wpabuf_put(msg, 0);
|
|
||||||
|
|
||||||
/* DPP Status */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
|
||||||
wpabuf_put_le16(msg, 1);
|
|
||||||
wpabuf_put_u8(msg, DPP_STATUS_OK);
|
|
||||||
|
|
||||||
/* Responder Bootstrapping Key Hash */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
|
|
||||||
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
|
||||||
wpabuf_put_data(msg, auth->own_bi->pubkey_hash, SHA256_MAC_LEN);
|
|
||||||
|
|
||||||
if (auth->peer_bi) {
|
|
||||||
/* Mutual authentication */
|
|
||||||
/* Initiator Bootstrapping Key Hash */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
|
|
||||||
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
|
||||||
wpabuf_put_data(msg, auth->peer_bi->pubkey_hash,
|
|
||||||
SHA256_MAC_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responder Protocol Key */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY);
|
|
||||||
wpabuf_put_le16(msg, wpabuf_len(pr));
|
|
||||||
wpabuf_put_buf(msg, pr);
|
|
||||||
wpabuf_free(pr);
|
|
||||||
pr = NULL;
|
|
||||||
|
|
||||||
attr_end = wpabuf_put(msg, 0);
|
|
||||||
|
|
||||||
/* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
|
|
||||||
pos = clear;
|
|
||||||
/* R-nonce */
|
|
||||||
WPA_PUT_LE16(pos, DPP_ATTR_R_NONCE);
|
|
||||||
pos += 2;
|
|
||||||
WPA_PUT_LE16(pos, nonce_len);
|
|
||||||
pos += 2;
|
|
||||||
os_memcpy(pos, auth->r_nonce, nonce_len);
|
|
||||||
pos += nonce_len;
|
|
||||||
/* I-nonce */
|
|
||||||
WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
|
|
||||||
pos += 2;
|
|
||||||
WPA_PUT_LE16(pos, nonce_len);
|
|
||||||
pos += 2;
|
|
||||||
os_memcpy(pos, auth->i_nonce, nonce_len);
|
|
||||||
pos += nonce_len;
|
|
||||||
/* R-capabilities */
|
|
||||||
WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES);
|
|
||||||
pos += 2;
|
|
||||||
WPA_PUT_LE16(pos, 1);
|
|
||||||
pos += 2;
|
|
||||||
auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
|
|
||||||
DPP_CAPAB_ENROLLEE;
|
|
||||||
*pos++ = auth->r_capab;
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
|
||||||
if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
|
|
||||||
wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
|
|
||||||
pos[-1] = 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
|
||||||
/* {R-auth}ke */
|
|
||||||
WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA);
|
|
||||||
pos += 2;
|
|
||||||
WPA_PUT_LE16(pos, wrapped_r_auth_len);
|
|
||||||
pos += 2;
|
|
||||||
os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
|
|
||||||
pos += wrapped_r_auth_len;
|
|
||||||
|
|
||||||
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
|
||||||
addr[0] = wpabuf_head_u8(msg) + 2;
|
|
||||||
len[0] = 3 + 1 + 1 + 1;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
|
||||||
|
|
||||||
/* Attributes before Wrapped Data */
|
|
||||||
addr[1] = attr_start;
|
|
||||||
len[1] = attr_end - attr_start;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
|
||||||
|
|
||||||
siv_len = pos - clear;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
|
||||||
if (aes_siv_encrypt(auth->k2, auth->curve->hash_len, clear, siv_len,
|
|
||||||
2, addr, len, wrapped_data) < 0)
|
|
||||||
goto fail;
|
|
||||||
siv_len += AES_BLOCK_SIZE;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
|
||||||
wrapped_data, siv_len);
|
|
||||||
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
|
||||||
wpabuf_put_le16(msg, siv_len);
|
|
||||||
wpabuf_put_data(msg, wrapped_data, siv_len);
|
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
|
||||||
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
|
|
||||||
wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_TESTING);
|
|
||||||
wpabuf_put_le16(msg, 0);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
|
||||||
|
|
||||||
wpa_hexdump_buf(MSG_DEBUG,
|
|
||||||
"DPP: Authentication Response frame attributes", msg);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
wpabuf_free(pr);
|
wpabuf_free(pr);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
|
static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
|
||||||
enum dpp_status_error status)
|
enum dpp_status_error status)
|
||||||
{
|
{
|
||||||
size_t nonce_len;
|
|
||||||
struct wpabuf *msg;
|
struct wpabuf *msg;
|
||||||
#define DPP_AUTH_RESP_CLEAR_LEN2 4 + DPP_MAX_NONCE_LEN + 4 + 1
|
const u8 *r_pubkey_hash, *i_pubkey_hash;
|
||||||
u8 clear[DPP_AUTH_RESP_CLEAR_LEN2];
|
|
||||||
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN2 + AES_BLOCK_SIZE];
|
|
||||||
u8 *pos;
|
|
||||||
const u8 *addr[2];
|
|
||||||
size_t len[2], siv_len, attr_len;
|
|
||||||
u8 *attr_start, *attr_end;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
||||||
|
|
||||||
/* Build DPP Authentication Response frame attributes */
|
r_pubkey_hash = auth->own_bi->pubkey_hash;
|
||||||
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) + 4 + sizeof(wrapped_data);
|
if (auth->peer_bi)
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
i_pubkey_hash = auth->peer_bi->pubkey_hash;
|
||||||
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
|
else
|
||||||
attr_len += 4;
|
i_pubkey_hash = NULL;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
|
msg = dpp_auth_build_resp(auth, status, NULL, auth->curve->nonce_len,
|
||||||
|
r_pubkey_hash, i_pubkey_hash,
|
||||||
|
NULL, auth->i_nonce, NULL, 0,
|
||||||
|
auth->k1);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto fail;
|
|
||||||
wpabuf_free(auth->resp_msg);
|
|
||||||
auth->resp_msg = msg;
|
|
||||||
|
|
||||||
attr_start = wpabuf_put(msg, 0);
|
|
||||||
|
|
||||||
/* DPP Status */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
|
||||||
wpabuf_put_le16(msg, 1);
|
|
||||||
wpabuf_put_u8(msg, status);
|
|
||||||
|
|
||||||
/* Responder Bootstrapping Key Hash */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
|
|
||||||
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
|
||||||
wpabuf_put_data(msg, auth->own_bi->pubkey_hash, SHA256_MAC_LEN);
|
|
||||||
|
|
||||||
if (auth->peer_bi) {
|
|
||||||
/* Mutual authentication */
|
|
||||||
/* Initiator Bootstrapping Key Hash */
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
|
|
||||||
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
|
||||||
wpabuf_put_data(msg, auth->peer_bi->pubkey_hash,
|
|
||||||
SHA256_MAC_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
attr_end = wpabuf_put(msg, 0);
|
|
||||||
|
|
||||||
/* Wrapped data ({I-nonce, R-capabilities}k1) */
|
|
||||||
pos = clear;
|
|
||||||
/* I-nonce */
|
|
||||||
nonce_len = auth->curve->nonce_len;
|
|
||||||
WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
|
|
||||||
pos += 2;
|
|
||||||
WPA_PUT_LE16(pos, nonce_len);
|
|
||||||
pos += 2;
|
|
||||||
os_memcpy(pos, auth->i_nonce, nonce_len);
|
|
||||||
pos += nonce_len;
|
|
||||||
/* R-capabilities */
|
|
||||||
WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES);
|
|
||||||
pos += 2;
|
|
||||||
WPA_PUT_LE16(pos, 1);
|
|
||||||
pos += 2;
|
|
||||||
auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
|
|
||||||
DPP_CAPAB_ENROLLEE;
|
|
||||||
*pos++ = auth->r_capab;
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
|
||||||
if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
|
|
||||||
wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
|
|
||||||
pos[-1] = 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
|
||||||
|
|
||||||
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
|
||||||
addr[0] = wpabuf_head_u8(msg) + 2;
|
|
||||||
len[0] = 3 + 1 + 1 + 1;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
|
||||||
|
|
||||||
/* Attributes before Wrapped Data */
|
|
||||||
addr[1] = attr_start;
|
|
||||||
len[1] = attr_end - attr_start;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
|
||||||
|
|
||||||
siv_len = pos - clear;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
|
||||||
if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
|
|
||||||
2, addr, len, wrapped_data) < 0)
|
|
||||||
goto fail;
|
|
||||||
siv_len += AES_BLOCK_SIZE;
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
|
||||||
wrapped_data, siv_len);
|
|
||||||
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
|
||||||
wpabuf_put_le16(msg, siv_len);
|
|
||||||
wpabuf_put_data(msg, wrapped_data, siv_len);
|
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
|
||||||
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
|
|
||||||
wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_TESTING);
|
|
||||||
wpabuf_put_le16(msg, 0);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
|
||||||
|
|
||||||
wpa_hexdump_buf(MSG_DEBUG,
|
|
||||||
"DPP: Authentication Response frame attributes", msg);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return -1;
|
return -1;
|
||||||
|
auth->resp_msg = msg;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2475,7 +2429,7 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||||
"%s", hex);
|
"%s", hex);
|
||||||
return auth;
|
return auth;
|
||||||
}
|
}
|
||||||
if (dpp_auth_build_resp(auth) < 0)
|
if (dpp_auth_build_resp_ok(auth) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return auth;
|
return auth;
|
||||||
|
@ -2516,7 +2470,7 @@ int dpp_notify_new_qr_code(struct dpp_authentication *auth,
|
||||||
MACSTR, MAC2STR(auth->peer_mac_addr));
|
MACSTR, MAC2STR(auth->peer_mac_addr));
|
||||||
auth->peer_bi = peer_bi;
|
auth->peer_bi = peer_bi;
|
||||||
|
|
||||||
if (dpp_auth_build_resp(auth) < 0)
|
if (dpp_auth_build_resp_ok(auth) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in a new issue