The DM AES command path takes operation-specific arguments after the
common arguments. Parse the requested operation before reading those
arguments so encrypt and decrypt use the correct positions.

Also handle in-place operations by reusing the source mapping when the
source and destination addresses match. Mapping and unmapping the same
range twice can break UCLASS_AES providers that perform DMA-backed
operations.

Signed-off-by: James Hilliard <[email protected]>
---
 cmd/aes.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/cmd/aes.c b/cmd/aes.c
index 3fd83013ffe..a74a68ee641 100644
--- a/cmd/aes.c
+++ b/cmd/aes.c
@@ -175,9 +175,9 @@ int cmd_aes_ecb(int argc, char *const argv[], u32 key_len)
        if (ret)
                return ret;
 
-       if (!strncmp(argv[1], "enc", 3))
+       if (!strncmp(argv[2], "enc", 3))
                enc = 1;
-       else if (!strncmp(argv[1], "dec", 3))
+       else if (!strncmp(argv[2], "dec", 3))
                enc = 0;
        else
                return CMD_RET_USAGE;
@@ -187,7 +187,10 @@ int cmd_aes_ecb(int argc, char *const argv[], u32 key_len)
        len = hextoul(argv[5], NULL);
 
        src_ptr = (uint8_t *)map_sysmem(src_addr, len);
-       dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
+       if (src_addr == dst_addr)
+               dst_ptr = src_ptr;
+       else
+               dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
 
        /* Calculate the number of AES blocks to encrypt. */
        aes_blocks = DIV_ROUND_UP(len, AES_BLOCK_LENGTH);
@@ -198,7 +201,8 @@ int cmd_aes_ecb(int argc, char *const argv[], u32 key_len)
                ret = dm_aes_ecb_decrypt(dev, src_ptr, dst_ptr, aes_blocks);
 
        unmap_sysmem(src_ptr);
-       unmap_sysmem(dst_ptr);
+       if (dst_ptr != src_ptr)
+               unmap_sysmem(dst_ptr);
 
        if (ret) {
                printf("Unable to do ecb operation: %d\n", ret);
@@ -223,9 +227,9 @@ int cmd_aes_cbc(int argc, char *const argv[], u32 key_len)
        if (ret)
                return ret;
 
-       if (!strncmp(argv[1], "enc", 3))
+       if (!strncmp(argv[2], "enc", 3))
                enc = 1;
-       else if (!strncmp(argv[1], "dec", 3))
+       else if (!strncmp(argv[2], "dec", 3))
                enc = 0;
        else
                return CMD_RET_USAGE;
@@ -237,7 +241,10 @@ int cmd_aes_cbc(int argc, char *const argv[], u32 key_len)
 
        iv_ptr = (uint8_t *)map_sysmem(iv_addr, AES_BLOCK_LENGTH);
        src_ptr = (uint8_t *)map_sysmem(src_addr, len);
-       dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
+       if (src_addr == dst_addr)
+               dst_ptr = src_ptr;
+       else
+               dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
 
        /* Calculate the number of AES blocks to encrypt. */
        aes_blocks = DIV_ROUND_UP(len, AES_BLOCK_LENGTH);
@@ -249,7 +256,8 @@ int cmd_aes_cbc(int argc, char *const argv[], u32 key_len)
 
        unmap_sysmem(iv_ptr);
        unmap_sysmem(src_ptr);
-       unmap_sysmem(dst_ptr);
+       if (dst_ptr != src_ptr)
+               unmap_sysmem(dst_ptr);
 
        if (ret) {
                printf("Unable to do cbc operation: %d\n", ret);
-- 
2.53.0

Reply via email to