Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111872426
D49238.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
D49238.diff
View Options
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,6 +66,7 @@
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);
@@ -74,7 +78,7 @@
.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,46 @@
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);
+}
+
+/**
+ * @brief Return the M parameter to use for CCMP block0 initialisation.
+ *
+ * M is defined as the number of bytes in the authentication
+ * field.
+ *
+ * See RFC3610, Section 2 (CCM Mode Specification) for more
+ * information.
+ *
+ * The MIC size is defined in 802.11-2020 12.5.3
+ * (CTR with CBC-MAC Protocol (CCMP)).
+ *
+ * CCM-128 - M=8, MIC is 8 octets.
+ * CCM-256 - M=16, MIC is 16 octets.
+ *
+ * @param key ieee80211_key to calculate M for
+ * @retval the number of bytes in the authentication field
+ */
+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 +197,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 +264,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);
@@ -290,13 +367,14 @@
* 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));
}
if ((rxs == NULL) || (rxs->c_pktflags & IEEE80211_RX_F_MIC_STRIP) == 0)
- m_adj(m, -ccmp.ic_trailer);
+ m_adj(m, -ccmp_get_trailer_len(k));
/*
* Ok to update rsc now.
@@ -348,18 +426,28 @@
static void
ccmp_init_blocks(rijndael_ctx *ctx, struct ieee80211_frame *wh,
- u_int64_t pn, size_t dlen,
+ 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=3 or 7 (8 or 16 octet auth field),
+ * L=1 (2-octet Dlen))
+ * Adata=1 (one or more auth blocks present)
* Nonce: 0x00 | A2 | PN
- * Dlen */
- b0[0] = 0x59;
+ * Dlen
+ */
+ b0[0] = 0x40 | 0x01 | (m << 3);
/* NB: b0[1] set below */
IEEE80211_ADDR_COPY(b0 + 2, wh->i_addr2);
b0[8] = pn >> 40;
@@ -381,6 +469,7 @@
aad[0] = 0; /* AAD length >> 8 */
/* NB: aad[1] set below */
aad[2] = wh->i_fc[0] & 0x8f; /* XXX magic #s */
+ /* TODO: 802.11-2016 12.5.3.3.3 - QoS control field mask */
aad[3] = wh->i_fc[1] & 0xc7; /* XXX magic #s */
/* NB: we know 3 addresses are contiguous */
memcpy(aad + 4, wh->i_addr1, 3 * IEEE80211_ADDR_LEN);
@@ -465,14 +554,14 @@
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;
@@ -580,8 +669,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
@@ -618,14 +707,17 @@
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;
@@ -684,7 +776,7 @@
if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MIC_STRIP) != 0)
return (1);
- 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++;
@@ -698,3 +790,4 @@
* Module glue.
*/
IEEE80211_CRYPTO_MODULE(ccmp, 1);
+IEEE80211_CRYPTO_MODULE_ADD(ccmp_256);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 10, 3:21 PM (16 h, 5 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17074139
Default Alt Text
D49238.diff (8 KB)
Attached To
Mode
D49238: net80211: Refactor CCMP-128 support; add CCMP-256 support
Attached
Detach File
Event Timeline
Log In to Comment