• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 DEV_BUF_LENGTH   3
28 #define HASH_LENGTH      32
29 #define DECIMAL_BASE     10
30 #define PER_BYTE_BITS    8
31 #define RANDOM_BYTES     4
32 
33 #if defined(MBEDTLS_VERSION_NUMBER) && (MBEDTLS_VERSION_NUMBER >= 0x03000000)
34 #define mbedtls_sha256_starts_ret mbedtls_sha256_starts
35 #define mbedtls_sha256_update_ret mbedtls_sha256_update
36 #define mbedtls_sha256_finish_ret mbedtls_sha256_finish
37 #endif
38 
GetRandomNum(void)39 int32_t GetRandomNum(void)
40 {
41     mbedtls_ctr_drbg_context randomContext;
42     mbedtls_entropy_context randomEntropy;
43     mbedtls_ctr_drbg_init(&randomContext);
44     mbedtls_entropy_init(&randomEntropy);
45     const char* pers = "CTR_DRBG";
46     int32_t result = 0;
47     unsigned char* random = (unsigned char *)ATTEST_MEM_MALLOC(RANDOM_BYTES);
48     if (random == NULL) {
49         return 0;
50     }
51     do {
52         int32_t ret = mbedtls_ctr_drbg_seed(&randomContext, mbedtls_entropy_func, &randomEntropy,
53                                             (const uint8_t*)pers, strlen(pers));
54         if (ret != ATTEST_OK) {
55             break;
56         }
57         ret = mbedtls_ctr_drbg_random(&randomContext, random, RANDOM_BYTES);
58         if (ret != ATTEST_OK) {
59             break;
60         }
61 
62         result = random[RANDOM_BYTES - 1];
63         for (int i = RANDOM_BYTES - 2; i >= 0; --i) {
64             result <<= PER_BYTE_BITS;
65             result |= random[i];
66         }
67     } while (0);
68     mbedtls_ctr_drbg_free(&randomContext);
69     mbedtls_entropy_free(&randomEntropy);
70     ATTEST_MEM_FREE(random);
71     return ABS(result);
72 }
73 
AttestStrdup(const char * input)74 char* AttestStrdup(const char* input)
75 {
76     if (input == NULL) {
77         return NULL;
78     }
79     size_t len = strlen(input) + 1;
80     if (len <= 1) {
81         return NULL;
82     }
83     char* out = ATTEST_MEM_MALLOC(len);
84     if (out == NULL) {
85         return NULL;
86     }
87     if (memcpy_s(out, len, input, strlen(input)) != 0) {
88         ATTEST_MEM_FREE(out);
89         return NULL;
90     }
91     return out;
92 }
93 
URLSafeBase64ToBase64(const char * input,size_t inputLen,uint8_t ** output,size_t * outputLen)94 void URLSafeBase64ToBase64(const char* input, size_t inputLen, uint8_t** output, size_t* outputLen)
95 {
96     uint8_t tempInputLen = 4;
97     if (input == NULL || inputLen == 0 || output == NULL || outputLen == NULL) {
98         ATTEST_LOG_ERROR("[URLSafeBase64ToBase64] Invalid parameter");
99         return;
100     }
101     *outputLen = inputLen + ((inputLen % tempInputLen == 0) ? 0 : (tempInputLen - inputLen % tempInputLen));
102     if (*outputLen == 0) {
103         return;
104     }
105     *output = (uint8_t *)ATTEST_MEM_MALLOC(*outputLen + 1);
106     if (*output == NULL) {
107         return;
108     }
109     size_t i;
110     for (i = 0; i < inputLen; ++i) {
111         if (input[i] == '-') {
112             (*output)[i] = '+';
113             continue;
114         }
115         if (input[i] == '_') {
116             (*output)[i] = '/';
117             continue;
118         }
119         (*output)[i] = input[i];
120     }
121     for (i = inputLen; i < *outputLen; ++i) {
122         (*output)[i] = '=';
123     }
124 }
125 
CalUnAnonyStrLen(uint32_t strLen)126 static uint32_t CalUnAnonyStrLen(uint32_t strLen)
127 {
128     uint32_t len = 1;
129     uint32_t tempLen = 2;
130     while ((tempLen * len) < strLen) {
131         len = len * tempLen;
132     }
133     return len / 2; // len / 2即保留信息的字符串总长度
134 }
135 
136 // 匿名化算法:长度小于8, 全部匿名;    长度大于8,保留前后信息,中间匿名化,一半保留一半匿名化。
AnonymiseStr(char * str)137 int32_t AnonymiseStr(char* str)
138 {
139     if (str == NULL || strlen(str) == 0) {
140         return ATTEST_ERR;
141     }
142     uint32_t strLen = strlen(str);
143     int32_t ret;
144     uint32_t tempLen = 8;
145     if (strLen <= tempLen) {
146         ret = memset_s((void*)str, strLen, '*', strLen);
147     } else {
148         uint32_t halfLen = 2;
149         int32_t unAnonyStrLen = CalUnAnonyStrLen(strLen);
150         int32_t endpointLen = unAnonyStrLen / halfLen;
151         ret = memset_s((void*)(str + endpointLen), (strLen - unAnonyStrLen), '*', (strLen - unAnonyStrLen));
152     }
153     if (ret != 0) {
154         ret = ATTEST_ERR;
155     }
156     return ret;
157 }
158 
PrintCurrentTime(void)159 void PrintCurrentTime(void)
160 {
161     time_t timet;
162     (void)time(&timet);
163     struct tm* timePacket = gmtime(&timet);
164     if (timePacket == NULL) {
165         return;
166     }
167     ATTEST_LOG_INFO("[PrintCurrentTime] Hours: %d, Minutes: %d, Seconds: %d",
168         timePacket->tm_hour, timePacket->tm_min, timePacket->tm_sec);
169 }
170 
171 // 字符串转化为小写
ToLowerStr(char * str,int len)172 int32_t ToLowerStr(char* str, int len)
173 {
174     if (str == NULL) {
175         ATTEST_LOG_ERROR("[ToLowerStr] Str is NUll");
176         return ATTEST_ERR;
177     }
178 
179     for (int i = 0; i < len; i++) {
180         str[i] = tolower(str[i]);
181     }
182     return ATTEST_OK;
183 }
184 
185 /**
186  * @brief Encrypt string with sha256 algorithm, and generate uppercase string.
187  *
188  */
Sha256Value(const unsigned char * src,int srcLen,char * dest,int destLen)189 int Sha256Value(const unsigned char *src, int srcLen, char *dest, int destLen)
190 {
191     if (src == NULL) {
192         return ATTEST_ERR;
193     }
194     char buf[DEV_BUF_LENGTH] = {0};
195     unsigned char hash[HASH_LENGTH] = {0};
196 
197     mbedtls_sha256_context context;
198     mbedtls_sha256_init(&context);
199     mbedtls_sha256_starts_ret(&context, 0);
200     mbedtls_sha256_update_ret(&context, src, srcLen);
201     mbedtls_sha256_finish_ret(&context, hash);
202 
203     for (size_t i = 0; i < HASH_LENGTH; i++) {
204         unsigned char value = hash[i];
205         (void)memset_s(buf, DEV_BUF_LENGTH, 0, DEV_BUF_LENGTH);
206         if (sprintf_s(buf, sizeof(buf), "%02X", value) < 0) {
207             return ATTEST_ERR;
208         }
209         if (strcat_s(dest, destLen, buf) != 0) {
210             return ATTEST_ERR;
211         }
212     }
213     return ATTEST_OK;
214 }
215 
AttestMemAlloc(uint32_t size,const char * file,uint32_t line,const char * func)216 void *AttestMemAlloc(uint32_t size, const char* file, uint32_t line, const char* func)
217 {
218     if (size == 0) {
219         return NULL;
220     }
221     void *addr = malloc(size);
222     if (addr == NULL) {
223         return NULL;
224     }
225     int32_t ret = memset_s(addr, size, 0, size);
226     if (ret != 0) {
227         free(addr);
228         return NULL;
229     }
230     if (ATTEST_DEBUG_MEMORY_LEAK) {
231         (void)AddMemInfo(addr, file, line, func);
232     }
233     return addr;
234 }
235 
AttestMemFree(void ** point)236 void AttestMemFree(void **point)
237 {
238     if (point == NULL || *point == NULL) {
239         return;
240     }
241     if (ATTEST_DEBUG_MEMORY_LEAK) {
242         (void)RemoveMemInfo(*point);
243     }
244     free(*point);
245     *point = NULL;
246 }
247 
CharToAscii(const char * str,int len,uint8_t * outputStr,int outputLen)248 int32_t CharToAscii(const char* str, int len, uint8_t* outputStr, int outputLen)
249 {
250     if (str == NULL || outputStr == NULL) {
251         ATTEST_LOG_ERROR("[CharToAscii] Str is NUll");
252         return ATTEST_ERR;
253     }
254     uint8_t outStr[OUT_STR_LEN_MAX] = {0};
255     for (int i = 0, j = 0; i < len; i++) {
256         if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'g' && str[i] <= 'z')) {
257             outStr[j++] = (str[i] - '0') / DECIMAL_BASE + '0';
258             outStr[j++] = (str[i] - '0') % DECIMAL_BASE + '0';
259         } else {
260             outStr[j++] = str[i];
261         }
262     }
263     int32_t outStrLen = strlen((const char*)outStr);
264     if (outStrLen >= outputLen) {
265         ATTEST_LOG_ERROR("[CharToAscii] out of the len");
266         return ATTEST_ERR;
267     }
268     if (memcpy_s(outputStr, outputLen, outStr, outStrLen) != 0) {
269         return ATTEST_ERR;
270     }
271     return ATTEST_OK;
272 }
273 
274