DPP2: Configuration Result message generation and processing
Use this new message from Enrollee to Configurator to indicate result of the config object provisioning if both devices support protocol version 2 or newer. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
8b6c834ff9
commit
22f90b32f1
4 changed files with 456 additions and 30 deletions
145
src/common/dpp.c
145
src/common/dpp.c
|
@ -4441,6 +4441,7 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
|
|||
wpabuf_head(conf), wpabuf_len(conf));
|
||||
}
|
||||
status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE;
|
||||
auth->conf_resp_status = status;
|
||||
|
||||
/* { E-nonce, configurationObject}ke */
|
||||
clear_len = 4 + e_nonce_len;
|
||||
|
@ -4613,6 +4614,7 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
|||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: Enrollee Nonce", e_nonce, e_nonce_len);
|
||||
os_memcpy(auth->e_nonce, e_nonce, e_nonce_len);
|
||||
|
||||
config_attr = dpp_get_attr(unwrapped, unwrapped_len,
|
||||
DPP_ATTR_CONFIG_ATTR_OBJ,
|
||||
|
@ -5486,6 +5488,8 @@ int dpp_conf_resp_rx(struct dpp_authentication *auth,
|
|||
size_t unwrapped_len = 0;
|
||||
int ret = -1;
|
||||
|
||||
auth->conf_resp_status = 255;
|
||||
|
||||
if (dpp_check_attrs(wpabuf_head(resp), wpabuf_len(resp)) < 0) {
|
||||
dpp_auth_fail(auth, "Invalid attribute in config response");
|
||||
return -1;
|
||||
|
@ -5546,6 +5550,7 @@ int dpp_conf_resp_rx(struct dpp_authentication *auth,
|
|||
"Missing or invalid required DPP Status attribute");
|
||||
goto fail;
|
||||
}
|
||||
auth->conf_resp_status = status[0];
|
||||
wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
|
||||
if (status[0] != DPP_STATUS_OK) {
|
||||
dpp_auth_fail(auth, "Configurator rejected configuration");
|
||||
|
@ -5572,6 +5577,146 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DPP2
|
||||
enum dpp_status_error dpp_conf_result_rx(struct dpp_authentication *auth,
|
||||
const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len)
|
||||
{
|
||||
const u8 *wrapped_data, *status, *e_nonce;
|
||||
u16 wrapped_data_len, status_len, e_nonce_len;
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
u8 *unwrapped = NULL;
|
||||
size_t unwrapped_len = 0;
|
||||
enum dpp_status_error ret = 256;
|
||||
|
||||
wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
|
||||
&wrapped_data_len);
|
||||
if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
|
||||
dpp_auth_fail(auth,
|
||||
"Missing or invalid required Wrapped Data attribute");
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
|
||||
wrapped_data, wrapped_data_len);
|
||||
|
||||
attr_len = wrapped_data - 4 - attr_start;
|
||||
|
||||
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)
|
||||
goto fail;
|
||||
if (aes_siv_decrypt(auth->ke, 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;
|
||||
}
|
||||
|
||||
e_nonce = dpp_get_attr(unwrapped, unwrapped_len,
|
||||
DPP_ATTR_ENROLLEE_NONCE,
|
||||
&e_nonce_len);
|
||||
if (!e_nonce || e_nonce_len != auth->curve->nonce_len) {
|
||||
dpp_auth_fail(auth,
|
||||
"Missing or invalid Enrollee Nonce attribute");
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: Enrollee Nonce", e_nonce, e_nonce_len);
|
||||
if (os_memcmp(e_nonce, auth->e_nonce, e_nonce_len) != 0) {
|
||||
dpp_auth_fail(auth, "Enrollee Nonce mismatch");
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: Expected Enrollee Nonce",
|
||||
auth->e_nonce, e_nonce_len);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_STATUS,
|
||||
&status_len);
|
||||
if (!status || status_len < 1) {
|
||||
dpp_auth_fail(auth,
|
||||
"Missing or invalid required DPP Status attribute");
|
||||
goto fail;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
|
||||
ret = status[0];
|
||||
|
||||
fail:
|
||||
bin_clear_free(unwrapped, unwrapped_len);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_DPP2 */
|
||||
|
||||
|
||||
struct wpabuf * dpp_build_conf_result(struct dpp_authentication *auth,
|
||||
enum dpp_status_error status)
|
||||
{
|
||||
struct wpabuf *msg, *clear;
|
||||
size_t nonce_len, clear_len, attr_len;
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
u8 *wrapped;
|
||||
|
||||
nonce_len = auth->curve->nonce_len;
|
||||
clear_len = 5 + 4 + nonce_len;
|
||||
attr_len = 4 + clear_len + AES_BLOCK_SIZE;
|
||||
clear = wpabuf_alloc(clear_len);
|
||||
msg = dpp_alloc_msg(DPP_PA_CONFIGURATION_RESULT, attr_len);
|
||||
if (!clear || !msg)
|
||||
return NULL;
|
||||
|
||||
/* DPP Status */
|
||||
dpp_build_attr_status(clear, status);
|
||||
|
||||
/* E-nonce */
|
||||
wpabuf_put_le16(clear, DPP_ATTR_ENROLLEE_NONCE);
|
||||
wpabuf_put_le16(clear, nonce_len);
|
||||
wpabuf_put_data(clear, auth->e_nonce, nonce_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 (none) */
|
||||
addr[1] = wpabuf_put(msg, 0);
|
||||
len[1] = 0;
|
||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||
|
||||
/* Wrapped Data */
|
||||
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
||||
wpabuf_put_le16(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
|
||||
wrapped = wpabuf_put(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
|
||||
|
||||
wpa_hexdump_buf(MSG_DEBUG, "DPP: AES-SIV cleartext", clear);
|
||||
if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
|
||||
wpabuf_head(clear), wpabuf_len(clear),
|
||||
2, addr, len, wrapped) < 0)
|
||||
goto fail;
|
||||
|
||||
wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Result attributes", msg);
|
||||
wpabuf_free(clear);
|
||||
return msg;
|
||||
fail:
|
||||
wpabuf_free(clear);
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void dpp_configurator_free(struct dpp_configurator *conf)
|
||||
{
|
||||
if (!conf)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue