mka: AES-CMAC-256 -based KDF
Extend the previously implemented KDF (IEEE Std 802.1X-2010, 6.2.1) to support 256-bit input key and AES-CMAC-256. This does not change any actual key derivation functionality yet, but is needed as a step towards supporting 256-bit CAK. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
a8aeaf41df
commit
9dd701c12e
1 changed files with 23 additions and 13 deletions
|
@ -31,7 +31,8 @@ static void joint_two_mac(const u8 *mac1, const u8 *mac2, u8 *out)
|
||||||
|
|
||||||
|
|
||||||
/* IEEE Std 802.1X-2010, 6.2.1 KDF */
|
/* IEEE Std 802.1X-2010, 6.2.1 KDF */
|
||||||
static int aes_kdf_128(const u8 *kdk, const char *label, const u8 *context,
|
static int aes_kdf(const u8 *kdk, size_t kdk_bits,
|
||||||
|
const char *label, const u8 *context,
|
||||||
int ctx_bits, int ret_bits, u8 *ret)
|
int ctx_bits, int ret_bits, u8 *ret)
|
||||||
{
|
{
|
||||||
const int h = 128;
|
const int h = 128;
|
||||||
|
@ -40,6 +41,9 @@ static int aes_kdf_128(const u8 *kdk, const char *label, const u8 *context,
|
||||||
int lab_len, ctx_len, ret_len, buf_len;
|
int lab_len, ctx_len, ret_len, buf_len;
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
|
|
||||||
|
if (kdk_bits != 128 && kdk_bits != 256)
|
||||||
|
return -1;
|
||||||
|
|
||||||
lab_len = os_strlen(label);
|
lab_len = os_strlen(label);
|
||||||
ctx_len = (ctx_bits + 7) / 8;
|
ctx_len = (ctx_bits + 7) / 8;
|
||||||
ret_len = ((ret_bits & 0xffff) + 7) / 8;
|
ret_len = ((ret_bits & 0xffff) + 7) / 8;
|
||||||
|
@ -60,8 +64,14 @@ static int aes_kdf_128(const u8 *kdk, const char *label, const u8 *context,
|
||||||
WPA_PUT_BE16(&buf[buf_len - 2], ret_bits);
|
WPA_PUT_BE16(&buf[buf_len - 2], ret_bits);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
int res;
|
||||||
|
|
||||||
buf[0] = (u8) (i + 1);
|
buf[0] = (u8) (i + 1);
|
||||||
if (omac1_aes_128(kdk, buf, buf_len, ret)) {
|
if (kdk_bits == 128)
|
||||||
|
res = omac1_aes_128(kdk, buf, buf_len, ret);
|
||||||
|
else
|
||||||
|
res = omac1_aes_256(kdk, buf, buf_len, ret);
|
||||||
|
if (res) {
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +95,7 @@ int ieee802_1x_cak_128bits_aes_cmac(const u8 *msk, const u8 *mac1,
|
||||||
u8 context[2 * ETH_ALEN];
|
u8 context[2 * ETH_ALEN];
|
||||||
|
|
||||||
joint_two_mac(mac1, mac2, context);
|
joint_two_mac(mac1, mac2, context);
|
||||||
return aes_kdf_128(msk, "IEEE8021 EAP CAK",
|
return aes_kdf(msk, 128, "IEEE8021 EAP CAK",
|
||||||
context, sizeof(context) * 8, 128, cak);
|
context, sizeof(context) * 8, 128, cak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +122,7 @@ int ieee802_1x_ckn_128bits_aes_cmac(const u8 *msk, const u8 *mac1,
|
||||||
os_memcpy(context, sid, sid_bytes);
|
os_memcpy(context, sid, sid_bytes);
|
||||||
joint_two_mac(mac1, mac2, context + sid_bytes);
|
joint_two_mac(mac1, mac2, context + sid_bytes);
|
||||||
|
|
||||||
res = aes_kdf_128(msk, "IEEE8021 EAP CKN", context, ctx_len * 8,
|
res = aes_kdf(msk, 128, "IEEE8021 EAP CKN", context, ctx_len * 8,
|
||||||
128, ckn);
|
128, ckn);
|
||||||
os_free(context);
|
os_free(context);
|
||||||
return res;
|
return res;
|
||||||
|
@ -134,7 +144,7 @@ int ieee802_1x_kek_128bits_aes_cmac(const u8 *cak, const u8 *ckn,
|
||||||
os_memset(context, 0, sizeof(context));
|
os_memset(context, 0, sizeof(context));
|
||||||
os_memcpy(context, ckn, (ckn_bytes < 16) ? ckn_bytes : 16);
|
os_memcpy(context, ckn, (ckn_bytes < 16) ? ckn_bytes : 16);
|
||||||
|
|
||||||
return aes_kdf_128(cak, "IEEE8021 KEK", context, sizeof(context) * 8,
|
return aes_kdf(cak, 128, "IEEE8021 KEK", context, sizeof(context) * 8,
|
||||||
128, kek);
|
128, kek);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +164,7 @@ int ieee802_1x_ick_128bits_aes_cmac(const u8 *cak, const u8 *ckn,
|
||||||
os_memset(context, 0, sizeof(context));
|
os_memset(context, 0, sizeof(context));
|
||||||
os_memcpy(context, ckn, (ckn_bytes < 16) ? ckn_bytes : 16);
|
os_memcpy(context, ckn, (ckn_bytes < 16) ? ckn_bytes : 16);
|
||||||
|
|
||||||
return aes_kdf_128(cak, "IEEE8021 ICK", context, sizeof(context) * 8,
|
return aes_kdf(cak, 128, "IEEE8021 ICK", context, sizeof(context) * 8,
|
||||||
128, ick);
|
128, ick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +195,6 @@ int ieee802_1x_icv_128bits_aes_cmac(const u8 *ick, const u8 *msg,
|
||||||
int ieee802_1x_sak_128bits_aes_cmac(const u8 *cak, const u8 *ctx,
|
int ieee802_1x_sak_128bits_aes_cmac(const u8 *cak, const u8 *ctx,
|
||||||
size_t ctx_bytes, u8 *sak, size_t sak_bytes)
|
size_t ctx_bytes, u8 *sak, size_t sak_bytes)
|
||||||
{
|
{
|
||||||
return aes_kdf_128(cak, "IEEE8021 SAK", ctx, ctx_bytes * 8,
|
return aes_kdf(cak, 128, "IEEE8021 SAK", ctx, ctx_bytes * 8,
|
||||||
sak_bytes * 8, sak);
|
sak_bytes * 8, sak);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue