From 9dd701c12e3a1084d2480aefe748ae095adc026e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 26 Dec 2018 12:13:40 +0200 Subject: [PATCH] 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 --- src/pae/ieee802_1x_key.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/pae/ieee802_1x_key.c b/src/pae/ieee802_1x_key.c index 4049fd3a4..e5c76df10 100644 --- a/src/pae/ieee802_1x_key.c +++ b/src/pae/ieee802_1x_key.c @@ -31,8 +31,9 @@ static void joint_two_mac(const u8 *mac1, const u8 *mac2, u8 *out) /* IEEE Std 802.1X-2010, 6.2.1 KDF */ -static int aes_kdf_128(const u8 *kdk, const char *label, const u8 *context, - int ctx_bits, int ret_bits, u8 *ret) +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) { const int h = 128; const int r = 8; @@ -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; u8 *buf; + if (kdk_bits != 128 && kdk_bits != 256) + return -1; + lab_len = os_strlen(label); ctx_len = (ctx_bits + 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); for (i = 0; i < n; i++) { + int res; + 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); return -1; } @@ -85,8 +95,8 @@ int ieee802_1x_cak_128bits_aes_cmac(const u8 *msk, const u8 *mac1, u8 context[2 * ETH_ALEN]; joint_two_mac(mac1, mac2, context); - return aes_kdf_128(msk, "IEEE8021 EAP CAK", - context, sizeof(context) * 8, 128, cak); + return aes_kdf(msk, 128, "IEEE8021 EAP CAK", + context, sizeof(context) * 8, 128, cak); } @@ -112,8 +122,8 @@ int ieee802_1x_ckn_128bits_aes_cmac(const u8 *msk, const u8 *mac1, os_memcpy(context, sid, sid_bytes); joint_two_mac(mac1, mac2, context + sid_bytes); - res = aes_kdf_128(msk, "IEEE8021 EAP CKN", context, ctx_len * 8, - 128, ckn); + res = aes_kdf(msk, 128, "IEEE8021 EAP CKN", context, ctx_len * 8, + 128, ckn); os_free(context); return res; } @@ -134,8 +144,8 @@ int ieee802_1x_kek_128bits_aes_cmac(const u8 *cak, const u8 *ckn, os_memset(context, 0, sizeof(context)); os_memcpy(context, ckn, (ckn_bytes < 16) ? ckn_bytes : 16); - return aes_kdf_128(cak, "IEEE8021 KEK", context, sizeof(context) * 8, - 128, kek); + return aes_kdf(cak, 128, "IEEE8021 KEK", context, sizeof(context) * 8, + 128, kek); } @@ -154,8 +164,8 @@ int ieee802_1x_ick_128bits_aes_cmac(const u8 *cak, const u8 *ckn, os_memset(context, 0, sizeof(context)); os_memcpy(context, ckn, (ckn_bytes < 16) ? ckn_bytes : 16); - return aes_kdf_128(cak, "IEEE8021 ICK", context, sizeof(context) * 8, - 128, ick); + return aes_kdf(cak, 128, "IEEE8021 ICK", context, sizeof(context) * 8, + 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, size_t ctx_bytes, u8 *sak, size_t sak_bytes) { - return aes_kdf_128(cak, "IEEE8021 SAK", ctx, ctx_bytes * 8, - sak_bytes * 8, sak); + return aes_kdf(cak, 128, "IEEE8021 SAK", ctx, ctx_bytes * 8, + sak_bytes * 8, sak); }