]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211: fix CMAC functions not handling errors
authorChien Wong <m@xv97.com>
Thu, 13 Nov 2025 14:05:07 +0000 (22:05 +0800)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 20 Nov 2025 10:56:18 +0000 (11:56 +0100)
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>
net/mac80211/aes_cmac.c
net/mac80211/aes_cmac.h
net/mac80211/wpa.c

index 48c04f89de20af1b29572b4a712d04cca9c2e8f9..65989c7dfc680905506fa49bf20bc57e719b0ecb 100644 (file)
 
 static const u8 zero[CMAC_TLEN_256];
 
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
-                       const u8 *data, size_t data_len, u8 *mic)
+int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
+                      const u8 *data, size_t data_len, u8 *mic)
 {
+       int err;
        SHASH_DESC_ON_STACK(desc, tfm);
        u8 out[AES_BLOCK_SIZE];
        const __le16 *fc;
 
        desc->tfm = tfm;
 
-       crypto_shash_init(desc);
-       crypto_shash_update(desc, aad, AAD_LEN);
+       err = crypto_shash_init(desc);
+       if (err)
+               return err;
+       err = crypto_shash_update(desc, aad, AAD_LEN);
+       if (err)
+               return err;
        fc = (const __le16 *)aad;
        if (ieee80211_is_beacon(*fc)) {
                /* mask Timestamp field to zero */
-               crypto_shash_update(desc, zero, 8);
-               crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN);
+               err = crypto_shash_update(desc, zero, 8);
+               if (err)
+                       return err;
+               err = crypto_shash_update(desc, data + 8,
+                                         data_len - 8 - CMAC_TLEN);
+               if (err)
+                       return err;
        } else {
-               crypto_shash_update(desc, data, data_len - CMAC_TLEN);
+               err = crypto_shash_update(desc, data,
+                                         data_len - CMAC_TLEN);
+               if (err)
+                       return err;
        }
-       crypto_shash_finup(desc, zero, CMAC_TLEN, out);
-
+       err = crypto_shash_finup(desc, zero, CMAC_TLEN, out);
+       if (err)
+               return err;
        memcpy(mic, out, CMAC_TLEN);
+
+       return 0;
 }
 
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
-                           const u8 *data, size_t data_len, u8 *mic)
+int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
+                          const u8 *data, size_t data_len, u8 *mic)
 {
+       int err;
        SHASH_DESC_ON_STACK(desc, tfm);
        const __le16 *fc;
 
        desc->tfm = tfm;
 
-       crypto_shash_init(desc);
-       crypto_shash_update(desc, aad, AAD_LEN);
+       err = crypto_shash_init(desc);
+       if (err)
+               return err;
+       err = crypto_shash_update(desc, aad, AAD_LEN);
+       if (err)
+               return err;
        fc = (const __le16 *)aad;
        if (ieee80211_is_beacon(*fc)) {
                /* mask Timestamp field to zero */
-               crypto_shash_update(desc, zero, 8);
-               crypto_shash_update(desc, data + 8,
-                                   data_len - 8 - CMAC_TLEN_256);
+               err = crypto_shash_update(desc, zero, 8);
+               if (err)
+                       return err;
+               err = crypto_shash_update(desc, data + 8,
+                                         data_len - 8 - CMAC_TLEN_256);
+               if (err)
+                       return err;
        } else {
-               crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
+               err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
+               if (err)
+                       return err;
        }
-       crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
+       return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
 }
 
 struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
index 76817446fb8384d4f8d29c589293d0066a5db736..f74150542142a6c8b933c6c25c0c6bc38eccb97a 100644 (file)
 
 struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
                                                  size_t key_len);
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
-                       const u8 *data, size_t data_len, u8 *mic);
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
-                           const u8 *data, size_t data_len, u8 *mic);
+int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
+                      const u8 *data, size_t data_len, u8 *mic);
+int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
+                          const u8 *data, size_t data_len, u8 *mic);
 void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm);
 
 #endif /* AES_CMAC_H */
index 40d5d9e484791623f0c794de5485e83ef0bd4967..bb0fa505cdcaeeca1d1aa846b3eeb560721007f3 100644 (file)
@@ -869,8 +869,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
        /*
         * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
         */
-       ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
-                          skb->data + 24, skb->len - 24, mmie->mic);
+       if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
+                              skb->data + 24, skb->len - 24, mmie->mic))
+               return TX_DROP;
 
        return TX_CONTINUE;
 }
@@ -916,8 +917,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
 
        /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128)
         */
-       ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
-                              skb->data + 24, skb->len - 24, mmie->mic);
+       if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
+                                  skb->data + 24, skb->len - 24, mmie->mic))
+               return TX_DROP;
 
        return TX_CONTINUE;
 }
@@ -956,8 +958,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
        if (!(status->flag & RX_FLAG_DECRYPTED)) {
                /* hardware didn't decrypt/verify MIC */
                bip_aad(skb, aad);
-               ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
-                                  skb->data + 24, skb->len - 24, mic);
+               if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
+                                      skb->data + 24, skb->len - 24, mic))
+                       return RX_DROP_U_DECRYPT_FAIL;
                if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
                        key->u.aes_cmac.icverrors++;
                        return RX_DROP_U_MIC_FAIL;
@@ -1006,8 +1009,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
        if (!(status->flag & RX_FLAG_DECRYPTED)) {
                /* hardware didn't decrypt/verify MIC */
                bip_aad(skb, aad);
-               ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
-                                      skb->data + 24, skb->len - 24, mic);
+               if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
+                                          skb->data + 24, skb->len - 24, mic))
+                       return RX_DROP_U_DECRYPT_FAIL;
                if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
                        key->u.aes_cmac.icverrors++;
                        return RX_DROP_U_MIC_FAIL;