Page MenuHomeFreeBSD

D49367.id152286.diff
No OneTemporary

D49367.id152286.diff

diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h
--- a/sys/net80211/ieee80211_crypto.h
+++ b/sys/net80211/ieee80211_crypto.h
@@ -274,5 +274,11 @@
uint64_t rsc, int tid);
void ieee80211_notify_michael_failure(struct ieee80211vap *,
const struct ieee80211_frame *, u_int keyix);
+
+/* AAD assembly for CCMP/GCMP. */
+int ieee80211_crypto_init_aad(const struct ieee80211_frame *,
+ uint8_t *, int);
+
+
#endif /* defined(__KERNEL__) || defined(_KERNEL) */
#endif /* _NET80211_IEEE80211_CRYPTO_H_ */
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
@@ -884,3 +884,86 @@
vap->iv_update_deftxkey(vap, kid);
}
+
+/**
+ * @brief Calculate the AAD required for this frame for AES-GCM/AES-CCM.
+ *
+ * NOTE: the first two bytes are a 16 bit big-endian length, which are used
+ * by AES-CCM. AES-GCM doesn't require the length at the beginning and will
+ * need to skip it.
+ *
+ * @param wh 802.11 frame to calculate the AAD over
+ * @param aad AAD buffer
+ * @param len The AAD buffer length in bytes.
+ * @returns The number of AAD payload bytes (ignoring the first two
+ * bytes, which are the AAD payload length in big-endian.)
+ */
+int
+ieee80211_crypto_init_aad(const struct ieee80211_frame *wh, uint8_t *aad,
+ int len)
+{
+ int aad_len;
+
+ memset(aad, 0, len);
+
+ /* AAD:
+ * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
+ * A1 | A2 | A3
+ * SC with bits 4..15 (seq#) masked to zero
+ * A4 (if present)
+ * QC (if present)
+ */
+ aad[0] = 0; /* AAD length >> 8 */
+ /* NB: aad[1] set below */
+
+ /*
+ * TODO: go back over this in 802.11-2020 and triple check
+ * the AAD assembly with regards to packet flags.
+ */
+
+ aad[2] = wh->i_fc[0] & 0x8f; /* XXX magic #s */
+ /*
+ * TODO: 12.5.3.3.3 - bit 14 should always be set; bit 15 masked to 0
+ * if QoS control field, unmasked otherwise
+ */
+ 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);
+ aad[22] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK;
+ aad[23] = 0; /* all bits masked */
+ /*
+ * Construct variable-length portion of AAD based
+ * on whether this is a 4-address frame/QOS frame.
+ * We always zero-pad to 32 bytes before running it
+ * through the cipher.
+ */
+ if (IEEE80211_IS_DSTODS(wh)) {
+ IEEE80211_ADDR_COPY(aad + 24,
+ ((const struct ieee80211_frame_addr4 *)wh)->i_addr4);
+ if (IEEE80211_QOS_HAS_SEQ(wh)) {
+ const struct ieee80211_qosframe_addr4 *qwh4 =
+ (const struct ieee80211_qosframe_addr4 *) wh;
+ aad[30] = qwh4->i_qos[0] & 0x0f;/* just priority bits */
+ aad[31] = 0;
+ aad_len = aad[1] = 22 + IEEE80211_ADDR_LEN + 2;
+ } else {
+ *(uint16_t *)&aad[30] = 0;
+ aad_len = aad[1] = 22 + IEEE80211_ADDR_LEN;
+ }
+ } else {
+ if (IEEE80211_QOS_HAS_SEQ(wh)) {
+ const struct ieee80211_qosframe *qwh =
+ (const struct ieee80211_qosframe*) wh;
+ aad[24] = qwh->i_qos[0] & 0x0f; /* just priority bits */
+ aad[25] = 0;
+ aad_len = aad[1] = 22 + 2;
+ } else {
+ *(uint16_t *)&aad[24] = 0;
+ aad_len = aad[1] = 22;
+ }
+ *(uint16_t *)&aad[26] = 0;
+ *(uint32_t *)&aad[28] = 0;
+ }
+
+ return (aad_len);
+}
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
@@ -410,6 +410,30 @@
b[i] ^= a[i];
}
+static void
+ieee80211_crypto_ccmp_init_priority(const struct ieee80211_frame *wh,
+ char *b0)
+{
+ if (IEEE80211_IS_DSTODS(wh)) {
+ if (IEEE80211_QOS_HAS_SEQ(wh)) {
+ const struct ieee80211_qosframe_addr4 *qwh4 =
+ (const struct ieee80211_qosframe_addr4 *) wh;
+
+ b0[1] = qwh4->i_qos[0] & 0x0f; /* prio bits */
+ } else {
+ b0[1] = 0;
+ }
+ } else {
+ if (IEEE80211_QOS_HAS_SEQ(wh)) {
+ const struct ieee80211_qosframe *qwh =
+ (const struct ieee80211_qosframe *) wh;
+ b0[1] = qwh->i_qos[0] & 0x0f; /* prio bits */
+ } else {
+ b0[1] = 0;
+ }
+ }
+}
+
/*
* Host AP crypt: host-based CCMP encryption implementation for Host AP driver
*
@@ -430,8 +454,6 @@
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)
@@ -448,7 +470,8 @@
* Dlen
*/
b0[0] = 0x40 | 0x01 | (m << 3);
- /* NB: b0[1] set below */
+ /* Init b0[1] (priority) */
+ ieee80211_crypto_ccmp_init_priority(wh, b0);
IEEE80211_ADDR_COPY(b0 + 2, wh->i_addr2);
b0[8] = pn >> 40;
b0[9] = pn >> 32;
@@ -459,63 +482,8 @@
b0[14] = (dlen >> 8) & 0xff;
b0[15] = dlen & 0xff;
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- 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);
- aad[22] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK;
- aad[23] = 0; /* all bits masked */
- /*
- * Construct variable-length portion of AAD based
- * on whether this is a 4-address frame/QOS frame.
- * We always zero-pad to 32 bytes before running it
- * through the cipher.
- *
- * We also fill in the priority bits of the CCM
- * initial block as we know whether or not we have
- * a QOS frame.
- */
- if (IEEE80211_IS_DSTODS(wh)) {
- IEEE80211_ADDR_COPY(aad + 24,
- ((struct ieee80211_frame_addr4 *)wh)->i_addr4);
- if (IS_QOS_DATA(wh)) {
- struct ieee80211_qosframe_addr4 *qwh4 =
- (struct ieee80211_qosframe_addr4 *) wh;
- aad[30] = qwh4->i_qos[0] & 0x0f;/* just priority bits */
- aad[31] = 0;
- b0[1] = aad[30];
- aad[1] = 22 + IEEE80211_ADDR_LEN + 2;
- } else {
- *(uint16_t *)&aad[30] = 0;
- b0[1] = 0;
- aad[1] = 22 + IEEE80211_ADDR_LEN;
- }
- } else {
- if (IS_QOS_DATA(wh)) {
- struct ieee80211_qosframe *qwh =
- (struct ieee80211_qosframe*) wh;
- aad[24] = qwh->i_qos[0] & 0x0f; /* just priority bits */
- aad[25] = 0;
- b0[1] = aad[24];
- aad[1] = 22 + 2;
- } else {
- *(uint16_t *)&aad[24] = 0;
- b0[1] = 0;
- aad[1] = 22;
- }
- *(uint16_t *)&aad[26] = 0;
- *(uint32_t *)&aad[28] = 0;
- }
+ /* Init AAD */
+ (void) ieee80211_crypto_init_aad(wh, aad, 2 * AES_BLOCK_LEN);
/* Start with the first block and AAD */
rijndael_encrypt(ctx, b0, auth);
@@ -526,7 +494,6 @@
b0[0] &= 0x07;
b0[14] = b0[15] = 0;
rijndael_encrypt(ctx, b0, s0);
-#undef IS_QOS_DATA
}
#define CCMP_ENCRYPT(_i, _b, _b0, _pos, _e, _len) do { \
diff --git a/sys/net80211/ieee80211_crypto_gcmp.c b/sys/net80211/ieee80211_crypto_gcmp.c
--- a/sys/net80211/ieee80211_crypto_gcmp.c
+++ b/sys/net80211/ieee80211_crypto_gcmp.c
@@ -380,90 +380,6 @@
return (1);
}
-/**
- * @brief Calculate the AAD required for this frame for AES-GCM.
- *
- * Note: This code was first copied over from ieee80211_crypto_ccmp.c, so
- * it has some CCMP-isms.
- *
- * NOTE: the first two bytes are a 16 bit big-endian length, which are used
- * by AES-CCM. AES-GCM doesn't require the length at the beginning.
- *
- * @param wh 802.11 frame to calculate the AAD over
- * @param aad AAD buffer, GCM_AAD_LEN bytes
- * @param The AAD length in bytes.
- */
-static int
-gcmp_init_aad(const struct ieee80211_frame *wh, uint8_t *aad)
-{
- int aad_len;
-
- memset(aad, 0, GCM_AAD_LEN);
-
-#define IS_QOS_DATA(wh) IEEE80211_QOS_HAS_SEQ(wh)
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- aad[0] = 0; /* AAD length >> 8 */
- /* NB: aad[1] set below */
-
- /*
- * TODO: go back over this in 802.11-2020 and triple check
- * the AAD assembly with regards to packet flags.
- */
-
- aad[2] = wh->i_fc[0] & 0x8f; /* XXX magic #s */
- /*
- * TODO: 12.5.3.3.3 - bit 14 should always be set; bit 15 masked to 0
- * if QoS control field, unmasked otherwise
- */
- 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);
- aad[22] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK;
- aad[23] = 0; /* all bits masked */
- /*
- * Construct variable-length portion of AAD based
- * on whether this is a 4-address frame/QOS frame.
- * We always zero-pad to 32 bytes before running it
- * through the cipher.
- */
- if (IEEE80211_IS_DSTODS(wh)) {
- IEEE80211_ADDR_COPY(aad + 24,
- ((const struct ieee80211_frame_addr4 *)wh)->i_addr4);
- if (IS_QOS_DATA(wh)) {
- const struct ieee80211_qosframe_addr4 *qwh4 =
- (const struct ieee80211_qosframe_addr4 *) wh;
- aad[30] = qwh4->i_qos[0] & 0x0f;/* just priority bits */
- aad[31] = 0;
- aad_len = aad[1] = 22 + IEEE80211_ADDR_LEN + 2;
- } else {
- *(uint16_t *)&aad[30] = 0;
- aad_len = aad[1] = 22 + IEEE80211_ADDR_LEN;
- }
- } else {
- if (IS_QOS_DATA(wh)) {
- const struct ieee80211_qosframe *qwh =
- (const struct ieee80211_qosframe*) wh;
- aad[24] = qwh->i_qos[0] & 0x0f; /* just priority bits */
- aad[25] = 0;
- aad_len = aad[1] = 22 + 2;
- } else {
- *(uint16_t *)&aad[24] = 0;
- aad_len = aad[1] = 22;
- }
- *(uint16_t *)&aad[26] = 0;
- *(uint32_t *)&aad[28] = 0;
- }
-#undef IS_QOS_DATA
-
- return (aad_len);
-}
-
/*
* Populate the 12 byte / 96 bit IV buffer.
*/
@@ -538,7 +454,7 @@
}
/* Initialise AAD */
- aad_len = gcmp_init_aad(wh, aad);
+ aad_len = ieee80211_crypto_init_aad(wh, aad, GCM_AAD_LEN);
/* Initialise local Nonce to work on */
/* TODO: rename iv stuff here to nonce */
@@ -629,7 +545,7 @@
}
/* Initialise AAD */
- aad_len = gcmp_init_aad(wh, aad);
+ aad_len = ieee80211_crypto_init_aad(wh, aad, GCM_AAD_LEN);
/* Initialise local IV copy to work on */
iv_len = gcmp_init_iv(iv, wh, pn);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 14, 9:51 PM (4 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31500075
Default Alt Text
D49367.id152286.diff (9 KB)

Event Timeline