Просмотр исходного кода

espnow/pmf: Implement ESPNOW + PMF Co-existance

H/W decryption of Mgmt frames was disabled for PMF and done through
S/W. If ESPNOW packets go through this path, it affects backward
compatibility since method of decrypting Mgmt packets is different in H/W.

To address PMF + ESPNOW Co-existance, CCMP decryption method is modified
for ESPNOW packets so that they can be decrypted correctly. Since Tx
of ESPNOW packets can still be done in H/W alongside PMF, no change
required in encryption method in S/W.

Co-Authored-By: Nachiket Kukade <nachiket.kukade@espressif.com>
Co-Authored-By: zhangyanjiao <zhangyanjiao@espressif.com>
Co-Authored-By: kapil.gupta <kapil.gupta@espressif.com>
Nachiket Kukade 5 лет назад
Родитель
Сommit
4d8ba4b4de

+ 3 - 1
components/esp_wifi/include/esp_wifi_crypto_types.h

@@ -336,10 +336,12 @@ typedef int (*esp_omac1_aes_128_t)(const uint8_t *key, const uint8_t *data, size
  * @data: Pointer to encrypted data buffer
  * @data_len: Encrypted data length in bytes
  * @decrypted_len: Length of decrypted data
+ * @espnow_pkt: Indicates if it's an ESPNOW packet
  * Returns: Pointer to decrypted data on success, NULL on failure
  */
 typedef uint8_t * (*esp_ccmp_decrypt_t)(const uint8_t *tk, const uint8_t *ieee80211_hdr,
-                                        const uint8_t *data, size_t data_len, size_t *decrypted_len);
+                                        const uint8_t *data, size_t data_len,
+                                        size_t *decrypted_len, bool espnow_pkt);
 
 /**
  * @brief Encrypt data using CCMP (Counter Mode CBC-MAC Protocol OR

+ 1 - 1
components/esp_wifi/lib_esp32

@@ -1 +1 @@
-Subproject commit 9c05e33052762634be655b50d911475e9384ba89
+Subproject commit f6b42143050858677aa2e69ed2a9ee0ffb12a871

+ 8 - 2
components/wpa_supplicant/src/crypto/aes-ccm.c

@@ -177,9 +177,10 @@ int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce,
 
 
 /* AES-CCM with fixed L=2 and aad_len <= 30 assumption */
-int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce,
+int aes_ccm_ad(const u8 *key, size_t key_len, u8 *nonce,
 	       size_t M, const u8 *crypt, size_t crypt_len,
-	       const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain)
+	       const u8 *aad, size_t aad_len, const u8 *auth,
+	       u8 *plain, bool skip_auth)
 {
 	const size_t L = 2;
 	void *aes;
@@ -200,6 +201,11 @@ int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce,
 	/* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */
 	aes_ccm_encr(aes, L, crypt, crypt_len, plain, a);
 
+	if (skip_auth) {
+		aes_encrypt_deinit(aes);
+		return 0;
+	}
+
 	aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, crypt_len, x);
 	aes_ccm_auth(aes, plain, crypt_len, x);
 

+ 2 - 2
components/wpa_supplicant/src/crypto/aes.h

@@ -29,8 +29,8 @@ int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac);
 int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce,
                size_t M, const u8 *plain, size_t plain_len,
                const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth);
-int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce,
+int aes_ccm_ad(const u8 *key, size_t key_len, u8 *nonce,
                size_t M, const u8 *crypt, size_t crypt_len,
                const u8 *aad, size_t aad_len, const u8 *auth,
-               u8 *plain);
+               u8 *plain, bool skip_auth);
 #endif /* AES_H */

+ 14 - 13
components/wpa_supplicant/src/crypto/ccmp.c

@@ -16,7 +16,7 @@
 #include "aes_wrap.h"
 
 static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data,
-			   u8 *aad, size_t *aad_len, u8 *nonce)
+                           u8 *aad, size_t *aad_len, u8 *nonce, bool espnow_pkt)
 {
 	u16 fc, stype, seq;
 	int qos = 0, addr4 = 0;
@@ -41,7 +41,7 @@ static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data,
 				qc += ETH_ALEN;
 			nonce[0] = qc[0] & 0x0f;
 		}
-	} else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
+	} else if (!espnow_pkt && WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
 		nonce[0] |= 0x10; /* Management */
 
 	fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
@@ -136,7 +136,7 @@ static void ccmp_aad_nonce_pv1(const u8 *hdr, const u8 *a1, const u8 *a2,
 
 
 u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, const u8 *data,
-		  size_t data_len, size_t *decrypted_len)
+		  size_t data_len, size_t *decrypted_len, bool espnow_pkt)
 {
 	u8 aad[30], nonce[13];
 	size_t aad_len;
@@ -153,22 +153,22 @@ u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, const u8 *data,
 	mlen = data_len - 8 - 8;
 
 	os_memset(aad, 0, sizeof(aad));
-	ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad, &aad_len, nonce);
-	//wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len);
-	//wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13);
+	ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad, &aad_len,
+                   nonce, espnow_pkt);
+	wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len);
+	wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13);
 
 	if (aes_ccm_ad(tk, 16, nonce, 8, data + 8, mlen, aad, aad_len,
-		       data + 8 + mlen, plain) < 0) {
+                   data + 8 + mlen, plain, espnow_pkt ? true : false) < 0) {
 		os_free(plain);
 		return NULL;
 	}
-	//wpa_hexdump(MSG_DEBUG, "CCMP decrypted", plain, mlen);
+	wpa_hexdump(MSG_DEBUG, "CCMP decrypted", plain, mlen);
 
 	*decrypted_len = mlen;
 	return plain;
 }
 
-
 void ccmp_get_pn(u8 *pn, const u8 *data)
 {
 	pn[0] = data[7]; /* PN5 */
@@ -210,7 +210,7 @@ u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
 	*pos++ = pn[0]; /* PN5 */
 
 	os_memset(aad, 0, sizeof(aad));
-	ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce);
+	ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce, false);
 	wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len);
 	wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13);
 
@@ -288,12 +288,13 @@ u8 * ccmp_256_decrypt(const u8 *tk, const u8 *hdr, const u8 *data,
 	mlen = data_len - 8 - 16;
 
 	os_memset(aad, 0, sizeof(aad));
-	ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad, &aad_len, nonce);
+	ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad,
+                   &aad_len, nonce, false);
 	wpa_hexdump(MSG_DEBUG, "CCMP-256 AAD", aad, aad_len);
 	wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13);
 
 	if (aes_ccm_ad(tk, 32, nonce, 16, data + 8, mlen, aad, aad_len,
-		       data + 8 + mlen, plain) < 0) {
+		       data + 8 + mlen, plain, false) < 0) {
 		os_free(plain);
 		return NULL;
 	}
@@ -334,7 +335,7 @@ u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
 	*pos++ = pn[0]; /* PN5 */
 
 	os_memset(aad, 0, sizeof(aad));
-	ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce);
+	ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce, false);
 	wpa_hexdump(MSG_DEBUG, "CCMP-256 AAD", aad, aad_len);
 	wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13);
 

+ 1 - 1
components/wpa_supplicant/src/crypto/ccmp.h

@@ -11,7 +11,7 @@
 #define CCMP_H
 
 u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, const u8 *data,
-		  size_t data_len, size_t *decrypted_len);
+		  size_t data_len, size_t *decrypted_len, bool espnow_pkt);
 u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
 		  u8 *pn, int keyid, size_t *encrypted_len);
 u8 * ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3,