• 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 "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