Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: mac80211: fix CMAC functions not handling errors

The called hash functions could fail thus we should check return values.

Fixes: 26717828b75d ("mac80211: aes-cmac: switch to shash CMAC driver")
Signed-off-by: Chien Wong <m@xv97.com>
Link: https://patch.msgid.link/20251113140511.48658-2-m@xv97.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Chien Wong and committed by
Johannes Berg
353cda30 799e9870

+61 -30
+45 -18
net/mac80211/aes_cmac.c
··· 22 22 23 23 static const u8 zero[CMAC_TLEN_256]; 24 24 25 - void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 26 - const u8 *data, size_t data_len, u8 *mic) 25 + int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 26 + const u8 *data, size_t data_len, u8 *mic) 27 27 { 28 + int err; 28 29 SHASH_DESC_ON_STACK(desc, tfm); 29 30 u8 out[AES_BLOCK_SIZE]; 30 31 const __le16 *fc; 31 32 32 33 desc->tfm = tfm; 33 34 34 - crypto_shash_init(desc); 35 - crypto_shash_update(desc, aad, AAD_LEN); 35 + err = crypto_shash_init(desc); 36 + if (err) 37 + return err; 38 + err = crypto_shash_update(desc, aad, AAD_LEN); 39 + if (err) 40 + return err; 36 41 fc = (const __le16 *)aad; 37 42 if (ieee80211_is_beacon(*fc)) { 38 43 /* mask Timestamp field to zero */ 39 - crypto_shash_update(desc, zero, 8); 40 - crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); 44 + err = crypto_shash_update(desc, zero, 8); 45 + if (err) 46 + return err; 47 + err = crypto_shash_update(desc, data + 8, 48 + data_len - 8 - CMAC_TLEN); 49 + if (err) 50 + return err; 41 51 } else { 42 - crypto_shash_update(desc, data, data_len - CMAC_TLEN); 52 + err = crypto_shash_update(desc, data, 53 + data_len - CMAC_TLEN); 54 + if (err) 55 + return err; 43 56 } 44 - crypto_shash_finup(desc, zero, CMAC_TLEN, out); 45 - 57 + err = crypto_shash_finup(desc, zero, CMAC_TLEN, out); 58 + if (err) 59 + return err; 46 60 memcpy(mic, out, CMAC_TLEN); 61 + 62 + return 0; 47 63 } 48 64 49 - void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, 50 - const u8 *data, size_t data_len, u8 *mic) 65 + int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, 66 + const u8 *data, size_t data_len, u8 *mic) 51 67 { 68 + int err; 52 69 SHASH_DESC_ON_STACK(desc, tfm); 53 70 const __le16 *fc; 54 71 55 72 desc->tfm = tfm; 56 73 57 - crypto_shash_init(desc); 58 - crypto_shash_update(desc, aad, AAD_LEN); 74 + err = crypto_shash_init(desc); 75 + if (err) 76 + return err; 77 + err = crypto_shash_update(desc, aad, AAD_LEN); 78 + if (err) 79 + return err; 59 80 fc = (const __le16 *)aad; 60 81 if (ieee80211_is_beacon(*fc)) { 61 82 /* mask Timestamp field to zero */ 62 - crypto_shash_update(desc, zero, 8); 63 - crypto_shash_update(desc, data + 8, 64 - data_len - 8 - CMAC_TLEN_256); 83 + err = crypto_shash_update(desc, zero, 8); 84 + if (err) 85 + return err; 86 + err = crypto_shash_update(desc, data + 8, 87 + data_len - 8 - CMAC_TLEN_256); 88 + if (err) 89 + return err; 65 90 } else { 66 - crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); 91 + err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); 92 + if (err) 93 + return err; 67 94 } 68 - crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); 95 + return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); 69 96 } 70 97 71 98 struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
+4 -4
net/mac80211/aes_cmac.h
··· 11 11 12 12 struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], 13 13 size_t key_len); 14 - void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 15 - const u8 *data, size_t data_len, u8 *mic); 16 - void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, 17 - const u8 *data, size_t data_len, u8 *mic); 14 + int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 15 + const u8 *data, size_t data_len, u8 *mic); 16 + int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, 17 + const u8 *data, size_t data_len, u8 *mic); 18 18 void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); 19 19 20 20 #endif /* AES_CMAC_H */
+12 -8
net/mac80211/wpa.c
··· 869 869 /* 870 870 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) 871 871 */ 872 - ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 873 - skb->data + 24, skb->len - 24, mmie->mic); 872 + if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 873 + skb->data + 24, skb->len - 24, mmie->mic)) 874 + return TX_DROP; 874 875 875 876 return TX_CONTINUE; 876 877 } ··· 917 916 918 917 /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) 919 918 */ 920 - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, 921 - skb->data + 24, skb->len - 24, mmie->mic); 919 + if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, 920 + skb->data + 24, skb->len - 24, mmie->mic)) 921 + return TX_DROP; 922 922 923 923 return TX_CONTINUE; 924 924 } ··· 958 956 if (!(status->flag & RX_FLAG_DECRYPTED)) { 959 957 /* hardware didn't decrypt/verify MIC */ 960 958 bip_aad(skb, aad); 961 - ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 962 - skb->data + 24, skb->len - 24, mic); 959 + if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 960 + skb->data + 24, skb->len - 24, mic)) 961 + return RX_DROP_U_DECRYPT_FAIL; 963 962 if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { 964 963 key->u.aes_cmac.icverrors++; 965 964 return RX_DROP_U_MIC_FAIL; ··· 1009 1006 if (!(status->flag & RX_FLAG_DECRYPTED)) { 1010 1007 /* hardware didn't decrypt/verify MIC */ 1011 1008 bip_aad(skb, aad); 1012 - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, 1013 - skb->data + 24, skb->len - 24, mic); 1009 + if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, 1010 + skb->data + 24, skb->len - 24, mic)) 1011 + return RX_DROP_U_DECRYPT_FAIL; 1014 1012 if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { 1015 1013 key->u.aes_cmac.icverrors++; 1016 1014 return RX_DROP_U_MIC_FAIL;