• 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_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