1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <ctype.h>
16 #include <string.h>
17 #include <securec.h>
18 #include <time.h>
19 #include "mbedtls/ctr_drbg.h"
20 #include "mbedtls/entropy.h"
21 #include "mbedtls/sha256.h"
22 #include "mbedtls/version.h"
23 #include "attest_utils_log.h"
24 #include "attest_utils_memleak.h"
25 #include "attest_utils.h"
26
27 #define PER_BYTE_BITS 8
28 #define RANDOM_BYTES 4
29
30 #if defined(MBEDTLS_VERSION_NUMBER) && (MBEDTLS_VERSION_NUMBER >= 0x03000000)
31 #define mbedtls_sha256_starts_ret mbedtls_sha256_starts
32 #define mbedtls_sha256_update_ret mbedtls_sha256_update
33 #define mbedtls_sha256_finish_ret mbedtls_sha256_finish
34 #endif
35
GetRandomNum(void)36 int32_t GetRandomNum(void)
37 {
38 mbedtls_ctr_drbg_context randomContext;
39 mbedtls_entropy_context randomEntropy;
40 mbedtls_ctr_drbg_init(&randomContext);
41 mbedtls_entropy_init(&randomEntropy);
42 const char* pers = "CTR_DRBG";
43 int32_t result = 0;
44 unsigned char* random = (unsigned char *)ATTEST_MEM_MALLOC(RANDOM_BYTES);
45 if (random == NULL) {
46 return 0;
47 }
48 do {
49 int32_t ret = mbedtls_ctr_drbg_seed(&randomContext, mbedtls_entropy_func, &randomEntropy,
50 (const uint8_t*)pers, strlen(pers));
51 if (ret != ATTEST_OK) {
52 break;
53 }
54 ret = mbedtls_ctr_drbg_random(&randomContext, random, RANDOM_BYTES);
55 if (ret != ATTEST_OK) {
56 break;
57 }
58
59 result = random[RANDOM_BYTES - 1];
60 for (int i = RANDOM_BYTES - 2; i >= 0; --i) {
61 result <<= PER_BYTE_BITS;
62 result |= random[i];
63 }
64 } while (0);
65 mbedtls_ctr_drbg_free(&randomContext);
66 mbedtls_entropy_free(&randomEntropy);
67 ATTEST_MEM_FREE(random);
68 return ABS(result);
69 }
70
AttestStrdup(const char* input)71 char* AttestStrdup(const char* input)
72 {
73 if (input == NULL) {
74 return NULL;
75 }
76 size_t inputLen = strlen(input);
77 if (inputLen == 0 || inputLen >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
78 return NULL;
79 }
80
81 size_t outputLen = inputLen + 1;
82 char* out = ATTEST_MEM_MALLOC(outputLen);
83 if (out == NULL) {
84 return NULL;
85 }
86 if (memcpy_s(out, outputLen, input, inputLen) != 0) {
87 ATTEST_MEM_FREE(out);
88 return NULL;
89 }
90 return out;
91 }
92
URLSafeBase64ToBase64(const char* input, size_t inputLen, uint8_t** output, size_t* outputLen)93 void URLSafeBase64ToBase64(const char* input, size_t inputLen, uint8_t** output, size_t* outputLen)
94 {
95 const uint8_t tempInputLen = 4;
96 if (input == NULL || output == NULL || outputLen == NULL) {
97 ATTEST_LOG_ERROR("[URLSafeBase64ToBase64] Invalid parameter");
98 return;
99 }
100 if (inputLen == 0 || inputLen >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
101 return;
102 }
103 *outputLen = inputLen + ((inputLen % tempInputLen == 0) ? 0 : (tempInputLen - inputLen % tempInputLen));
104 if (*outputLen == 0 || *outputLen >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
105 return;
106 }
107 *output = (uint8_t *)ATTEST_MEM_MALLOC(*outputLen + 1);
108 if (*output == NULL) {
109 return;
110 }
111 size_t i;
112 for (i = 0; i < inputLen; ++i) {
113 if (input[i] == '-') {
114 (*output)[i] = '+';
115 continue;
116 }
117 if (input[i] == '_') {
118 (*output)[i] = '/';
119 continue;
120 }
121 (*output)[i] = input[i];
122 }
123 for (i = inputLen; i < *outputLen; ++i) {
124 (*output)[i] = '=';
125 }
126 }
127
CalUnAnonyStrLen(uint32_t strLen)128 static uint32_t CalUnAnonyStrLen(uint32_t strLen)
129 {
130 uint32_t len = 1;
131 uint32_t tempLen = 2;
132 while ((tempLen * len) < strLen) {
133 len = len * tempLen;
134 }
135 return len / 2; // len / 2即保留信息的字符串总长度
136 }
137
138 // 匿名化算法:长度小于8, 全部匿名; 长度大于8,保留前后信息,中间匿名化,一半保留一半匿名化。
AnonymiseStr(char* str)139 int32_t AnonymiseStr(char* str)
140 {
141 if (str == NULL || strlen(str) == 0) {
142 return ATTEST_ERR;
143 }
144 uint32_t strLen = strlen(str);
145 int32_t ret;
146 uint32_t tempLen = 8;
147 if (strLen <= tempLen) {
148 ret = memset_s((void*)str, strLen, '*', strLen);
149 } else {
150 const uint32_t halfLen = 2;
151 int32_t unAnonyStrLen = CalUnAnonyStrLen(strLen);
152 int32_t endpointLen = unAnonyStrLen / halfLen;
153 ret = memset_s((void*)(str + endpointLen), (strLen - unAnonyStrLen), '*', (strLen - unAnonyStrLen));
154 }
155 if (ret != 0) {
156 ret = ATTEST_ERR;
157 }
158 return ret;
159 }
160
PrintCurrentTime(void)161 void PrintCurrentTime(void)
162 {
163 time_t timet;
164 (void)time(&timet);
165 struct tm* timePacket = gmtime(&timet);
166 if (timePacket == NULL) {
167 return;
168 }
169 ATTEST_LOG_INFO("[PrintCurrentTime] Hours: %d, Minutes: %d, Seconds: %d",
170 timePacket->tm_hour, timePacket->tm_min, timePacket->tm_sec);
171 }
172
173 // 字符串转化为小写
ToLowerStr(char* str, int len)174 int32_t ToLowerStr(char* str, int len)
175 {
176 if (str == NULL) {
177 ATTEST_LOG_ERROR("[ToLowerStr] Str is NUll");
178 return ATTEST_ERR;
179 }
180
181 for (int i = 0; i < len; i++) {
182 str[i] = tolower(str[i]);
183 }
184 return ATTEST_OK;
185 }
186
Sha256ValueToAscii(const unsigned char *src, int srcLen, char *dest, int destLen)187 int Sha256ValueToAscii(const unsigned char *src, int srcLen, char *dest, int destLen)
188 {
189 if (src == NULL || srcLen <= 0 || dest == NULL || destLen <= 0) {
190 ATTEST_LOG_ERROR("[Sha256ValueToAscii] Invalid parameter");
191 return ATTEST_ERR;
192 }
193
194 unsigned char hash[HASH_LENGTH] = {0};
195
196 mbedtls_sha256_context context;
197 mbedtls_sha256_init(&context);
198 mbedtls_sha256_starts_ret(&context, 0);
199 mbedtls_sha256_update_ret(&context, src, srcLen);
200 mbedtls_sha256_finish_ret(&context, hash);
201
202 int ret = ATTEST_OK;
203 if (memcpy_s(dest, destLen, hash, HASH_LENGTH) != 0) {
204 ATTEST_LOG_ERROR("[Sha256ValueToAscii] Failed to memcpy");
205 ret = ATTEST_ERR;
206 }
207 (void)memset_s(hash, HASH_LENGTH, 0, HASH_LENGTH);
208 return ret;
209 }
210
211 /**
212 * @brief Encrypt string with sha256 algorithm, and generate uppercase string.
213 *
214 */
Sha256Value(const unsigned char *src, int srcLen, char *dest, int destLen)215 int Sha256Value(const unsigned char *src, int srcLen, char *dest, int destLen)
216 {
217 if (src == NULL || srcLen <= 0 || dest == NULL || destLen <= 0) {
218 ATTEST_LOG_ERROR("[Sha256ValueToAscii] Invalid parameter");
219 return ATTEST_ERR;
220 }
221 char buf[DEV_BUF_LENGTH] = {0};
222 char hash[HASH_LENGTH] = {0};
223
224 int32_t ret = Sha256ValueToAscii(src, srcLen, hash, HASH_LENGTH);
225 if (ret != ATTEST_OK) {
226 return ATTEST_ERR;
227 }
228
229 for (int i = 0; i < HASH_LENGTH; i++) {
230 (void)memset_s(buf, DEV_BUF_LENGTH, 0, DEV_BUF_LENGTH);
231 // generate uppercase string
232 if (sprintf_s(buf, sizeof(buf), "%02X", hash[i]) < 0) {
233 ret = ATTEST_ERR;
234 break;
235 }
236 if (strcat_s(dest, destLen, buf) != 0) {
237 ret = ATTEST_ERR;
238 break;
239 }
240 }
241 (void)memset_s(buf, DEV_BUF_LENGTH, 0, DEV_BUF_LENGTH);
242 (void)memset_s(hash, HASH_LENGTH, 0, HASH_LENGTH);
243 return ret;
244 }
245
AttestMemAlloc(uint32_t size, const char* file, uint32_t line, const char* func)246 void *AttestMemAlloc(uint32_t size, const char* file, uint32_t line, const char* func)
247 {
248 if (size == 0) {
249 return NULL;
250 }
251 void *addr = malloc(size);
252 if (addr == NULL) {
253 return NULL;
254 }
255 int32_t ret = memset_s(addr, size, 0, size);
256 if (ret != 0) {
257 free(addr);
258 return NULL;
259 }
260 if (ATTEST_DEBUG_MEMORY_LEAK) {
261 (void)AddMemInfo(addr, file, line, func);
262 }
263 return addr;
264 }
265
AttestMemFree(void **point)266 void AttestMemFree(void **point)
267 {
268 if (point == NULL || *point == NULL) {
269 return;
270 }
271 if (ATTEST_DEBUG_MEMORY_LEAK) {
272 (void)RemoveMemInfo(*point);
273 }
274 free(*point);
275 *point = NULL;
276 }
277
CharToAscii(const char* str, uint32_t len, uint8_t* outputStr, uint32_t outputLen)278 int32_t CharToAscii(const char* str, uint32_t len, uint8_t* outputStr, uint32_t outputLen)
279 {
280 // tokenId {a-f,0-9,-}
281 if (str == NULL || len == 0 || outputStr == NULL || outputLen == 0) {
282 ATTEST_LOG_ERROR("[CharToAscii] Invaild paramter");
283 return ATTEST_ERR;
284 }
285 if (strlen(str) < len) {
286 ATTEST_LOG_ERROR("[CharToAscii] Invaild len");
287 return ATTEST_ERR;
288 }
289 // Max length of outStr is OUT_STR_LEN_MAX, but if the last char of str need to conver 2 char,
290 // outStr should reserve one more size.
291 const uint32_t outStrLenMax = OUT_STR_LEN_MAX + 1;
292 char outStr[OUT_STR_LEN_MAX + 2] = {0};
293 for (uint32_t i = 0, j = 0; i < len; i++) {
294 if (j >= outStrLenMax) {
295 break;
296 }
297 if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'g' && str[i] <= 'z')) {
298 outStr[j++] = (str[i] - '0') / DECIMAL_BASE + '0';
299 outStr[j++] = (str[i] - '0') % DECIMAL_BASE + '0';
300 } else {
301 outStr[j++] = str[i];
302 }
303 }
304 int32_t ret = ATTEST_OK;
305 do {
306 if (strnlen(outStr, outStrLenMax) == outStrLenMax) {
307 ATTEST_LOG_ERROR("[CharToAscii] Out of the outStrLenMax");
308 ret = ATTEST_ERR;
309 break;
310 }
311 uint32_t outStrLen = strlen(outStr);
312 if (outStrLen >= outputLen) {
313 ATTEST_LOG_ERROR("[CharToAscii] Out of the outputLen");
314 ret = ATTEST_ERR;
315 break;
316 }
317 if (memcpy_s(outputStr, outputLen, outStr, outStrLen) != 0) {
318 ret = ATTEST_ERR;
319 break;
320 }
321 } while (0);
322 (void)memset_s(outStr, outStrLenMax + 1, 0, outStrLenMax + 1);
323 return ret;
324 }
325
HexToNumber(char inputChr)326 static int32_t HexToNumber(char inputChr)
327 {
328 int retNumber = 0;
329 if (inputChr >= '0' && inputChr <= '9') {
330 retNumber = inputChr - '0';
331 } else if (inputChr >= 'a' && inputChr <= 'f') {
332 retNumber = DECIMAL_BASE + inputChr - 'a';
333 } else if (inputChr >= 'A' && inputChr <= 'F') {
334 retNumber = DECIMAL_BASE + inputChr - 'A';
335 } else {
336 retNumber = ATTEST_ERR;
337 }
338 return retNumber;
339 }
340
HEXStringToAscii(const char* input, int32_t inputLen, char* output, int32_t outputLen)341 int32_t HEXStringToAscii(const char* input, int32_t inputLen, char* output, int32_t outputLen)
342 {
343 if (input == NULL || inputLen <= 0 || output == NULL || (inputLen % ATTEST_EVEN_NUMBER == 1)) {
344 ATTEST_LOG_ERROR("[HEXStringToAscii] Invaild paramter");
345 return ATTEST_ERR;
346 }
347
348 if (outputLen < (inputLen / ATTEST_EVEN_NUMBER)) {
349 ATTEST_LOG_ERROR("[HEXStringToAscii] outputLen is shorter than required");
350 return ATTEST_ERR;
351 }
352
353 int tempLen = 0;
354 int32_t ret = ATTEST_OK;
355 for(int i = 0; i < inputLen; ) {
356 int highNumber = HexToNumber(input[i]);
357 int lowNumber = HexToNumber(input[i + 1]);
358 if (highNumber == ATTEST_ERR || lowNumber == ATTEST_ERR) {
359 ret = ATTEST_ERR;
360 break;
361 }
362 output[tempLen++] = highNumber * HEXADECIMAL_BASE + lowNumber;
363 i += ATTEST_EVEN_NUMBER;
364 }
365 return ret;
366 }
367