• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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