diff --git a/arch/arm/cpu/armv7/qca/common/scm.c b/arch/arm/cpu/armv7/qca/common/scm.c index de2472dfd2..bd7e4fcfe7 100644 --- a/arch/arm/cpu/armv7/qca/common/scm.c +++ b/arch/arm/cpu/armv7/qca/common/scm.c @@ -570,6 +570,19 @@ int qca_scm_secure_authenticate(void *cmd_buf, size_t cmd_len) } #endif +int qca_scm_call_crypto_v8(u32 svc_id, u32 cmd_id, u32 *addr, u32 val) +{ + int ret = 0; + struct qca_scm_desc desc = {0}; + + desc.arginfo = QCA_SCM_ARGS(2, SCM_RW_OP, SCM_VAL); + + desc.args[0] = (u32)addr; + desc.args[1] = val; + ret = scm_call_64(svc_id, cmd_id, &desc); + return ret; +} + int qca_scm_call_write(u32 svc_id, u32 cmd_id, u32 *addr, u32 val) { int ret = 0; @@ -623,6 +636,18 @@ int qca_scm_sdi(void) return ret; } +int qca_scm_crypto(int cmd_id, void *req_ptr, uint32_t req_size) +{ + int ret; + if (is_scm_armv8()) + ret = qca_scm_call_crypto_v8(SCM_SVC_CRYPTO, cmd_id, + (u32 *)req_ptr, req_size); + else + ret = -ENOTSUPP; + + return ret; +} + int qca_scm_dload(unsigned int magic_cookie) { int ret; diff --git a/arch/arm/include/asm/arch-qca-common/scm.h b/arch/arm/include/asm/arch-qca-common/scm.h index 4bbe13f48a..a31cac4584 100644 --- a/arch/arm/include/asm/arch-qca-common/scm.h +++ b/arch/arm/include/asm/arch-qca-common/scm.h @@ -21,6 +21,7 @@ #define SCM_SVC_SSD 0x7 #define SCM_SVC_FUSE 0x8 #define SCM_SVC_PWR 0x9 +#define SCM_SVC_CRYPTO 0xA #define SCM_SVC_CP 0xC #define SCM_SVC_DCVS 0xD #define SCM_SVC_TZSCHEDULER 0xFC @@ -117,6 +118,7 @@ extern int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len); int qca_scm_usb_mode_write(u32, u32); int qca_scm_call_write(u32, u32, u32 *, u32); int qca_scm_call_read(u32, u32, u32 *, u32 *); +int qca_scm_crypto(int, void *, u32); int qca_scm_sdi(void); int qca_scm_dload(u32); int qca_scm_fuseipq(u32, u32, void *, size_t); diff --git a/common/cmd_aes.c b/common/cmd_aes.c index 76da3efffe..6ae6ecde40 100644 --- a/common/cmd_aes.c +++ b/common/cmd_aes.c @@ -13,9 +13,149 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_CMD_AES_256 +enum tz_crypto_service_aes_cmd_t { + TZ_CRYPTO_SERVICE_AES_ENC_ID = 0x7, + TZ_CRYPTO_SERVICE_AES_DEC_ID = 0x8, +}; + +enum tz_crypto_service_aes_type_t { + TZ_CRYPTO_SERVICE_AES_SHK = 0x1, + TZ_CRYPTO_SERVICE_AES_PHK = 0x2, + TZ_CRYPTO_SERVICE_AES_TYPE_MAX, + +}; + +enum tz_crypto_service_aes_mode_t { + TZ_CRYPTO_SERVICE_AES_ECB = 0x0, + TZ_CRYPTO_SERVICE_AES_CBC = 0x1, + TZ_CRYPTO_SERVICE_AES_MODE_MAX, +}; + +struct crypto_aes_req_data_t { + uint64_t type; + uint64_t mode; + uint64_t req_buf; + uint64_t req_len; + uint64_t ivdata; + uint64_t iv_len; + uint64_t resp_buf; + uint64_t resp_len; +}; + +/** + * do_aes_256() - Handle the "aes" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */ +static int do_aes_256(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + uint64_t src_addr, dst_addr, ivdata; + uint64_t req_len, iv_len, resp_len, type, mode; + struct crypto_aes_req_data_t *req_ptr = NULL; + int cmd_id = -1; + int ret = CMD_RET_USAGE; + + if (argc != 10) + return ret; + + if (!strncmp(argv[1], "enc", 3)) + cmd_id = TZ_CRYPTO_SERVICE_AES_ENC_ID; + else if (!strncmp(argv[1], "dec", 3)) + cmd_id = TZ_CRYPTO_SERVICE_AES_DEC_ID; + else + return ret; + + type = simple_strtoul(argv[2], NULL, 16); + if (type >= TZ_CRYPTO_SERVICE_AES_TYPE_MAX) { + printf("unkown type specified, use 0x1 - SHK, 0x2 - PHK\n"); + goto err; + } + + mode = simple_strtoul(argv[3], NULL, 16); + if (mode >= TZ_CRYPTO_SERVICE_AES_MODE_MAX) { + printf("unkown mode specified, use 0x0 - ECB, 0x1 - CBC\n"); + goto err; + } + + src_addr = simple_strtoull(argv[4], NULL, 16); + req_len = simple_strtoul(argv[5], NULL, 16); + if (req_len <= 0 || (req_len % 16) != 0) { + printf("Invalid request buffer length, length " + "should be multiple of AES block size (16)\n"); + goto err; + } + + ivdata = simple_strtoull(argv[6], NULL, 16); + iv_len = simple_strtoul(argv[7], NULL, 16); + if (iv_len != 16) { + printf("Error: iv length should be equal to AES block size (16)\n"); + goto err; + } + + dst_addr = simple_strtoull(argv[8], NULL, 16); + resp_len = simple_strtoul(argv[9], NULL, 16); + if (resp_len < req_len) { + printf("Error: response buffer cannot be less then request buffer\n"); + goto err; + } + + req_ptr = (struct crypto_aes_req_data_t *)memalign(ARCH_DMA_MINALIGN, + sizeof(struct crypto_aes_req_data_t)); + if (!req_ptr) { + printf("Error allocating memory"); + return -ENOMEM; + } + + req_ptr->type = type; + req_ptr->mode = mode; + req_ptr->req_buf = (uint64_t)src_addr; + req_ptr->req_len = req_len; + req_ptr->ivdata = (mode == TZ_CRYPTO_SERVICE_AES_CBC) ? (uint64_t)ivdata : 0; + req_ptr->iv_len = iv_len; + req_ptr->resp_buf = (uint64_t)dst_addr; + req_ptr->resp_len = resp_len; + ret = qca_scm_crypto(cmd_id, (void *)req_ptr, + sizeof(struct crypto_aes_req_data_t)); + + if (req_ptr) + free(req_ptr); + + if (ret) { + printf("Scm call failed with error code: %d\n", ret); + return ret; + } + return 0; + +err: + if (req_ptr) + free(req_ptr); + return CMD_RET_USAGE; +} + +/***************************************************/ +U_BOOT_CMD( + aes_256, 10, 1, do_aes_256, + "AES 256 CBC/ECB encryption/decryption", + "Encryption: echo enc " + " " + "Decryption: echo dec " +); +#endif + + +#ifdef CONFIG_CMD_AES_128 /** * do_aes() - Handle the "aes" command-line command * @cmdtp: Command data struct pointer @@ -87,3 +227,4 @@ U_BOOT_CMD( "AES 128 CBC encryption", aes_help_text ); +#endif diff --git a/include/configs/ipq807x.h b/include/configs/ipq807x.h index 19a69f486a..6c24dee4b5 100644 --- a/include/configs/ipq807x.h +++ b/include/configs/ipq807x.h @@ -28,6 +28,9 @@ * #define CONFIG_RUMI */ +#define CONFIG_CMD_AES +#define CONFIG_CMD_AES_256 + #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_IPQ_NO_RELOC #define CONFIG_BOARD_LATE_INIT