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>
This commit is contained in:
Nachiket Kukade 2020-09-02 15:02:45 +05:30
parent d1fa5c712a
commit 4d8ba4b4de
6 changed files with 29 additions and 20 deletions

View file

@ -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 @@
Subproject commit 9c05e33052762634be655b50d911475e9384ba89
Subproject commit f6b42143050858677aa2e69ed2a9ee0ffb12a871

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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,