3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-22 13:02:44 +01:00

crypto: Add SHA256 based KDF

This commit is contained in:
Denis Kenzior 2016-02-10 16:30:22 -06:00
parent fa852d1c48
commit 39444ab532
2 changed files with 48 additions and 0 deletions

View File

@ -339,6 +339,51 @@ bool prf_sha1(const void *key, size_t key_len,
return true;
}
/* Defined in 802.11-2012, Section 11.6.1.7.2 Key derivation function (KDF) */
bool kdf_sha256(const void *key, size_t key_len,
const void *prefix, size_t prefix_len,
const void *data, size_t data_len, void *output, size_t size)
{
struct l_checksum *hmac;
unsigned int i, offset = 0;
unsigned int counter;
uint8_t counter_le[2];
uint8_t length_le[2];
struct iovec iov[4] = {
[0] = { .iov_base = counter_le, .iov_len = 2 },
[1] = { .iov_base = (void *) prefix, .iov_len = prefix_len },
[2] = { .iov_base = (void *) data, .iov_len = data_len },
[3] = { .iov_base = length_le, .iov_len = 2 },
};
hmac = l_checksum_new_hmac(L_CHECKSUM_SHA256, key, key_len);
if (!hmac)
return false;
/* Length is denominated in bits, not bytes */
l_put_le16(size * 8, length_le);
/* 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_le16(counter, counter_le);
l_checksum_updatev(hmac, iov, 4);
l_checksum_get_digest(hmac, output + offset, len);
offset += len;
}
l_checksum_free(hmac);
return true;
}
/*
* 802.11, Section 11.6.6.7:
* PTK = PRF-X(PMK, "Pairwise key expansion", Min(AA, SA) || Max(AA, SA) ||

View File

@ -62,6 +62,9 @@ int crypto_psk_from_passphrase(const char *passphrase,
const unsigned char *ssid, size_t ssid_len,
unsigned char *out_psk);
bool kdf_sha256(const void *key, size_t key_len,
const void *prefix, size_t prefix_len,
const void *data, size_t data_len, void *output, size_t size);
bool prf_sha1(const void *key, size_t key_len,
const void *prefix, size_t prefix_len,
const void *data, size_t data_len, void *output, size_t size);