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:
parent
d1fa5c712a
commit
4d8ba4b4de
6 changed files with 29 additions and 20 deletions
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue