aboutsummaryrefslogtreecommitdiffstats
path: root/src/pae/ieee802_1x_key.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2018-12-26 10:13:40 (GMT)
committerJouni Malinen <j@w1.fi>2018-12-26 14:42:26 (GMT)
commit9dd701c12e3a1084d2480aefe748ae095adc026e (patch)
treeb3219a5be65321a341e0e8a04128980160475bdd /src/pae/ieee802_1x_key.c
parenta8aeaf41df95ac6f979eb9014d0e2d17c46c671e (diff)
downloadhostap-9dd701c12e3a1084d2480aefe748ae095adc026e.zip
hostap-9dd701c12e3a1084d2480aefe748ae095adc026e.tar.gz
hostap-9dd701c12e3a1084d2480aefe748ae095adc026e.tar.bz2
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>
Diffstat (limited to 'src/pae/ieee802_1x_key.c')
-rw-r--r--src/pae/ieee802_1x_key.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/src/pae/ieee802_1x_key.c b/src/pae/ieee802_1x_key.c
index 4049fd3..e5c76df 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);
}