Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115976882
D44921.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D44921.diff
View Options
diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c
--- a/sys/net80211/ieee80211_crypto.c
+++ b/sys/net80211/ieee80211_crypto.c
@@ -153,7 +153,8 @@
* hardware cipher list (ic_cryptocaps.)
*/
ic->ic_sw_cryptocaps = IEEE80211_CRYPTO_WEP |
- IEEE80211_CRYPTO_TKIP | IEEE80211_CRYPTO_AES_CCM;
+ IEEE80211_CRYPTO_TKIP | IEEE80211_CRYPTO_AES_CCM |
+ IEEE80211_CRYPTO_AES_CCM_256;
/*
* Default set of net80211 supported key management types.
diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c
--- a/sys/net80211/ieee80211_crypto_ccmp.c
+++ b/sys/net80211/ieee80211_crypto_ccmp.c
@@ -54,6 +54,9 @@
#define AES_BLOCK_LEN 16
+#define CCMP_128_MIC_LEN 8
+#define CCMP_256_MIC_LEN 16
+
struct ccmp_ctx {
struct ieee80211vap *cc_vap; /* for diagnostics+statistics */
struct ieee80211com *cc_ic;
@@ -63,18 +66,19 @@
static void *ccmp_attach(struct ieee80211vap *, struct ieee80211_key *);
static void ccmp_detach(struct ieee80211_key *);
static int ccmp_setkey(struct ieee80211_key *);
+static int ccmp_256_setkey(struct ieee80211_key *);
static void ccmp_setiv(struct ieee80211_key *, uint8_t *);
static int ccmp_encap(struct ieee80211_key *, struct mbuf *);
static int ccmp_decap(struct ieee80211_key *, struct mbuf *, int);
static int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int);
static int ccmp_demic(struct ieee80211_key *, struct mbuf *, int);
-static const struct ieee80211_cipher ccmp = {
+static const struct ieee80211_cipher ccmp_128 = {
.ic_name = "AES-CCM",
.ic_cipher = IEEE80211_CIPHER_AES_CCM,
.ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
IEEE80211_WEP_EXTIVLEN,
- .ic_trailer = IEEE80211_WEP_MICLEN,
+ .ic_trailer = CCMP_128_MIC_LEN,
.ic_miclen = 0,
.ic_attach = ccmp_attach,
.ic_detach = ccmp_detach,
@@ -86,6 +90,23 @@
.ic_demic = ccmp_demic,
};
+static const struct ieee80211_cipher ccmp_256 = {
+ .ic_name = "AES-CCM-256",
+ .ic_cipher = IEEE80211_CIPHER_AES_CCM_256,
+ .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
+ IEEE80211_WEP_EXTIVLEN,
+ .ic_trailer = CCMP_256_MIC_LEN,
+ .ic_miclen = 0,
+ .ic_attach = ccmp_attach,
+ .ic_detach = ccmp_detach,
+ .ic_setkey = ccmp_256_setkey,
+ .ic_setiv = ccmp_setiv,
+ .ic_encap = ccmp_encap,
+ .ic_decap = ccmp_decap,
+ .ic_enmic = ccmp_enmic,
+ .ic_demic = ccmp_demic,
+};
+
static int ccmp_encrypt(struct ieee80211_key *, struct mbuf *, int hdrlen);
static int ccmp_decrypt(struct ieee80211_key *, u_int64_t pn,
struct mbuf *, int hdrlen);
@@ -120,6 +141,28 @@
nrefs--; /* NB: we assume caller locking */
}
+static int
+ccmp_get_trailer_len(struct ieee80211_key *k)
+{
+ return k->wk_cipher->ic_trailer;
+}
+
+static int
+ccmp_get_header_len(struct ieee80211_key *k)
+{
+ return k->wk_cipher->ic_header;
+}
+
+static int
+ccmp_get_ccm_m(struct ieee80211_key *k)
+{
+ if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM)
+ return 8;
+ if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM_256)
+ return 16;
+ return 8; /* XXX default */
+}
+
static int
ccmp_setkey(struct ieee80211_key *k)
{
@@ -136,6 +179,22 @@
return 1;
}
+static int
+ccmp_256_setkey(struct ieee80211_key *k)
+{
+ struct ccmp_ctx *ctx = k->wk_private;
+
+ if (k->wk_keylen != (256/NBBY)) {
+ IEEE80211_DPRINTF(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
+ "%s: Invalid key length %u, expecting %u\n",
+ __func__, k->wk_keylen, 256/NBBY);
+ return 0;
+ }
+ if (k->wk_flags & IEEE80211_KEY_SWENCRYPT)
+ rijndael_set_key(&ctx->cc_aes, k->wk_key, k->wk_keylen*NBBY);
+ return 1;
+}
+
static void
ccmp_setiv(struct ieee80211_key *k, uint8_t *ivp)
{
@@ -187,11 +246,11 @@
/*
* Copy down 802.11 header and add the IV, KeyID, and ExtIV.
*/
- M_PREPEND(m, ccmp.ic_header, IEEE80211_M_NOWAIT);
+ M_PREPEND(m, ccmp_get_header_len(k), IEEE80211_M_NOWAIT);
if (m == NULL)
return 0;
ivp = mtod(m, uint8_t *);
- ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen);
+ ovbcopy(ivp + ccmp_get_header_len(k), ivp, hdrlen);
ivp += hdrlen;
ccmp_setiv(k, ivp);
@@ -287,16 +346,16 @@
* Copy up 802.11 header and strip crypto bits.
*/
if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))) {
- ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + ccmp.ic_header,
+ ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + ccmp_get_header_len(k),
hdrlen);
- m_adj(m, ccmp.ic_header);
+ m_adj(m, ccmp_get_header_len(k));
}
/*
* XXX TODO: see if MMIC_STRIP also covers CCMP MIC trailer.
*/
if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MMIC_STRIP)))
- m_adj(m, -ccmp.ic_trailer);
+ m_adj(m, -ccmp_get_trailer_len(k));
/*
* Ok to update rsc now.
@@ -341,18 +400,27 @@
static void
ccmp_init_blocks(rijndael_ctx *ctx, struct ieee80211_frame *wh,
+ uint32_t m,
u_int64_t pn, size_t dlen,
uint8_t b0[AES_BLOCK_LEN], uint8_t aad[2 * AES_BLOCK_LEN],
uint8_t auth[AES_BLOCK_LEN], uint8_t s0[AES_BLOCK_LEN])
{
#define IS_QOS_DATA(wh) IEEE80211_QOS_HAS_SEQ(wh)
+ /*
+ * Map M parameter to encoding
+ * (RFC3610, Section 2 (CCM Mode Specification)
+ */
+ m = (m - 2) / 2;
+
/* CCM Initial Block:
- * Flag (Include authentication header, M=3 (8-octet MIC),
- * L=1 (2-octet Dlen))
+ * Flag (Include authentication header, M=8 (8-octet MIC),
+ * L=2 (2-octet Dlen))
* Nonce: 0x00 | A2 | PN
* Dlen */
- b0[0] = 0x59;
+ /* XXX 0x40 = Adata, 0x01 = L=2, 0x18 = M=8 */
+ /* M=3, L=2, ADATA = 0x59 */
+ b0[0] = 0x40 | 0x01 | (m << 3);
/* NB: b0[1] set below */
IEEE80211_ADDR_COPY(b0 + 2, wh->i_addr2);
b0[8] = pn >> 40;
@@ -458,14 +526,16 @@
ctx->cc_vap->iv_stats.is_crypto_ccmp++;
wh = mtod(m, struct ieee80211_frame *);
- data_len = m->m_pkthdr.len - (hdrlen + ccmp.ic_header);
- ccmp_init_blocks(&ctx->cc_aes, wh, key->wk_keytsc,
- data_len, b0, aad, b, s0);
+ data_len = m->m_pkthdr.len - (hdrlen + ccmp_get_header_len(key));
+ ccmp_init_blocks(&ctx->cc_aes, wh,
+ ccmp_get_ccm_m(key),
+ key->wk_keytsc,
+ data_len, b0, aad, b, s0);
i = 1;
- pos = mtod(m, uint8_t *) + hdrlen + ccmp.ic_header;
+ pos = mtod(m, uint8_t *) + hdrlen + ccmp_get_header_len(key);
/* NB: assumes header is entirely in first mbuf */
- space = m->m_len - (hdrlen + ccmp.ic_header);
+ space = m->m_len - (hdrlen + ccmp_get_header_len(key));
for (;;) {
if (space > data_len)
space = data_len;
@@ -573,8 +643,8 @@
}
done:
/* tack on MIC */
- xor_block(b, s0, ccmp.ic_trailer);
- return m_append(m0, ccmp.ic_trailer, b);
+ xor_block(b, s0, ccmp_get_trailer_len(key));
+ return m_append(m0, ccmp_get_trailer_len(key), b);
}
#undef CCMP_ENCRYPT
@@ -606,14 +676,18 @@
ctx->cc_vap->iv_stats.is_crypto_ccmp++;
wh = mtod(m, struct ieee80211_frame *);
- data_len = m->m_pkthdr.len - (hdrlen + ccmp.ic_header + ccmp.ic_trailer);
- ccmp_init_blocks(&ctx->cc_aes, wh, pn, data_len, b0, aad, a, b);
- m_copydata(m, m->m_pkthdr.len - ccmp.ic_trailer, ccmp.ic_trailer, mic);
- xor_block(mic, b, ccmp.ic_trailer);
+ data_len = m->m_pkthdr.len - (hdrlen + ccmp_get_header_len(key)
+ + ccmp_get_trailer_len(key));
+ ccmp_init_blocks(&ctx->cc_aes, wh,
+ ccmp_get_ccm_m(key),
+ pn, data_len, b0, aad, a, b);
+ m_copydata(m, m->m_pkthdr.len - ccmp_get_trailer_len(key),
+ ccmp_get_trailer_len(key), mic);
+ xor_block(mic, b, ccmp_get_trailer_len(key));
i = 1;
- pos = mtod(m, uint8_t *) + hdrlen + ccmp.ic_header;
- space = m->m_len - (hdrlen + ccmp.ic_header);
+ pos = mtod(m, uint8_t *) + hdrlen + ccmp_get_header_len(key);
+ space = m->m_len - (hdrlen + ccmp_get_header_len(key));
for (;;) {
if (space > data_len)
space = data_len;
@@ -665,7 +739,7 @@
space = m->m_len;
}
}
- if (memcmp(mic, a, ccmp.ic_trailer) != 0) {
+ if (memcmp(mic, a, ccmp_get_trailer_len(key)) != 0) {
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
"%s", "AES-CCM decrypt failed; MIC mismatch");
vap->iv_stats.is_rx_ccmpmic++;
@@ -678,4 +752,5 @@
/*
* Module glue.
*/
-IEEE80211_CRYPTO_MODULE(ccmp, 1);
+IEEE80211_CRYPTO_MODULE(ccmp_128, 1);
+IEEE80211_CRYPTO_MODULE_ADD(ccmp_256);
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -1385,6 +1385,9 @@
case RSN_SEL(RSN_CSE_CCMP):
*cipher = IEEE80211_CIPHER_AES_CCM;
break;
+ case RSN_SEL(RSN_CSE_CCMP_256):
+ *cipher = IEEE80211_CIPHER_AES_CCM_256;
+ break;
case RSN_SEL(RSN_CSE_WRAP):
*cipher = IEEE80211_CIPHER_AES_OCB;
break;
@@ -1500,8 +1503,10 @@
frm += 4, len -= 4;
}
- if (w & (1 << IEEE80211_CIPHER_AES_CCM))
- rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
+ if (w & (1 << IEEE80211_CIPHER_AES_CCM_256))
+ rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM_256;
+ else if (w & (1 << IEEE80211_CIPHER_AES_CCM))
+ rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
else if (w & (1 << IEEE80211_CIPHER_AES_OCB))
rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_OCB;
else if (w & (1 << IEEE80211_CIPHER_TKIP))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 2, 3:11 AM (17 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17897062
Default Alt Text
D44921.diff (8 KB)
Attached To
Mode
D44921: net80211: add 256 bit CCMP support
Attached
Detach File
Event Timeline
Log In to Comment