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