DPP: Process Authentication Confirm failure cases
Process Authentication Confirm with the two failure cases defined in the spec: STATUS_NOT_COMPATIBLE and STATUS_AUTH_FAILURE. This verifies the {R-nonce}k2 part and reports more detailed failure reason if the message is valid. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
7d917ab048
commit
19ef4289ca
1 changed files with 77 additions and 0 deletions
|
@ -3107,6 +3107,77 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth,
|
||||
const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len,
|
||||
const u8 *wrapped_data,
|
||||
u16 wrapped_data_len,
|
||||
enum dpp_status_error status)
|
||||
{
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
u8 *unwrapped = NULL;
|
||||
size_t unwrapped_len = 0;
|
||||
const u8 *r_nonce;
|
||||
u16 r_nonce_len;
|
||||
|
||||
/* Authentication Confirm failure cases are expected to include
|
||||
* {R-nonce}k2 in the Wrapped Data attribute. */
|
||||
|
||||
addr[0] = hdr;
|
||||
len[0] = DPP_HDR_LEN;
|
||||
addr[1] = attr_start;
|
||||
len[1] = attr_len;
|
||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||
wrapped_data, wrapped_data_len);
|
||||
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
||||
unwrapped = os_malloc(unwrapped_len);
|
||||
if (!unwrapped) {
|
||||
dpp_auth_fail(auth, "Authentication failed");
|
||||
goto fail;
|
||||
}
|
||||
if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
|
||||
wrapped_data, wrapped_data_len,
|
||||
2, addr, len, unwrapped) < 0) {
|
||||
dpp_auth_fail(auth, "AES-SIV decryption failed");
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
|
||||
unwrapped, unwrapped_len);
|
||||
|
||||
if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
|
||||
dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
|
||||
&r_nonce_len);
|
||||
if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
|
||||
dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
|
||||
goto fail;
|
||||
}
|
||||
if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) {
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce",
|
||||
r_nonce, r_nonce_len);
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce",
|
||||
auth->r_nonce, r_nonce_len);
|
||||
dpp_auth_fail(auth, "R-nonce mismatch");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (status == DPP_STATUS_NOT_COMPATIBLE)
|
||||
dpp_auth_fail(auth, "Peer reported incompatible R-capab role");
|
||||
else if (status == DPP_STATUS_AUTH_FAILURE)
|
||||
dpp_auth_fail(auth, "Peer reported authentication failure)");
|
||||
|
||||
fail:
|
||||
bin_clear_free(unwrapped, unwrapped_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len)
|
||||
{
|
||||
|
@ -3186,6 +3257,12 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
|
|||
return -1;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
|
||||
if (status[0] == DPP_STATUS_NOT_COMPATIBLE ||
|
||||
status[0] == DPP_STATUS_AUTH_FAILURE)
|
||||
return dpp_auth_conf_rx_failure(auth, hdr, attr_start,
|
||||
attr_len, wrapped_data,
|
||||
wrapped_data_len, status[0]);
|
||||
|
||||
if (status[0] != DPP_STATUS_OK) {
|
||||
dpp_auth_fail(auth, "Authentication failed");
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue