]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
crypto: omap-aes-gcm - fix failure with assocdata only
authorTero Kristo <t-kristo@ti.com>
Tue, 5 Nov 2019 14:01:06 +0000 (16:01 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 11 Dec 2019 08:36:59 +0000 (16:36 +0800)
If we only have assocdata with an omap-aes-gcm, it currently just
completes it directly without passing it over to the crypto HW. This
produces wrong results.

Fix by passing the request down to the crypto HW, and fix the DMA
support code to accept a case where we don't expect any output data.
In the case where only assocdata is provided, it just passes through
the accelerator and provides authentication results, without any
encrypted/decrypted buffer via DMA.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/omap-aes-gcm.c
drivers/crypto/omap-aes.c

index 6da05149b195c19d3300d8805d1c6ee775690700..e92000846f1605adfe265b81d30c9ecb959c6c51 100644 (file)
@@ -244,7 +244,7 @@ static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
 
        err = omap_aes_write_ctrl(dd);
        if (!err) {
-               if (dd->in_sg_len && dd->out_sg_len)
+               if (dd->in_sg_len)
                        err = omap_aes_crypt_dma_start(dd);
                else
                        omap_aes_gcm_dma_out_callback(dd);
index d63ab370030e0b25bbc996968d03e7f984dedf65..758c93908fa54af942bbd6d053afd0df3b7a4d84 100644 (file)
@@ -269,13 +269,14 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
                              struct scatterlist *out_sg,
                              int in_sg_len, int out_sg_len)
 {
-       struct dma_async_tx_descriptor *tx_in, *tx_out;
+       struct dma_async_tx_descriptor *tx_in, *tx_out = NULL, *cb_desc;
        struct dma_slave_config cfg;
        int ret;
 
        if (dd->pio_only) {
                scatterwalk_start(&dd->in_walk, dd->in_sg);
-               scatterwalk_start(&dd->out_walk, dd->out_sg);
+               if (out_sg_len)
+                       scatterwalk_start(&dd->out_walk, dd->out_sg);
 
                /* Enable DATAIN interrupt and let it take
                   care of the rest */
@@ -312,34 +313,45 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
 
        /* No callback necessary */
        tx_in->callback_param = dd;
+       tx_in->callback = NULL;
 
        /* OUT */
-       ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
-       if (ret) {
-               dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
-                       ret);
-               return ret;
-       }
+       if (out_sg_len) {
+               ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
+               if (ret) {
+                       dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
+                               ret);
+                       return ret;
+               }
 
-       tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, out_sg_len,
-                                       DMA_DEV_TO_MEM,
-                                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-       if (!tx_out) {
-               dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
-               return -EINVAL;
+               tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg,
+                                                out_sg_len,
+                                                DMA_DEV_TO_MEM,
+                                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (!tx_out) {
+                       dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
+                       return -EINVAL;
+               }
+
+               cb_desc = tx_out;
+       } else {
+               cb_desc = tx_in;
        }
 
        if (dd->flags & FLAGS_GCM)
-               tx_out->callback = omap_aes_gcm_dma_out_callback;
+               cb_desc->callback = omap_aes_gcm_dma_out_callback;
        else
-               tx_out->callback = omap_aes_dma_out_callback;
-       tx_out->callback_param = dd;
+               cb_desc->callback = omap_aes_dma_out_callback;
+       cb_desc->callback_param = dd;
+
 
        dmaengine_submit(tx_in);
-       dmaengine_submit(tx_out);
+       if (tx_out)
+               dmaengine_submit(tx_out);
 
        dma_async_issue_pending(dd->dma_lch_in);
-       dma_async_issue_pending(dd->dma_lch_out);
+       if (out_sg_len)
+               dma_async_issue_pending(dd->dma_lch_out);
 
        /* start DMA */
        dd->pdata->trigger(dd, dd->total);
@@ -361,11 +373,13 @@ int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
                        return -EINVAL;
                }
 
-               err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
-                                DMA_FROM_DEVICE);
-               if (!err) {
-                       dev_err(dd->dev, "dma_map_sg() error\n");
-                       return -EINVAL;
+               if (dd->out_sg_len) {
+                       err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
+                                        DMA_FROM_DEVICE);
+                       if (!err) {
+                               dev_err(dd->dev, "dma_map_sg() error\n");
+                               return -EINVAL;
+                       }
                }
        }
 
@@ -373,8 +387,9 @@ int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
                                 dd->out_sg_len);
        if (err && !dd->pio_only) {
                dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
-               dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
-                            DMA_FROM_DEVICE);
+               if (dd->out_sg_len)
+                       dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
+                                    DMA_FROM_DEVICE);
        }
 
        return err;