wscutil: Add WSC KDF function

This commit is contained in:
Denis Kenzior 2016-08-23 13:52:52 -05:00
parent 0a6ffdf029
commit c2b1351396
2 changed files with 53 additions and 0 deletions

View File

@ -1703,3 +1703,48 @@ bool wsc_uuid_from_addr(const uint8_t addr[], uint8_t *out_uuid)
return l_uuid_v5(nsid, addr, 6, out_uuid);
}
/* WSC 2.0.5, Section 7.3 */
bool wsc_kdf(const void *key, void *output, size_t size)
{
static char *personalization = "Wi-Fi Easy and Secure Key Derivation";
struct l_checksum *hmac;
unsigned int i, offset = 0;
unsigned int counter;
uint8_t counter_be[4];
uint8_t total_key_bits[4];
struct iovec iov[3] = {
[0] = { .iov_base = counter_be, .iov_len = 4 },
[1] = { .iov_base = personalization,
.iov_len = strlen(personalization) },
[2] = { .iov_base = total_key_bits, .iov_len = 4 },
};
hmac = l_checksum_new_hmac(L_CHECKSUM_SHA256, key, 32);
if (!hmac)
return false;
/* Length is denominated in bits, not bytes */
l_put_be32(size * 8, total_key_bits);
/* KDF processes in 256-bit chunks (32 bytes) */
for (i = 0, counter = 1; i < (size + 31) / 32; i++, counter++) {
size_t len;
if (size - offset > 32)
len = 32;
else
len = size - offset;
l_put_be32(counter, counter_be);
l_checksum_updatev(hmac, iov, 3);
l_checksum_get_digest(hmac, output + offset, len);
offset += len;
}
l_checksum_free(hmac);
return true;
}

View File

@ -469,3 +469,11 @@ uint8_t *wsc_build_m4(const struct wsc_m4 *m4, const uint8_t *encrypted,
size_t encrypted_len, size_t *out_len);
bool wsc_uuid_from_addr(const uint8_t addr[], uint8_t *out_uuid);
struct wsc_session_key {
uint8_t auth_key[32];
uint8_t keywrap_key[16];
uint8_t emsk[32];
} __attribute__ ((packed));
bool wsc_kdf(const void *kdk, void *output, size_t size);