drivers: qseecom: Add new SCM call for AES 128 bytes context length

A new SCM has been added in TZ to support AES 128 byte context length.
Updated aes driver to add the same. Added new command as mentioned
below for 128 byte context length.
derive_aes_256_max_ctxt_key 0x2 0x20 0x41000000 0x80

Note: This new SCM call has been introduced since initial SCM call does not
derive keys the same way as Linux Fscrypt feature (128 byte context length)

Signed-off-by: Poovendhan Selvaraj <quic_poovendh@quicinc.com>
Change-Id: Ie71fc0e9b3c0b0d01995745bb61cd2d82f07eb85
This commit is contained in:
Poovendhan Selvaraj 2024-03-06 18:37:32 +05:30
parent 78d19e2dbb
commit dae19193ab

View file

@ -18,13 +18,13 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
#define SCM_SW_CONTEXT_FEATURE_ID 0x5
#ifdef CONFIG_CMD_AES_256 #ifdef CONFIG_CMD_AES_256
enum tz_crypto_service_aes_cmd_t { enum tz_crypto_service_aes_cmd_t {
TZ_CRYPTO_SERVICE_AES_ENC_ID = 0x7, TZ_CRYPTO_SERVICE_AES_ENC_ID = 0x7,
TZ_CRYPTO_SERVICE_AES_DEC_ID = 0x8, TZ_CRYPTO_SERVICE_AES_DEC_ID = 0x8,
#ifdef CONFIG_IPQ_DERIVE_KEY #ifdef CONFIG_IPQ_DERIVE_KEY
TZ_CRYPTO_SERVICE_AES_DERIVE_KEY_ID = 0x9, TZ_CRYPTO_SERVICE_AES_DERIVE_KEY_ID = 0x9,
TZ_CRYPTO_SERVICE_AES_DERIVE_128_KEY_ID = 0xE,
#endif #endif
}; };
@ -117,7 +117,6 @@ unsigned char toBinary(char c)
return (c - 'a') + 10; return (c - 'a') + 10;
} }
static uint32_t max_context_len = MAX_CONTEXT_BUFFER_LEN_V1;
/** /**
* do_derive_aes_256_key() - Handle the "derive_key" command-line command * do_derive_aes_256_key() - Handle the "derive_key" command-line command
* @cmdtp: Command data struct pointer * @cmdtp: Command data struct pointer
@ -131,8 +130,7 @@ static uint32_t max_context_len = MAX_CONTEXT_BUFFER_LEN_V1;
static int do_derive_aes_256_key(cmd_tbl_t *cmdtp, int flag, static int do_derive_aes_256_key(cmd_tbl_t *cmdtp, int flag,
int argc, char *const argv[]) int argc, char *const argv[])
{ {
struct crypto_aes_derive_key_cmd_t_v1 *v1_req_ptr = NULL; struct crypto_aes_derive_key_cmd_t_v1 *req_ptr = NULL;
struct crypto_aes_derive_key_cmd_t_v2 *v2_req_ptr = NULL;
int ret = CMD_RET_USAGE; int ret = CMD_RET_USAGE;
uintptr_t *key_handle = NULL; uintptr_t *key_handle = NULL;
uint8_t *context_buf = NULL; uint8_t *context_buf = NULL;
@ -141,77 +139,39 @@ static int do_derive_aes_256_key(cmd_tbl_t *cmdtp, int flag,
if (argc != 5) if (argc != 5)
return ret; return ret;
ret = qca_scm_is_feature_available(SCM_SW_CONTEXT_FEATURE_ID);
if (ret > 0) {
max_context_len = 128;
}
else {
max_context_len = 64;
}
context_buf = (uint8_t *)simple_strtoul(argv[3], NULL, 16);; context_buf = (uint8_t *)simple_strtoul(argv[3], NULL, 16);;
context_len = simple_strtoul(argv[4], NULL, 16); context_len = simple_strtoul(argv[4], NULL, 16);
if (context_len > max_context_len) { if (context_len > MAX_CONTEXT_BUFFER_LEN_V1) {
printf("Error: context length should be less than %d\n", printf("Error: context length should be less than %d\n",
max_context_len); MAX_CONTEXT_BUFFER_LEN_V1);
return ret; return ret;
} }
key_handle = (uintptr_t *)memalign(ARCH_DMA_MINALIGN, sizeof(uint64_t)); key_handle = (uintptr_t *)memalign(ARCH_DMA_MINALIGN, sizeof(uint64_t));
if (max_context_len == MAX_CONTEXT_BUFFER_LEN_V1) { req_ptr = (struct crypto_aes_derive_key_cmd_t_v1 *)memalign(
v1_req_ptr = (struct crypto_aes_derive_key_cmd_t_v1 *)memalign(
ARCH_DMA_MINALIGN, sizeof(struct crypto_aes_derive_key_cmd_t_v1)); ARCH_DMA_MINALIGN, sizeof(struct crypto_aes_derive_key_cmd_t_v1));
if (!v1_req_ptr) { if (!req_ptr) {
printf("Error allocating memory for key handle request buf"); printf("Error allocating memory for key handle request buf");
return -ENOMEM; return -ENOMEM;
} }
v1_req_ptr->policy.key_type = DEFAULT_KEY_TYPE; req_ptr->policy.key_type = DEFAULT_KEY_TYPE;
v1_req_ptr->policy.destination = DEFAULT_POLICY_DESTINATION; req_ptr->policy.destination = DEFAULT_POLICY_DESTINATION;
v1_req_ptr->source = simple_strtoul(argv[1], NULL, 16); req_ptr->source = simple_strtoul(argv[1], NULL, 16);
v1_req_ptr->hw_key_bindings.bindings = simple_strtoul(argv[2], req_ptr->hw_key_bindings.bindings = simple_strtoul(argv[2],
NULL, 16); NULL, 16);
v1_req_ptr->key = (uintptr_t) key_handle; req_ptr->key = (uintptr_t) key_handle;
v1_req_ptr->mixing_key = 0; req_ptr->mixing_key = 0;
v1_req_ptr->hw_key_bindings.context_len = context_len; req_ptr->hw_key_bindings.context_len = context_len;
while (i < context_len) { while (i < context_len) {
v1_req_ptr->hw_key_bindings.context[j++] = context_buf[i++]; req_ptr->hw_key_bindings.context[j++] = context_buf[i++];
}
ret = qca_scm_crypto(TZ_CRYPTO_SERVICE_AES_DERIVE_KEY_ID,
(void *)v1_req_ptr, sizeof(struct crypto_aes_derive_key_cmd_t_v1));
}
else if (max_context_len == MAX_CONTEXT_BUFFER_LEN_V2) {
v2_req_ptr = (struct crypto_aes_derive_key_cmd_t_v2 *)memalign(
ARCH_DMA_MINALIGN, sizeof(struct crypto_aes_derive_key_cmd_t_v2));
if (!v2_req_ptr) {
printf("Error allocating memory for key handle request buf");
return -ENOMEM;
}
v2_req_ptr->policy.key_type = DEFAULT_KEY_TYPE;
v2_req_ptr->policy.destination = DEFAULT_POLICY_DESTINATION;
v2_req_ptr->source = simple_strtoul(argv[1], NULL, 16);
v2_req_ptr->hw_key_bindings.bindings = simple_strtoul(argv[2],
NULL, 16);
v2_req_ptr->key = (uintptr_t) key_handle;
v2_req_ptr->mixing_key = 0;
v2_req_ptr->hw_key_bindings.context_len = context_len;
while (i < context_len) {
v2_req_ptr->hw_key_bindings.context[j++] = context_buf[i++];
}
ret = qca_scm_crypto(TZ_CRYPTO_SERVICE_AES_DERIVE_KEY_ID,
(void *)v2_req_ptr, sizeof(struct crypto_aes_derive_key_cmd_t_v2));
}
if (ret)
printf("Scm call failed with error code: %d\n", ret);
else {
printf("Key handle is %u\n", (unsigned int)*key_handle);
} }
ret = qca_scm_crypto(TZ_CRYPTO_SERVICE_AES_DERIVE_KEY_ID,
(void *)req_ptr, sizeof(struct crypto_aes_derive_key_cmd_t_v1));
if (key_handle) if (key_handle)
free(key_handle); free(key_handle);
if (v1_req_ptr) if (req_ptr)
free(v1_req_ptr); free(req_ptr);
if (v2_req_ptr)
free(v2_req_ptr);
return ret; return ret;
} }
@ -223,6 +183,91 @@ U_BOOT_CMD(
"Key Derivation: derive_aes_256_key <source_data> <bindings_data>" "Key Derivation: derive_aes_256_key <source_data> <bindings_data>"
"<context_data address> <context data len>" "<context_data address> <context data len>"
); );
/**
* do_derive_aes_256_max_ctxt_key() - Handle the "derive_key" command-line
* command for 128 byte context
* @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_derive_aes_256_max_ctxt_key(cmd_tbl_t *cmdtp, int flag,
int argc, char *const argv[])
{
struct crypto_aes_derive_key_cmd_t_v2 *req_ptr = NULL;
int ret = CMD_RET_USAGE;
uintptr_t *key_handle = NULL;
uint8_t *context_buf = NULL;
int context_len = 0;
int i = 0, j = 0;
if (argc != 5)
return ret;
ret = is_scm_sec_auth_available(SCM_SVC_CRYPTO,
TZ_CRYPTO_SERVICE_AES_DERIVE_128_KEY_ID);
if (ret <= 0) {
printf("Aes 256 Max context key derivation"
"scm call is not supported. ret = %d\n", ret);
return CMD_RET_SUCCESS;
}
context_buf = (uint8_t *)simple_strtoul(argv[3], NULL, 16);
context_len = simple_strtoul(argv[4], NULL, 16);
if (context_len > MAX_CONTEXT_BUFFER_LEN_V2) {
printf("Error: context length should be less than %d\n",
MAX_CONTEXT_BUFFER_LEN_V2);
return ret;
}
key_handle = (uintptr_t *)memalign(ARCH_DMA_MINALIGN,
sizeof(uint64_t));
req_ptr = (struct crypto_aes_derive_key_cmd_t_v2 *)memalign(ARCH_DMA_MINALIGN,
sizeof(struct crypto_aes_derive_key_cmd_t_v2));
if (!req_ptr) {
printf("Error allocating memory for key handle request buf");
return -ENOMEM;
}
req_ptr->policy.key_type = DEFAULT_KEY_TYPE;
req_ptr->policy.destination = DEFAULT_POLICY_DESTINATION;
req_ptr->source = simple_strtoul(argv[1], NULL, 16);
req_ptr->hw_key_bindings.bindings = simple_strtoul(argv[2], NULL, 16);
req_ptr->key = (uintptr_t) key_handle;
req_ptr->mixing_key = 0;
req_ptr->hw_key_bindings.context_len = context_len;
while (i < context_len) {
req_ptr->hw_key_bindings.context[j++] = context_buf[i++];
}
ret = qca_scm_crypto(TZ_CRYPTO_SERVICE_AES_DERIVE_128_KEY_ID,
(void *)req_ptr, sizeof(struct crypto_aes_derive_key_cmd_t_v2));
if (ret)
printf("Scm call failed with error code: %d\n", ret);
else {
printf("Key handle is %u\n", (unsigned int)*key_handle);
}
if (key_handle)
free(key_handle);
if (req_ptr)
free(req_ptr);
return ret;
}
/***************************************************/
U_BOOT_CMD(
derive_aes_256_max_ctxt_key, 5, 1, do_derive_aes_256_max_ctxt_key,
"Derive AES 256 key with 128 byte context before"
"encrypt/decrypt in TME-L based systems",
"Key Derivation: derive_aes_256_max_ctxt_key <source_data>"
"<bindings_data> <context_data address> <context data len>"
);
#endif #endif
/** /**