mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-02-16 15:20:42 +01:00
dpp: fix data corruption around prf_plus() call
Without the change test-dpp fails on aarch64-linux as: $ unit/test-dpp TEST: DPP test responder-only key derivation TEST: DPP test mutual key derivation TEST: DPP test PKEX key derivation test-dpp: unit/test-dpp.c:514: test_pkex_key_derivation: Assertion `!memcmp(tmp, __tmp, 32)' failed. This happens due to int/size_t type mismatch passed to vararg parameters to prf_plus(): bool prf_plus(enum l_checksum_type type, const void *key, size_t key_len, void *out, size_t out_len, size_t n_extra, ...) { // ... va_start(va, n_extra); for (i = 0; i < n_extra; i++) { iov[i + 1].iov_base = va_arg(va, void *); iov[i + 1].iov_len = va_arg(va, size_t); // ... Note that varargs here could only be a sequence of `void *` / `size_t` values. But in src/dpp-util.c `iwd` attempted to pass `int` there: prf_plus(sha, prk, bytes, z_out, bytes, 5, mac_i, 6, // <- here mac_r, 6, // <- and here m_x, bytes, n_x, bytes, key, strlen(key)); aarch64 stores only 32-bit value part of the register: mov w7, #0x6 str w7, [sp, #...] and loads full 64-bit form of the register: ldr x3, [x3] As a result higher bits of `iov[].iov_len` contain unexpected values and sendmsg sends a lot more data than expected to the kernel. The change fixes test-dpp test for me. While at it fixed obvious `int` / `size_t` mismatch in src/erp.c. Fixes: 6320d6db0f ("crypto: remove label from prf_plus, instead use va_args")
This commit is contained in:
parent
5af1fe34b6
commit
688d277008
@ -1376,8 +1376,9 @@ bool dpp_derive_z(const uint8_t *mac_i, const uint8_t *mac_r,
|
|||||||
hkdf_extract(sha, NULL, 0, 1, prk, k_x, bytes);
|
hkdf_extract(sha, NULL, 0, 1, prk, k_x, bytes);
|
||||||
|
|
||||||
/* HKDF-Extract (since it doesn't take non-string arguments)*/
|
/* HKDF-Extract (since it doesn't take non-string arguments)*/
|
||||||
prf_plus(sha, prk, bytes, z_out, bytes, 5, mac_i, 6, mac_r, 6, m_x,
|
prf_plus(sha, prk, bytes, z_out, bytes, 5,
|
||||||
bytes, n_x, bytes, key, strlen(key));
|
mac_i, (size_t) 6, mac_r, (size_t) 6, m_x, bytes,
|
||||||
|
n_x, bytes, key, strlen(key));
|
||||||
|
|
||||||
*z_len = bytes;
|
*z_len = bytes;
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ static bool erp_derive_reauth_keys(const uint8_t *emsk, size_t emsk_len,
|
|||||||
if (!prf_plus(L_CHECKSUM_SHA256, r_rk, emsk_len,
|
if (!prf_plus(L_CHECKSUM_SHA256, r_rk, emsk_len,
|
||||||
r_ik, emsk_len, 3, ERP_RIK_LABEL,
|
r_ik, emsk_len, 3, ERP_RIK_LABEL,
|
||||||
strlen(ERP_RIK_LABEL) + 1,
|
strlen(ERP_RIK_LABEL) + 1,
|
||||||
&cryptosuite, 1, &len, sizeof(len)))
|
&cryptosuite, (size_t) 1, &len, sizeof(len)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user