]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
cmd: aes: Add support for using device key while decryption
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Mon, 21 Aug 2017 13:49:48 +0000 (19:19 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 24 Aug 2017 14:27:13 +0000 (16:27 +0200)
This patch adds support for using device key while decryption
Devicekey is nothing but a key which was programmed in device
such as eFUSE or BBRAM. Having this feature support in this
command helps to inform hardware to use key from device instead
of user provided key.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
board/xilinx/zynqmp/zynqmp.c
cmd/aes.c
include/aes.h

index 6b29510ddb213e7a1b50a740947ba3a769d27288..45d6b2deefab4545c5590c964a5b316b43062163 100644 (file)
@@ -361,12 +361,15 @@ int board_late_init(void)
 #define KEY_LEN                                64
 #define IV_LEN                         24
 #define ZYNQMP_PM_SECURE_AES           0x1
+#define ZYNQMP_PM_SECURE_AES_DEVKEY    0x4
 
-int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len)
+int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len,
+                  bool devkey)
 {
        int ret;
        u32 src_lo, src_hi, wlen;
        u32 ret_payload[PAYLOAD_ARG_CNT];
+       u32 keylen, flag;
 
        if ((ulong)src_ptr != ALIGN((ulong)src_ptr,
                                    CONFIG_SYS_CACHELINE_SIZE)) {
@@ -378,12 +381,20 @@ int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len)
        src_hi = upper_32_bits((ulong)src_ptr);
        wlen = DIV_ROUND_UP(len, 4);
 
-       memcpy(src_ptr + len, key_ptr, KEY_LEN + IV_LEN);
-       len = ROUND(len + KEY_LEN + IV_LEN, CONFIG_SYS_CACHELINE_SIZE);
+       if (devkey) {
+               keylen = IV_LEN;
+               flag = ZYNQMP_PM_SECURE_AES_DEVKEY;
+       } else {
+               keylen = KEY_LEN + IV_LEN;
+               flag = ZYNQMP_PM_SECURE_AES;
+       }
+
+       memcpy(src_ptr + len, key_ptr, keylen);
+       len = ROUND(len + keylen, CONFIG_SYS_CACHELINE_SIZE);
        flush_dcache_range((ulong)src_ptr, (ulong)(src_ptr + len));
 
        ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_LOAD, src_lo, src_hi, wlen,
-                        ZYNQMP_PM_SECURE_AES, ret_payload);
+                        flag, ret_payload);
        if (ret)
                debug("aes_decrypt_hw fail\n");
 
index 12886b796193ee5a6e3ad3d521110d74a122ebad..b410b674e302fb4b72afc4d41536fd01dbd242eb 100644 (file)
--- a/cmd/aes.c
+++ b/cmd/aes.c
@@ -16,7 +16,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-__weak int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len)
+__weak int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len,
+                         bool devkey)
 {
        return 0;
 }
@@ -39,8 +40,9 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        uint32_t aes_blocks;
        int enc;
        bool use_hw = false;
+       bool use_devkey = false;
 
-       if (argc < 6 || argc > 7)
+       if (argc < 6 || argc > 8)
                return CMD_RET_USAGE;
 
        if (!strncmp(argv[1], "enc", 3))
@@ -55,17 +57,23 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        dst_addr = simple_strtoul(argv[4], NULL, 16);
        len = simple_strtoul(argv[5], NULL, 16);
 
-       if (argc == 7)
+       if (argc >= 7)
                if (!strncmp(argv[6], "hw", 2))
                        use_hw = true;
 
+       if (use_hw) {
+               if (!strncmp(argv[7], "dev", 3))
+                       use_devkey = true;
+       }
+
        key_ptr = (uint8_t *)(uintptr_t)key_addr;
        src_ptr = (uint8_t *)(uintptr_t)src_addr;
        dst_ptr = (uint8_t *)(uintptr_t)dst_addr;
 
        if (use_hw) {
                if (!enc)
-                       aes_decrypt_hw(key_ptr, src_ptr, dst_ptr, len);
+                       aes_decrypt_hw(key_ptr, src_ptr, dst_ptr, len,
+                                      use_devkey);
        } else {
                /* First we expand the key. */
                aes_expand_key(key_ptr, key_exp);
@@ -91,18 +99,24 @@ static char aes_help_text[] =
        "                          $key and store the result at address\n"
        "                          $dst. The $len size must be multiple of\n"
        "                          16 bytes and $key must be 16 bytes long.\n"
-       "aes dec key src dst len [hw] - Decrypt block of data $len bytes\n"
-       "                               long at address $src using a key at\n"
-       "                               address $key and store the result at\n"
-       "                               address $dst. The $len size must be\n"
-       "                               multiple of 16 bytes and $key must be\n"
-       "                               16 bytes long. The optional hw flag\n"
-       "                               specifies to used hardware engine if\n"
-       "                               supports\n";
+       "aes dec key src dst len [hw] [dev] - Decrypt block of data $len\n"
+       "                                     bytes long at address $src\n"
+       "                                     using a key at address $key\n"
+       "                                     and store the result at\n"
+       "                                     address $dst. The $len size\n"
+       "                                     must be multiple of 16 bytes\n"
+       "                                     and $key must be 16 bytes\n"
+       "                                     long. The optional hw flag\n"
+       "                                     specifies to used hardware\n"
+       "                                     engine if supports. Other\n"
+       "                                     optional flag dev sepcifies\n"
+       "                                     it to use device key which was\n"
+       "                                     programmed in eFUSE/BBRAM or\n"
+       "                                     any such\n";
 #endif
 
 U_BOOT_CMD(
-       aes, 7, 1, do_aes,
+       aes, 8, 1, do_aes,
        "AES 128 CBC encryption",
        aes_help_text
 );
index 5198bb98d0760b6d8bda0feb468c7c6c350f1aa1..16b5fbc7b2c15488f4e23a00c5f77d7dec17273b 100644 (file)
@@ -98,7 +98,9 @@ void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks);
  * @src_ptr            Source data to decrypt
  * @dst_ptr            Destination buffer
  * @len                        Length of encrypted image
+ * @devkey             Key to be used from device ex:efuse/BBRAM
  */
-int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len);
+int aes_decrypt_hw(u8 *key_ptr, u8 *src_ptr, u8 *dst_ptr, u32 len,
+                  bool devkey);
 
 #endif /* _AES_REF_H_ */