mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +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 (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,
|
||||
bytes, n_x, bytes, key, strlen(key));
|
||||
prf_plus(sha, prk, bytes, z_out, bytes, 5,
|
||||
mac_i, (size_t) 6, mac_r, (size_t) 6, m_x, bytes,
|
||||
n_x, bytes, key, strlen(key));
|
||||
|
||||
*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,
|
||||
r_ik, emsk_len, 3, ERP_RIK_LABEL,
|
||||
strlen(ERP_RIK_LABEL) + 1,
|
||||
&cryptosuite, 1, &len, sizeof(len)))
|
||||
&cryptosuite, (size_t) 1, &len, sizeof(len)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user