Skip to content

Commit 5d5f3ee

Browse files
Tero Kristoherbertx
authored andcommitted
crypto: omap-aes-gcm - fix failure with assocdata only
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>
1 parent f0956d4 commit 5d5f3ee

File tree

2 files changed

+42
-27
lines changed

2 files changed

+42
-27
lines changed

drivers/crypto/omap-aes-gcm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
244244

245245
err = omap_aes_write_ctrl(dd);
246246
if (!err) {
247-
if (dd->in_sg_len && dd->out_sg_len)
247+
if (dd->in_sg_len)
248248
err = omap_aes_crypt_dma_start(dd);
249249
else
250250
omap_aes_gcm_dma_out_callback(dd);

drivers/crypto/omap-aes.c

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,14 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
269269
struct scatterlist *out_sg,
270270
int in_sg_len, int out_sg_len)
271271
{
272-
struct dma_async_tx_descriptor *tx_in, *tx_out;
272+
struct dma_async_tx_descriptor *tx_in, *tx_out = NULL, *cb_desc;
273273
struct dma_slave_config cfg;
274274
int ret;
275275

276276
if (dd->pio_only) {
277277
scatterwalk_start(&dd->in_walk, dd->in_sg);
278-
scatterwalk_start(&dd->out_walk, dd->out_sg);
278+
if (out_sg_len)
279+
scatterwalk_start(&dd->out_walk, dd->out_sg);
279280

280281
/* Enable DATAIN interrupt and let it take
281282
care of the rest */
@@ -312,34 +313,45 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
312313

313314
/* No callback necessary */
314315
tx_in->callback_param = dd;
316+
tx_in->callback = NULL;
315317

316318
/* OUT */
317-
ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
318-
if (ret) {
319-
dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
320-
ret);
321-
return ret;
322-
}
319+
if (out_sg_len) {
320+
ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
321+
if (ret) {
322+
dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
323+
ret);
324+
return ret;
325+
}
323326

324-
tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, out_sg_len,
325-
DMA_DEV_TO_MEM,
326-
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
327-
if (!tx_out) {
328-
dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
329-
return -EINVAL;
327+
tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg,
328+
out_sg_len,
329+
DMA_DEV_TO_MEM,
330+
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
331+
if (!tx_out) {
332+
dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
333+
return -EINVAL;
334+
}
335+
336+
cb_desc = tx_out;
337+
} else {
338+
cb_desc = tx_in;
330339
}
331340

332341
if (dd->flags & FLAGS_GCM)
333-
tx_out->callback = omap_aes_gcm_dma_out_callback;
342+
cb_desc->callback = omap_aes_gcm_dma_out_callback;
334343
else
335-
tx_out->callback = omap_aes_dma_out_callback;
336-
tx_out->callback_param = dd;
344+
cb_desc->callback = omap_aes_dma_out_callback;
345+
cb_desc->callback_param = dd;
346+
337347

338348
dmaengine_submit(tx_in);
339-
dmaengine_submit(tx_out);
349+
if (tx_out)
350+
dmaengine_submit(tx_out);
340351

341352
dma_async_issue_pending(dd->dma_lch_in);
342-
dma_async_issue_pending(dd->dma_lch_out);
353+
if (out_sg_len)
354+
dma_async_issue_pending(dd->dma_lch_out);
343355

344356
/* start DMA */
345357
dd->pdata->trigger(dd, dd->total);
@@ -361,20 +373,23 @@ int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
361373
return -EINVAL;
362374
}
363375

364-
err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
365-
DMA_FROM_DEVICE);
366-
if (!err) {
367-
dev_err(dd->dev, "dma_map_sg() error\n");
368-
return -EINVAL;
376+
if (dd->out_sg_len) {
377+
err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
378+
DMA_FROM_DEVICE);
379+
if (!err) {
380+
dev_err(dd->dev, "dma_map_sg() error\n");
381+
return -EINVAL;
382+
}
369383
}
370384
}
371385

372386
err = omap_aes_crypt_dma(dd, dd->in_sg, dd->out_sg, dd->in_sg_len,
373387
dd->out_sg_len);
374388
if (err && !dd->pio_only) {
375389
dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
376-
dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
377-
DMA_FROM_DEVICE);
390+
if (dd->out_sg_len)
391+
dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
392+
DMA_FROM_DEVICE);
378393
}
379394

380395
return err;

0 commit comments

Comments
 (0)