Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152285298
D49367.id152286.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D49367.id152286.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D49367: net80211: refactor out the AAD init code shared between GCMP and CCMP
Attached
Detach File
Event Timeline
Log In to Comment