diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2007-08-01 12:15:49 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2007-08-01 12:15:49 +0000 |
commit | 0b07761ba86cd0298f4aecc2e91451401b788655 (patch) | |
tree | f7402f7ba90660c6724e2b56671ee34701456b86 /sys/net80211 | |
parent | f48974641446932e7f1414db98ca60209b0d59cd (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/net80211')
-rw-r--r-- | sys/net80211/ieee80211_crypto.c | 25 | ||||
-rw-r--r-- | sys/net80211/ieee80211_output.c | 23 |
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); |