• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include <stdlib.h>
17 #include "securec.h"
18 #include "hitls_build.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_errno.h"
21 #include "bsl_sal.h"
22 #include "bsl_binlog_id.h"
23 #include "sal_memimpl.h"
24 
25 static BSL_SAL_MemCallback g_memCallback = {0};
26 
BSL_SAL_Malloc(uint32_t size)27 void *BSL_SAL_Malloc(uint32_t size)
28 {
29     // When size is 0, malloc of different systems may return NULL or non-NULL. Here, a definite result is required.
30     // If the callback is registered, everything is determined by the callback.
31     if (g_memCallback.pfMalloc != NULL && g_memCallback.pfMalloc != BSL_SAL_Malloc) {
32         return g_memCallback.pfMalloc(size);
33     }
34     if (size == 0) {
35         return NULL;
36     }
37 #if defined(HITLS_BSL_SAL_MEM) && defined(HITLS_BSL_SAL_LINUX)
38     return SAL_MallocImpl(size);
39 #else
40     return NULL;
41 #endif
42 }
43 
BSL_SAL_Free(void * value)44 void BSL_SAL_Free(void *value)
45 {
46     if (g_memCallback.pfFree == NULL || g_memCallback.pfFree == BSL_SAL_Free) {
47 #if defined(HITLS_BSL_SAL_MEM) && defined(HITLS_BSL_SAL_LINUX)
48         SAL_FreeImpl(value);
49 #endif
50         return;
51     }
52     g_memCallback.pfFree(value);
53 }
54 
BSL_SAL_Calloc(uint32_t num,uint32_t size)55 void *BSL_SAL_Calloc(uint32_t num, uint32_t size)
56 {
57     if (num == 0 || size == 0) {
58         return BSL_SAL_Malloc(0);
59     }
60     if (num > UINT32_MAX / size) { // process the rewinding according to G.INT.02 in the HW C Coding Specifications V5.1
61         return NULL;
62     }
63     uint32_t blockSize = num * size;
64     uint8_t *ptr = BSL_SAL_Malloc(blockSize);
65     if (ptr == NULL) {
66         return NULL;
67     }
68     // If the value is greater than SECUREC_MEM_MAX_LEN, segment processing is required.
69     // This is because memset_s can process only the value which the size is SECUREC_MEM_MAX_LEN.
70     uint32_t offset = 0;
71     while (blockSize > SECUREC_MEM_MAX_LEN) {
72         if (memset_s(&ptr[offset], SECUREC_MEM_MAX_LEN, 0, SECUREC_MEM_MAX_LEN) != EOK) {
73             BSL_SAL_FREE(ptr);
74             return NULL;
75         }
76         offset += SECUREC_MEM_MAX_LEN;
77         blockSize -= SECUREC_MEM_MAX_LEN;
78     }
79     if (memset_s(&ptr[offset], blockSize, 0, blockSize) != EOK) {
80         BSL_SAL_FREE(ptr);
81         return NULL;
82     }
83     return ptr;
84 }
85 
BSL_SAL_Realloc(void * addr,uint32_t newSize,uint32_t oldSize)86 void *BSL_SAL_Realloc(void *addr, uint32_t newSize, uint32_t oldSize)
87 {
88     if (addr == NULL) {
89         return BSL_SAL_Malloc(newSize);
90     }
91     uint32_t minSize = (oldSize > newSize) ? newSize : oldSize;
92 
93     void *ptr = BSL_SAL_Malloc(newSize);
94     if (ptr == NULL) {
95         return NULL;
96     }
97 
98     if (memcpy_s(ptr, newSize, addr, minSize) != EOK) {
99         BSL_SAL_FREE(ptr);
100     } else {
101         BSL_SAL_FREE(addr);
102     }
103 
104     return ptr;
105 }
106 
BSL_SAL_Dump(const void * src,uint32_t size)107 void *BSL_SAL_Dump(const void *src, uint32_t size)
108 {
109     if (src == NULL) {
110         return NULL;
111     }
112     void *ptr = BSL_SAL_Malloc(size);
113     if (ptr == NULL) {
114         return NULL;
115     }
116 
117     if (memcpy_s(ptr, size, src, size) != EOK) {
118         BSL_SAL_FREE(ptr);
119         return NULL;
120     }
121 
122     return ptr;
123 }
124 
SAL_MemCallBack_Ctrl(BSL_SAL_CB_FUNC_TYPE type,void * funcCb)125 int32_t SAL_MemCallBack_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb)
126 {
127     if (type > BSL_SAL_MEM_FREE || type < BSL_SAL_MEM_MALLOC) {
128         return BSL_SAL_ERR_BAD_PARAM;
129     }
130     uint32_t offset = (uint32_t)(type - BSL_SAL_MEM_MALLOC);
131     ((void **)&g_memCallback)[offset] = funcCb;
132     return BSL_SUCCESS;
133 }
134 
135 #if !defined(__clang__)
136 #pragma GCC push_options
137 #pragma GCC optimize("O3")
138 #endif
139 #define CLEAN_THRESHOLD_SIZE 16UL
140 
CleanSensitiveDataLess16Byte(void * buf,uint32_t bufLen)141 static void CleanSensitiveDataLess16Byte(void *buf, uint32_t bufLen)
142 {
143     uint8_t *tmp = (uint8_t *)buf;
144     switch (bufLen) {
145         case 16: *(tmp++) = (uint8_t)0;
146         /* FALLTHRU */
147         case 15: *(tmp++) = (uint8_t)0;
148         /* FALLTHRU */
149         case 14: *(tmp++) = (uint8_t)0;
150         /* FALLTHRU */
151         case 13: *(tmp++) = (uint8_t)0;
152         /* FALLTHRU */
153         case 12: *(tmp++) = (uint8_t)0;
154         /* FALLTHRU */
155         case 11: *(tmp++) = (uint8_t)0;
156         /* FALLTHRU */
157         case 10: *(tmp++) = (uint8_t)0;
158         /* FALLTHRU */
159         case 9: *(tmp++) = (uint8_t)0;
160         /* FALLTHRU */
161         case 8: *(tmp++) = (uint8_t)0;
162         /* FALLTHRU */
163         case 7: *(tmp++) = (uint8_t)0;
164         /* FALLTHRU */
165         case 6: *(tmp++) = (uint8_t)0;
166         /* FALLTHRU */
167         case 5: *(tmp++) = (uint8_t)0;
168         /* FALLTHRU */
169         case 4: *(tmp++) = (uint8_t)0;
170         /* FALLTHRU */
171         case 3: *(tmp++) = (uint8_t)0;
172         /* FALLTHRU */
173         case 2: *(tmp++) = (uint8_t)0;
174         /* FALLTHRU */
175         case 1: *(tmp) = (uint8_t)0;
176         /* FALLTHRU */
177         default:
178             break;
179     }
180 }
181 
CleanSensitiveData(void * buf,uint32_t bufLen)182 static void CleanSensitiveData(void *buf, uint32_t bufLen)
183 {
184     uint8_t *tmp = (uint8_t *)buf;
185     uint32_t boundOpt;
186 
187     if (((uintptr_t)buf & 0x3) == 0) { // buf & 0x3, used to determine whether 4-byte alignment
188         // shift rightwards by 4 bits and then leftwards by 4 bits, which is used to calculate an integer multiple of 16
189         boundOpt = (bufLen >> 4) << 4;
190         for (uint32_t i = 0; i < boundOpt; i += 16) { // Clear 16 pieces of memory each time.
191             uint32_t *ctmp = (uint32_t *)(tmp + i);
192             ctmp[0] = 0;
193             ctmp[1] = 0;
194             ctmp[2] = 0;
195             ctmp[3] = 0;
196         }
197     } else {
198         // shifted rightward by 2 bits and then left by 2 bits, used to calculate an integer multiple of 4.
199         boundOpt = (bufLen >> 2) << 2;
200         for (uint32_t i = 0; i < boundOpt; i += 4) { // Clear 4 pieces of memory each time.
201             tmp[i] = 0;
202             tmp[i + 1] = 0;
203             tmp[i + 2] = 0;
204             tmp[i + 3] = 0;
205         }
206     }
207     for (uint32_t i = boundOpt; i < bufLen; ++i) {
208         tmp[i] = 0;
209     }
210 }
211 
BSL_SAL_CleanseData(void * ptr,uint32_t size)212 void BSL_SAL_CleanseData(void *ptr, uint32_t size)
213 {
214     if (ptr == NULL) {
215         return;
216     }
217     if (size > CLEAN_THRESHOLD_SIZE) {
218         CleanSensitiveData(ptr, size);
219     } else {
220         CleanSensitiveDataLess16Byte(ptr, size);
221     }
222 }
223 
BSL_SAL_ClearFree(void * ptr,uint32_t size)224 void BSL_SAL_ClearFree(void *ptr, uint32_t size)
225 {
226     if (ptr == NULL) {
227         return;
228     }
229     if (size != 0) {
230         BSL_SAL_CleanseData(ptr, size);
231     }
232     BSL_SAL_FREE(ptr);
233 }
234 
235 #if !defined(__clang__)
236 #pragma GCC pop_options
237 #endif
238