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