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
|
@ -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: Pointer to encrypted data buffer
|
||||||
* @data_len: Encrypted data length in bytes
|
* @data_len: Encrypted data length in bytes
|
||||||
* @decrypted_len: Length of decrypted data
|
* @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
|
* 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,
|
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
|
* @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 */
|
/* 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,
|
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;
|
const size_t L = 2;
|
||||||
void *aes;
|
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) */
|
/* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */
|
||||||
aes_ccm_encr(aes, L, crypt, crypt_len, plain, a);
|
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_start(aes, M, L, nonce, aad, aad_len, crypt_len, x);
|
||||||
aes_ccm_auth(aes, plain, 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,
|
int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce,
|
||||||
size_t M, const u8 *plain, size_t plain_len,
|
size_t M, const u8 *plain, size_t plain_len,
|
||||||
const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth);
|
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,
|
size_t M, const u8 *crypt, size_t crypt_len,
|
||||||
const u8 *aad, size_t aad_len, const u8 *auth,
|
const u8 *aad, size_t aad_len, const u8 *auth,
|
||||||
u8 *plain);
|
u8 *plain, bool skip_auth);
|
||||||
#endif /* AES_H */
|
#endif /* AES_H */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "aes_wrap.h"
|
#include "aes_wrap.h"
|
||||||
|
|
||||||
static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data,
|
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;
|
u16 fc, stype, seq;
|
||||||
int qos = 0, addr4 = 0;
|
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;
|
qc += ETH_ALEN;
|
||||||
nonce[0] = qc[0] & 0x0f;
|
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 */
|
nonce[0] |= 0x10; /* Management */
|
||||||
|
|
||||||
fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
|
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,
|
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];
|
u8 aad[30], nonce[13];
|
||||||
size_t aad_len;
|
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;
|
mlen = data_len - 8 - 8;
|
||||||
|
|
||||||
os_memset(aad, 0, sizeof(aad));
|
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,
|
||||||
//wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len);
|
nonce, espnow_pkt);
|
||||||
//wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13);
|
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,
|
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);
|
os_free(plain);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
//wpa_hexdump(MSG_DEBUG, "CCMP decrypted", plain, mlen);
|
wpa_hexdump(MSG_DEBUG, "CCMP decrypted", plain, mlen);
|
||||||
|
|
||||||
*decrypted_len = mlen;
|
*decrypted_len = mlen;
|
||||||
return plain;
|
return plain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ccmp_get_pn(u8 *pn, const u8 *data)
|
void ccmp_get_pn(u8 *pn, const u8 *data)
|
||||||
{
|
{
|
||||||
pn[0] = data[7]; /* PN5 */
|
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 */
|
*pos++ = pn[0]; /* PN5 */
|
||||||
|
|
||||||
os_memset(aad, 0, sizeof(aad));
|
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 AAD", aad, aad_len);
|
||||||
wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13);
|
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;
|
mlen = data_len - 8 - 16;
|
||||||
|
|
||||||
os_memset(aad, 0, sizeof(aad));
|
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 AAD", aad, aad_len);
|
||||||
wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13);
|
wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13);
|
||||||
|
|
||||||
if (aes_ccm_ad(tk, 32, nonce, 16, data + 8, mlen, aad, aad_len,
|
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);
|
os_free(plain);
|
||||||
return NULL;
|
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 */
|
*pos++ = pn[0]; /* PN5 */
|
||||||
|
|
||||||
os_memset(aad, 0, sizeof(aad));
|
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 AAD", aad, aad_len);
|
||||||
wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13);
|
wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define CCMP_H
|
#define CCMP_H
|
||||||
|
|
||||||
u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, const u8 *data,
|
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 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
|
||||||
u8 *pn, int keyid, size_t *encrypted_len);
|
u8 *pn, int keyid, size_t *encrypted_len);
|
||||||
u8 * ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3,
|
u8 * ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3,
|
||||||
|
|
Loading…
Reference in a new issue