summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2007-08-01 12:15:49 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2007-08-01 12:15:49 +0000
commit0b07761ba86cd0298f4aecc2e91451401b788655 (patch)
treef7402f7ba90660c6724e2b56671ee34701456b86 /sys
parentf48974641446932e7f1414db98ca60209b0d59cd (diff)
the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic() quite a bit. set the EAPOL-Key body length before computing the MIC since the MIC is computed with the 802.1X header too. add a missing htons() while i'm here.
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_crypto.c25
-rw-r--r--sys/net80211/ieee80211_output.c23
2 files changed, 13 insertions, 35 deletions
diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c
index feb12d14e0a..cbe97fda43e 100644
--- a/sys/net80211/ieee80211_crypto.c
+++ b/sys/net80211/ieee80211_crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_crypto.c,v 1.26 2007/07/28 11:01:19 damien Exp $ */
+/* $OpenBSD: ieee80211_crypto.c,v 1.27 2007/08/01 12:15:48 damien Exp $ */
/* $NetBSD: ieee80211_crypto.c,v 1.5 2003/12/14 09:56:53 dyoung Exp $ */
/*-
@@ -655,22 +655,17 @@ ieee80211_eapol_key_mic(struct ieee80211_eapol_key *key, const u_int8_t *kck)
len = BE_READ_2(key->len) + 4;
info = BE_READ_2(key->info);
- KASSERT(!(info & EAPOL_KEY_KEYMIC));
switch (info & EAPOL_KEY_VERSION_MASK) {
case EAPOL_KEY_DESC_V1:
- ieee80211_hmac_md5(kck, 16, &key->version, len, key->mic);
+ ieee80211_hmac_md5((u_int8_t *)key, len, kck, 16, key->mic);
break;
case EAPOL_KEY_DESC_V2:
- ieee80211_hmac_sha1(kck, 16, &key->version, len, hash);
+ ieee80211_hmac_sha1((u_int8_t *)key, len, kck, 16, hash);
/* truncate HMAC-SHA1 to its 128 MSBs */
memcpy(key->mic, hash, EAPOL_KEY_MIC_LEN);
break;
}
-
- /* set the Key MIC bit */
- info |= EAPOL_KEY_KEYMIC;
- BE_WRITE_2(key->info, info);
}
/*
@@ -682,15 +677,9 @@ ieee80211_eapol_key_check_mic(struct ieee80211_eapol_key *key,
const u_int8_t *kck)
{
u_int8_t mic[EAPOL_KEY_MIC_LEN];
- u_int16_t info;
-
- info = BE_READ_2(key->info);
- KASSERT(info & EAPOL_KEY_KEYMIC);
memcpy(mic, key->mic, EAPOL_KEY_MIC_LEN);
memset(key->mic, 0, EAPOL_KEY_MIC_LEN);
- info &= ~EAPOL_KEY_KEYMIC;
- BE_WRITE_2(key->info, info);
ieee80211_eapol_key_mic(key, kck);
return memcmp(key->mic, mic, EAPOL_KEY_MIC_LEN) != 0;
@@ -713,8 +702,6 @@ ieee80211_eapol_key_encrypt(struct ieee80211com *ic,
len = BE_READ_2(key->paylen);
info = BE_READ_2(key->info);
- /* should not come here if key data is already encrypted */
- KASSERT(!(info & EAPOL_KEY_ENCRYPTED));
data = (u_int8_t *)(key + 1);
switch (info & EAPOL_KEY_VERSION_MASK) {
@@ -745,12 +732,10 @@ ieee80211_eapol_key_encrypt(struct ieee80211com *ic,
len += 8; /* AES Key Wrap adds 8 bytes */
/* update key data length */
BE_WRITE_2(key->paylen, len);
+ /* update packet body length */
+ BE_WRITE_2(key->len, sizeof(*key) + len - 4);
break;
}
-
- /* set the Encrypted Key Data bit */
- info |= EAPOL_KEY_ENCRYPTED;
- BE_WRITE_2(key->info, info);
}
/*
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index c8ee20719c6..458fc568e23 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_output.c,v 1.49 2007/08/01 11:59:40 damien Exp $ */
+/* $OpenBSD: ieee80211_output.c,v 1.50 2007/08/01 12:15:48 damien Exp $ */
/* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */
/*-
@@ -1519,7 +1519,7 @@ ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
if (m == NULL)
return ENOMEM;
eh = mtod(m, struct ether_header *);
- eh->ether_type = ETHERTYPE_PAE;
+ eh->ether_type = htons(ETHERTYPE_PAE);
IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);
@@ -1533,26 +1533,19 @@ ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
info |= (ni->ni_pairwise_cipher != IEEE80211_CIPHER_CCMP) ?
EAPOL_KEY_DESC_V1 : EAPOL_KEY_DESC_V2;
BE_WRITE_2(key->info, info);
- BE_WRITE_2(key->paylen, m->m_len - sizeof(*key));
+
+ len = m->m_len - sizeof(struct ether_header);
+ BE_WRITE_2(key->paylen, len - sizeof(*key));
+ BE_WRITE_2(key->len, len - 4);
KASSERT((info & (EAPOL_KEY_ENCRYPTED | EAPOL_KEY_KEYMIC)) == 0 ||
ni->ni_ptk_ok);
- if (info & EAPOL_KEY_ENCRYPTED) {
- info &= ~EAPOL_KEY_ENCRYPTED;
- BE_WRITE_2(key->info, info);
+ if (info & EAPOL_KEY_ENCRYPTED)
ieee80211_eapol_key_encrypt(ic, key, ni->ni_ptk.kek);
- }
- if (info & EAPOL_KEY_KEYMIC) {
- info &= ~EAPOL_KEY_KEYMIC;
- BE_WRITE_2(key->info, info);
+ if (info & EAPOL_KEY_KEYMIC)
ieee80211_eapol_key_mic(key, ni->ni_ptk.kck);
- }
-
- /* write packet body length field */
- len = BE_READ_2(key->paylen);
- BE_WRITE_2(key->len, sizeof(*key) + len);
s = splnet();
IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);