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