1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "tee_huk_derive_key.h"
13 #include <securec.h>
14 #include <errno.h>
15 #include <tee_log.h>
16 #include <mem_ops.h>
17 #include "tee_inner_uuid.h"
18 #include "huk_service_msg.h"
19 #include "huk_service_msg_call.h"
20
huk_alloc_shared_mem(uint32_t size)21 void *huk_alloc_shared_mem(uint32_t size)
22 {
23 void *p = NULL;
24 TEE_UUID uuid = TEE_SERVICE_HUK;
25
26 p = alloc_sharemem_aux(&uuid, size);
27 if (p != NULL)
28 (void)memset_s(p, size, 0, size);
29
30 return p;
31 }
32
huk_free_shared_mem(uint8_t * p,uint32_t size)33 void huk_free_shared_mem(uint8_t *p, uint32_t size)
34 {
35 if (p == NULL || size == 0) {
36 tloge("check params failed\n");
37 return;
38 }
39 (void)memset_s(p, size, 0, size);
40 if (free_sharemem(p, size) != 0)
41 tloge("free shared mem failed\n");
42 }
43
derive_takey(uint32_t msg_id,const struct meminfo_t * salt_info,struct meminfo_t * takey_info,uint32_t outer_iter_num,uint32_t inner_iter_num)44 static TEE_Result derive_takey(uint32_t msg_id, const struct meminfo_t *salt_info, struct meminfo_t *takey_info,
45 uint32_t outer_iter_num, uint32_t inner_iter_num)
46 {
47 struct huk_srv_msg msg;
48 struct huk_srv_rsp rsp;
49 (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
50 (void)memset_s(&rsp, sizeof(rsp), 0, sizeof(rsp));
51
52 uint8_t *salt_shared = huk_alloc_shared_mem(salt_info->size);
53 if (salt_shared == NULL) {
54 tloge("malloc salt buff shared failed, size = 0x%x\n", salt_info->size);
55 return TEE_ERROR_OUT_OF_MEMORY;
56 }
57 if (memcpy_s(salt_shared, salt_info->size, (uint8_t *)(uintptr_t)salt_info->buffer, salt_info->size) != EOK) {
58 tloge("copy salt failed\n");
59 huk_free_shared_mem(salt_shared, salt_info->size);
60 return TEE_ERROR_GENERIC;
61 }
62
63 uint8_t *takey_shared = huk_alloc_shared_mem(takey_info->size);
64 if (takey_shared == NULL) {
65 tloge("malloc key buff shared failed, size = 0x%x\n", takey_info->size);
66 huk_free_shared_mem(salt_shared, salt_info->size);
67 return TEE_ERROR_OUT_OF_MEMORY;
68 }
69
70 msg.data.takey_msg.outer_iter_num = outer_iter_num;
71 msg.data.takey_msg.inner_iter_num = inner_iter_num;
72 msg.data.takey_msg.salt_buf = (uintptr_t)salt_shared;
73 msg.data.takey_msg.salt_size = salt_info->size;
74 msg.data.takey_msg.key_buf = (uintptr_t)takey_shared;
75 msg.data.takey_msg.key_size = takey_info->size;
76 msg.header.send.msg_id = msg_id;
77
78 if (huk_srv_msg_call(&msg, &rsp) < 0 || rsp.data.ret != TEE_SUCCESS) {
79 tloge("derive takey msg call failed\n");
80 rsp.data.ret = TEE_ERROR_GENERIC;
81 goto clean;
82 }
83 if (memcpy_s((uint8_t *)(uintptr_t)takey_info->buffer, takey_info->size, takey_shared, takey_info->size) != EOK) {
84 tloge("copy takey shared failed\n");
85 rsp.data.ret = TEE_ERROR_GENERIC;
86 }
87 clean:
88 huk_free_shared_mem(salt_shared, salt_info->size);
89 huk_free_shared_mem(takey_shared, takey_info->size);
90 return rsp.data.ret;
91 }
92
93 /*
94 * For compatible platforms, derive the key directly;
95 * for new platforms, salt + the uuid obtained from the huk service to be new salt, and then derive the key
96 */
tee_internal_derive_key(const uint8_t * salt,uint32_t saltsize,uint8_t * key,uint32_t keysize)97 TEE_Result tee_internal_derive_key(const uint8_t *salt, uint32_t saltsize, uint8_t *key, uint32_t keysize)
98 {
99 if (salt == NULL || key == NULL || saltsize == 0 || saltsize > CMAC_DERV_MAX_DATA_IN_SIZE ||
100 keysize == 0 || keysize > CMAC_DERV_MAX_DATA_IN_SIZE) {
101 tloge("derive key check params failed\n");
102 return TEE_ERROR_BAD_PARAMETERS;
103 }
104
105 struct meminfo_t salt_info = {0};
106 struct meminfo_t key_info = {0};
107 salt_info.buffer = (uintptr_t)salt;
108 salt_info.size = saltsize;
109 key_info.buffer = (uintptr_t)key;
110 key_info.size = keysize;
111 TEE_Result ret = derive_takey(CMD_HUK_DERIVE_TAKEY, &salt_info, &key_info, 1, 1);
112 if (ret != TEE_SUCCESS)
113 tloge("derive key failed, ret = 0x%x\n", ret);
114 return ret;
115 }
116