DPP: Move PKEX Commit-Reveal Request building to a helper function

This cleans up dpp_pkex_rx_exchange_resp() a bit and makes it easier to
add protocol testing functionality to PKEX exchange similarly to the
previously added DPP Authentication case.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2017-11-02 21:21:55 +02:00 committed by Jouni Malinen
parent a5c3b41b2f
commit b0626c2a6b

View file

@ -5905,6 +5905,80 @@ static int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
} }
static struct wpabuf *
dpp_pkex_build_commit_reveal_req(struct dpp_pkex *pkex,
const struct wpabuf *A_pub, const u8 *u)
{
const struct dpp_curve_params *curve = pkex->own_bi->curve;
struct wpabuf *msg = NULL;
size_t clear_len, attr_len;
struct wpabuf *clear = NULL;
u8 *wrapped;
u8 octet;
const u8 *addr[2];
size_t len[2];
/* {A, u, [bootstrapping info]}z */
clear_len = 4 + 2 * curve->prime_len + 4 + curve->hash_len;
clear = wpabuf_alloc(clear_len);
attr_len = 4 + clear_len + AES_BLOCK_SIZE;
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ)
attr_len += 4;
#endif /* CONFIG_TESTING_OPTIONS */
msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_REQ, attr_len);
if (!clear || !msg)
goto fail;
/* A in Bootstrap Key attribute */
wpabuf_put_le16(clear, DPP_ATTR_BOOTSTRAP_KEY);
wpabuf_put_le16(clear, wpabuf_len(A_pub));
wpabuf_put_buf(clear, A_pub);
/* u in I-Auth tag attribute */
wpabuf_put_le16(clear, DPP_ATTR_I_AUTH_TAG);
wpabuf_put_le16(clear, curve->hash_len);
wpabuf_put_data(clear, u, curve->hash_len);
addr[0] = wpabuf_head_u8(msg) + 2;
len[0] = DPP_HDR_LEN;
octet = 0;
addr[1] = &octet;
len[1] = sizeof(octet);
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]);
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(pkex->z, curve->hash_len,
wpabuf_head(clear), wpabuf_len(clear),
2, addr, len, wrapped) < 0)
goto fail;
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ) {
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 */
out:
wpabuf_free(clear);
return msg;
fail:
wpabuf_free(msg);
msg = NULL;
goto out;
}
struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex, struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
const u8 *buf, size_t buflen) const u8 *buf, size_t buflen)
{ {
@ -5912,9 +5986,6 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
u16 attr_status_len, attr_id_len, attr_key_len; u16 attr_status_len, attr_id_len, attr_key_len;
const EC_GROUP *group; const EC_GROUP *group;
BN_CTX *bnctx = NULL; BN_CTX *bnctx = NULL;
size_t clear_len, attr_len;
struct wpabuf *clear = NULL;
u8 *wrapped;
struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL; struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
const struct dpp_curve_params *curve = pkex->own_bi->curve; const struct dpp_curve_params *curve = pkex->own_bi->curve;
EC_POINT *Qr = NULL, *Y = NULL, *N = NULL; EC_POINT *Qr = NULL, *Y = NULL, *N = NULL;
@ -5926,7 +5997,6 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
const u8 *addr[4]; const u8 *addr[4];
size_t len[4]; size_t len[4];
u8 u[DPP_MAX_HASH_LEN]; u8 u[DPP_MAX_HASH_LEN];
u8 octet;
int res; int res;
attr_status = dpp_get_attr(buf, buflen, DPP_ATTR_STATUS, attr_status = dpp_get_attr(buf, buflen, DPP_ATTR_STATUS,
@ -6062,58 +6132,11 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
if (res < 0) if (res < 0)
goto fail; goto fail;
/* {A, u, [bootstrapping info]}z */ msg = dpp_pkex_build_commit_reveal_req(pkex, A_pub, u);
clear_len = 4 + 2 * curve->prime_len + 4 + curve->hash_len; if (!msg)
clear = wpabuf_alloc(clear_len);
attr_len = 4 + clear_len + AES_BLOCK_SIZE;
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ)
attr_len += 4;
#endif /* CONFIG_TESTING_OPTIONS */
msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_REQ, attr_len);
if (!clear || !msg)
goto fail; goto fail;
/* A in Bootstrap Key attribute */
wpabuf_put_le16(clear, DPP_ATTR_BOOTSTRAP_KEY);
wpabuf_put_le16(clear, wpabuf_len(A_pub));
wpabuf_put_buf(clear, A_pub);
/* u in I-Auth tag attribute */
wpabuf_put_le16(clear, DPP_ATTR_I_AUTH_TAG);
wpabuf_put_le16(clear, curve->hash_len);
wpabuf_put_data(clear, u, curve->hash_len);
addr[0] = wpabuf_head_u8(msg) + 2;
len[0] = DPP_HDR_LEN;
octet = 0;
addr[1] = &octet;
len[1] = sizeof(octet);
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]);
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(pkex->z, curve->hash_len,
wpabuf_head(clear), wpabuf_len(clear),
2, addr, len, wrapped) < 0)
goto fail;
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ) {
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 */
out: out:
wpabuf_free(clear);
wpabuf_free(A_pub); wpabuf_free(A_pub);
wpabuf_free(X_pub); wpabuf_free(X_pub);
wpabuf_free(Y_pub); wpabuf_free(Y_pub);
@ -6128,8 +6151,6 @@ out:
return msg; return msg;
fail: fail:
wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed"); wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed");
wpabuf_free(msg);
msg = NULL;
goto out; goto out;
} }