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_mem_mgmt_api.h"
13
14 #include <malloc.h>
15 #include <securec.h>
16
17 #include <mem_ops.h>
18 #include "tee_log.h"
19 #include "ta_framework.h"
20 #include "tee_property_inner.h"
21
22 #define COMPARE_SMALL (-1)
23 #define COMPARE_LARGE 1
24 #define COMPARE_EQUAL 0
25
26 #define ERR_INVALID 0xFFFFFFFFU
27 #define ERR_NO_MASK 0xFF
28
29 // overwrite GP standard interface, enable it only in GP certificate
30 #ifndef SUPPORT_GP_PANIC
31 #define TEE_Panic(x) \
32 do { \
33 } while (0)
34 #endif
35
36 static void *g_instance_data = NULL;
37
malloc_with_hint(size_t size,uint32_t hint)38 static void *malloc_with_hint(size_t size, uint32_t hint)
39 {
40 void *ptr = NULL;
41
42 ptr = malloc(size);
43 if (ptr == NULL) {
44 tloge("apply buffer is failed 0x%x\n", size);
45 return ptr;
46 }
47
48 if (hint == 0)
49 (void)memset_s(ptr, size, 0x0, size);
50
51 return ptr;
52 }
53
malloc_with_hint_mask(size_t size,uint32_t hint)54 static void *malloc_with_hint_mask(size_t size, uint32_t hint)
55 {
56 void *ptr = NULL;
57
58 if (((hint & TEE_MALLOC_NO_FILL) != 0) && ((hint & TEE_MALLOC_NO_SHARE) == 0)) {
59 tloge("invalid parameters\n");
60 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
61 return ptr;
62 }
63
64 ptr = malloc(size);
65 if (ptr == NULL) {
66 tloge("apply buffer is failed 0x%x\n", size);
67 return ptr;
68 }
69
70 if ((hint == 0) || ((hint & TEE_MALLOC_NO_FILL) == 0))
71 (void)memset_s(ptr, size, 0x0, size);
72
73 return ptr;
74 }
75
compare_each_byte(const void * buffer1,const void * buffer2,size_t size)76 static int32_t compare_each_byte(const void *buffer1, const void *buffer2, size_t size)
77 {
78 const unsigned char *c1 = buffer1;
79 const unsigned char *c2 = buffer2;
80 size_t i;
81 int32_t result = 0;
82
83 for (i = 0; i < size; i++) {
84 if ((*c1 != *c2) && (result == 0))
85 result = (*c1 > *c2 ? COMPARE_LARGE : COMPARE_SMALL);
86
87 c1++;
88 c2++;
89 }
90
91 return result;
92 }
93
buffer_full_compare(const void * buffer1,const void * buffer2,size_t size)94 static int32_t buffer_full_compare(const void *buffer1, const void *buffer2, size_t size)
95 {
96 // static function, called only by TEE_MemCompare, don't need to check param again
97 const unsigned long *l1 = NULL;
98 const unsigned long *l2 = NULL;
99
100 uint32_t remainder;
101 uint32_t step = sizeof(*l1);
102 int32_t result = 0;
103
104 remainder = size % step;
105
106 if (remainder != 0)
107 result = compare_each_byte(buffer1, buffer2, remainder);
108
109 l1 = buffer1 + remainder;
110 l2 = buffer2 + remainder;
111 size -= remainder;
112
113 for (; size > 0; size -= step) {
114 if ((*l1 != *l2) && (result == 0)) {
115 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
116 result = compare_each_byte(l1, l2, step);
117 #else
118 result = ((*l1 > *l2) ? COMPARE_LARGE : COMPARE_SMALL);
119 #endif
120 }
121
122 l1++;
123 l2++;
124 }
125
126 return result;
127 }
128
129 /*
130 * below APIs are defined by Global Platform or Platform SDK released previously
131 * for compatibility:
132 * don't change function name / return value type / parameters types / parameters names
133 */
TEE_MemFill(void * buffer,uint32_t x,size_t size)134 void TEE_MemFill(void *buffer, uint32_t x, size_t size)
135 {
136 unsigned char *p = NULL;
137
138 if (buffer == NULL)
139 return;
140
141 p = buffer;
142
143 while (size-- > 0)
144 *p++ = (unsigned char)x;
145 }
146
TEE_MemMove(void * dest,const void * src,size_t size)147 void TEE_MemMove(void *dest, const void *src, size_t size)
148 {
149 char *dst_ptr = NULL;
150 const char *src_ptr = NULL;
151
152 bool invalid = (size == 0) || (size > SECUREC_MEM_MAX_LEN) || (dest == NULL) || (src == NULL);
153 if (invalid)
154 return;
155
156 if (dest == src)
157 return;
158
159 src_ptr = src;
160 dst_ptr = dest;
161 if (src_ptr < dst_ptr) {
162 while (size-- != 0)
163 dst_ptr[size] = src_ptr[size];
164 } else {
165 while (size-- != 0)
166 *dst_ptr++ = *src_ptr++;
167 }
168 }
169
TEE_Malloc(size_t size,uint32_t hint)170 void *TEE_Malloc(size_t size, uint32_t hint)
171 {
172 uint32_t api_level;
173 if (size == 0)
174 return NULL;
175
176 api_level = tee_get_ta_api_level();
177 if (api_level >= API_LEVEL1_2)
178 return malloc_with_hint_mask(size, hint);
179 else
180 return malloc_with_hint(size, hint);
181 }
182
TEE_Free(void * buffer)183 void TEE_Free(void *buffer)
184 {
185 if (buffer == NULL)
186 return;
187
188 free(buffer);
189 }
190
TEE_Realloc(void * buffer,size_t new_size)191 void *TEE_Realloc(void *buffer, size_t new_size)
192 {
193 if (new_size == 0)
194 return NULL;
195
196 return realloc(buffer, new_size);
197 }
198
TEE_MemCompare(const void * buffer1,const void * buffer2,size_t size)199 int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size)
200 {
201 if ((buffer1 != NULL) && (buffer2 != NULL))
202 return buffer_full_compare(buffer1, buffer2, size);
203 else if ((buffer1 == NULL) && (buffer2 != NULL))
204 return COMPARE_SMALL;
205 else if ((buffer1 != NULL) && (buffer2 == NULL))
206 return COMPARE_LARGE;
207 else
208 return COMPARE_EQUAL;
209 }
210
TEE_CheckMemoryAccessRights(uint32_t accessFlags,const void * buffer,size_t size)211 TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, const void *buffer, size_t size)
212 {
213 (void)accessFlags;
214 (void)buffer;
215 (void)size;
216 return TEE_ERROR_NOT_SUPPORTED;
217 }
218
TEE_SetInstanceData(void * instanceData)219 void TEE_SetInstanceData(void *instanceData)
220 {
221 g_instance_data = instanceData;
222 }
223
TEE_GetInstanceData(void)224 void *TEE_GetInstanceData(void)
225 {
226 return g_instance_data;
227 }
228