Hello,
omap_aes_(cbc/ctr)(encrypt/decrypt) don't return the updated IV, add the
code to do just that at the end of the operation.
In omap_aes_done_task(), omap_crypto_cleanup() is called with:
omap_crypto_cleanup(&dd->out_sgl, dd->orig_out, 0, dd->total_save,
FLAGS_OUT_DATA_ST_SHIFT, dd->flags);
this ends up in freeing the part of the omap_aes_dev structure starting
at the address of the out_sgl member.
As the memory released is soon reused the kernel crashes at the next
encrypt/decrypt call:
[ 334.559643] Unable to handle kernel paging request at virtual
address 30627375
[ 334.566922] pgd = c0004000
[ 334.569650] [30627375] *pgd=00000000
[ 334.573252] Internal error: Oops: 5 [#1] SMP ARM
Entering kdb (current=0xee5fb0c0, pid 89) on processor 1 Oops: (null)
due to oops @ 0xc0b36a20
CPU: 1 PID: 89 Comm: 4b500000.aes-en Tainted: G C
4.14.13-ti-r25 #55
Hardware name: Generic DRA74X (Flattened Device Tree)
task: ee5fb0c0 task.stack: ee782000
PC is at omap_aes_crypt_dma+0x234/0x58c
LR is at irq_work_queue+0x14/0x90
pc : [<c0b36a20>] lr : [<c0256020>] psr: 60080013
sp : ee783e48 ip : 00000007 fp : ee783eac
r10: eba7f740 r9 : eba7f740 r8 : ee70d380
r7 : 00000001 r6 : c011a320 r5 : c1504dc8 r4 : ee70d310
r3 : 5c40a269 r2 : 5c40a269 r1 : 00000000 r0 : 30627375
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: ad69c06a DAC: 00000051
CPU: 1 PID: 89 Comm: 4b500000.aes-en Tainted: G C
4.14.13-ti-r25 #55
Hardware name: Generic DRA74X (Flattened Device Tree)
[<c0d881f8>] (__dabt_svc) from [<c0b36a20>]
(omap_aes_crypt_dma+0x234/0x58c)
[<c0b36a20>] (omap_aes_crypt_dma) from [<c0b36fa0>]
(omap_aes_crypt_dma_start+0x228/0x400)
[<c0b36fa0>] (omap_aes_crypt_dma_start) from [<c0b3720c>]
(omap_aes_crypt_req+0x94/0x128)
[<c0b3720c>] (omap_aes_crypt_req) from [<c073bbf4>]
(crypto_pump_work+0x278/0x2f8)
[<c073bbf4>] (crypto_pump_work) from [<c016665c>]
(kthread_worker_fn+0x11c/0x20c)
[<c016665c>] (kthread_worker_fn) from [<c01664f4>]
(kthread+0x170/0x178)
[<c01664f4>] (kthread) from [<c0108fa8>] (ret_from_fork+0x14/0x2c)
Here the call should be omap_crypt_cleanup(dd->out_sg, ...);
A similar issue exists in omap-des.c.
Signed-off-by: Francis Le Bourse<francis.lebourse@xxxxxx> ---
drivers/crypto/omap-aes.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 49bd56f..b3a8081 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -97,6 +97,13 @@ static void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset,
omap_aes_write(dd, offset, *value);
}
+static void omap_aes_read_n(struct omap_aes_dev *dd, u32 offset,
+ u32 *value, int count)
+{
+ for (; count--; value++, offset += 4)
+ *value = omap_aes_read(dd, offset);
+}
+
static int omap_aes_hw_init(struct omap_aes_dev *dd)
{
int err;
@@ -389,6 +396,9 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
pr_debug("err: %d\n", err);
+ if ((dd->flags & (FLAGS_CBC | FLAGS_CTR)) && dd->req->info)
+ omap_aes_read_n(dd, AES_REG_IV(dd, 0), dd->req->info, 4);
+
crypto_finalize_cipher_request(dd->engine, req, err);
pm_runtime_mark_last_busy(dd->dev);
@@ -498,7 +508,7 @@ static void omap_aes_done_task(unsigned long data)
omap_crypto_cleanup(dd->in_sgl, NULL, 0, dd->total_save,
FLAGS_IN_DATA_ST_SHIFT, dd->flags);
- omap_crypto_cleanup(&dd->out_sgl, dd->orig_out, 0, dd->total_save,
+ omap_crypto_cleanup(dd->out_sg, dd->orig_out, 0, dd->total_save,
FLAGS_OUT_DATA_ST_SHIFT, dd->flags);
omap_aes_finish_req(dd, 0);