1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include <stdint.h>
17 #include <pthread.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20
21 #include "hitls_build.h"
22 #include "bsl_sal.h"
23 #include "bsl_errno.h"
24 #include "crypt_errno.h"
25 #include "crypt_types.h"
26 #include "crypt_eal_md.h"
27 #include "eal_md_local.h"
28 #include "crypt_eal_rand.h"
29 #include "crypt_eal_mac.h"
30 #include "crypt_eal_init.h"
31
32 #include "test.h"
33 #include "helper.h"
34 #include "crypto_test_util.h"
35
36 #include "securec.h"
37 #include "crypt_util_rand.h"
38
39 #ifndef HITLS_BSL_SAL_MEM
TestMalloc(uint32_t len)40 void *TestMalloc(uint32_t len)
41 {
42 return malloc((size_t)len);
43 }
44 #endif
45
TestMemInit(void)46 void TestMemInit(void)
47 {
48 #ifdef HITLS_BSL_SAL_MEM
49 return;
50 #else
51 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, TestMalloc);
52 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free);
53 #endif
54 }
55
56 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_DRBG)
57 typedef struct {
58 CRYPT_Data *entropy;
59 CRYPT_Data *nonce;
60 CRYPT_Data *pers;
61
62 CRYPT_Data *addin1;
63 CRYPT_Data *entropyPR1;
64
65 CRYPT_Data *addin2;
66 CRYPT_Data *entropyPR2;
67
68 CRYPT_Data *retBits;
69 } DRBG_Vec_t;
70
71 #ifndef HITLS_CRYPTO_ENTROPY
GetEntropy(void * ctx,CRYPT_Data * entropy,uint32_t strength,CRYPT_Range * lenRange)72 static int32_t GetEntropy(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange)
73 {
74 if (lenRange == NULL) {
75 Print("getEntropy Error lenRange NULL\n");
76 return CRYPT_NULL_INPUT;
77 }
78 if (ctx == NULL || entropy == NULL) {
79 Print("getEntropy Error\n");
80 lenRange->max = strength;
81 return CRYPT_NULL_INPUT;
82 }
83
84 DRBG_Vec_t *seedCtx = (DRBG_Vec_t *)ctx;
85
86 entropy->data = seedCtx->entropy->data;
87 entropy->len = seedCtx->entropy->len;
88
89 return CRYPT_SUCCESS;
90 }
91
CleanEntropy(void * ctx,CRYPT_Data * entropy)92 static void CleanEntropy(void *ctx, CRYPT_Data *entropy)
93 {
94 (void)ctx;
95 (void)entropy;
96 return;
97 }
98 #endif
99
TestSimpleRand(uint8_t * buff,uint32_t len)100 int32_t TestSimpleRand(uint8_t *buff, uint32_t len)
101 {
102 int rand = open("/dev/urandom", O_RDONLY);
103 if (rand < 0) {
104 printf("open /dev/urandom failed.\n");
105 return -1;
106 }
107 int l = read(rand, buff, len);
108 if (l < 0) {
109 printf("read from /dev/urandom failed. errno: %d.\n", errno);
110 close(rand);
111 return -1;
112 }
113 close(rand);
114 return 0;
115 }
116
TestSimpleRandEx(void * libCtx,uint8_t * buff,uint32_t len)117 int32_t TestSimpleRandEx(void *libCtx, uint8_t *buff, uint32_t len)
118 {
119 (void)libCtx;
120 return TestSimpleRand(buff, len);
121 }
122
TestRandInit(void)123 int TestRandInit(void)
124 {
125 int drbgAlgId = GetAvailableRandAlgId();
126 int32_t ret;
127 if (drbgAlgId == -1) {
128 Print("Drbg algs are disabled.");
129 return CRYPT_NOT_SUPPORT;
130 }
131
132 #ifndef HITLS_CRYPTO_ENTROPY
133 CRYPT_RandSeedMethod seedMeth = {GetEntropy, CleanEntropy, NULL, NULL};
134 uint8_t entropy[64] = {0};
135 CRYPT_Data tempEntropy = {entropy, sizeof(entropy)};
136 DRBG_Vec_t seedCtx = {0};
137 seedCtx.entropy = &tempEntropy;
138 #endif
139
140 #ifdef HITLS_CRYPTO_PROVIDER
141 #ifndef HITLS_CRYPTO_ENTROPY
142 BSL_Param param[4] = {0};
143 (void)BSL_PARAM_InitValue(¶m[0], CRYPT_PARAM_RAND_SEEDCTX, BSL_PARAM_TYPE_CTX_PTR, &seedCtx, 0);
144 (void)BSL_PARAM_InitValue(¶m[1], CRYPT_PARAM_RAND_SEED_GETENTROPY, BSL_PARAM_TYPE_FUNC_PTR, seedMeth.getEntropy, 0);
145 (void)BSL_PARAM_InitValue(¶m[2], CRYPT_PARAM_RAND_SEED_CLEANENTROPY, BSL_PARAM_TYPE_FUNC_PTR, seedMeth.cleanEntropy, 0);
146 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, (CRYPT_RAND_AlgId)drbgAlgId, "provider=default", NULL, 0, param);
147 #else
148 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, (CRYPT_RAND_AlgId)drbgAlgId, "provider=default", NULL, 0, NULL);
149 #endif
150 #else
151 #ifndef HITLS_CRYPTO_ENTROPY
152 ret = CRYPT_EAL_RandInit(drbgAlgId, &seedMeth, (void *)&seedCtx, NULL, 0);
153 #else
154 ret = CRYPT_EAL_RandInit(drbgAlgId, NULL, NULL, NULL, 0);
155 #endif
156 #endif
157 if (ret == CRYPT_EAL_ERR_DRBG_REPEAT_INIT) {
158 ret = CRYPT_SUCCESS;
159 }
160 return ret;
161 }
162
TestRandDeInit(void)163 void TestRandDeInit(void)
164 {
165 #ifdef HITLS_CRYPTO_PROVIDER
166 CRYPT_EAL_RandDeinitEx(NULL);
167 #else
168 CRYPT_EAL_RandDeinit();
169 #endif
170 }
171 #endif
172
173 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_MAC)
174
TestGetMacLen(int algId)175 uint32_t TestGetMacLen(int algId)
176 {
177 switch (algId) {
178 case CRYPT_MAC_HMAC_MD5:
179 return 16;
180 case CRYPT_MAC_HMAC_SHA1:
181 return 20;
182 case CRYPT_MAC_HMAC_SHA224:
183 case CRYPT_MAC_HMAC_SHA3_224:
184 return 28;
185 case CRYPT_MAC_HMAC_SHA256:
186 case CRYPT_MAC_HMAC_SHA3_256:
187 return 32;
188 case CRYPT_MAC_HMAC_SHA384:
189 case CRYPT_MAC_HMAC_SHA3_384:
190 return 48;
191 case CRYPT_MAC_HMAC_SHA512:
192 case CRYPT_MAC_HMAC_SHA3_512:
193 return 64;
194 case CRYPT_MAC_HMAC_SM3:
195 return 32;
196 case CRYPT_MAC_CMAC_AES128:
197 case CRYPT_MAC_CMAC_AES192:
198 case CRYPT_MAC_CMAC_AES256:
199 return 16; // AES block size
200 case CRYPT_MAC_CMAC_SM4:
201 return 16;// SM4 block size
202 case CRYPT_MAC_CBC_MAC_SM4:
203 return 16;// SM4 block size
204 case CRYPT_MAC_SIPHASH64:
205 return 8;
206 case CRYPT_MAC_SIPHASH128:
207 return 16;
208 default:
209 return 0;
210 }
211 }
212
TestMacSameAddr(int algId,Hex * key,Hex * data,Hex * mac)213 void TestMacSameAddr(int algId, Hex *key, Hex *data, Hex *mac)
214 {
215 uint32_t outLen = data->len > mac->len ? data->len : mac->len;
216 uint8_t out[outLen];
217 CRYPT_EAL_MacCtx *ctx = NULL;
218 int padType = CRYPT_PADDING_ZEROS;
219
220 ASSERT_EQ(memcpy_s(out, outLen, data->x, data->len), 0);
221 TestMemInit();
222
223 ASSERT_TRUE((ctx = CRYPT_EAL_MacNewCtx(algId)) != NULL);
224 ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key->x, key->len), CRYPT_SUCCESS);
225 if (algId == CRYPT_MAC_CBC_MAC_SM4) {
226 ASSERT_EQ(CRYPT_EAL_MacCtrl(ctx, CRYPT_CTRL_SET_CBC_MAC_PADDING, &padType, sizeof(int)), CRYPT_SUCCESS);
227 }
228 ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, out, data->len), CRYPT_SUCCESS);
229 ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, out, &outLen), CRYPT_SUCCESS);
230 ASSERT_COMPARE("mac result cmp", out, outLen, mac->x, mac->len);
231
232 EXIT:
233 CRYPT_EAL_MacFreeCtx(ctx);
234 }
235
TestMacAddrNotAlign(int algId,Hex * key,Hex * data,Hex * mac)236 void TestMacAddrNotAlign(int algId, Hex *key, Hex *data, Hex *mac)
237 {
238 uint32_t outLen = data->len > mac->len ? data->len : mac->len;
239 uint8_t out[outLen];
240 CRYPT_EAL_MacCtx *ctx = NULL;
241 int padType = CRYPT_PADDING_ZEROS;
242 uint8_t keyTmp[key->len + 1] __attribute__((aligned(8)));
243 uint8_t dataTmp[data->len + 1] __attribute__((aligned(8)));
244 uint8_t *pKey = keyTmp + 1;
245 uint8_t *pData = dataTmp + 1;
246
247 ASSERT_TRUE(memcpy_s(pKey, key->len, key->x, key->len) == EOK);
248 ASSERT_TRUE(memcpy_s(pData, data->len, data->x, data->len) == EOK);
249 TestMemInit();
250
251 ASSERT_TRUE((ctx = CRYPT_EAL_MacNewCtx(algId)) != NULL);
252 ASSERT_EQ(CRYPT_EAL_MacInit(ctx, pKey, key->len), CRYPT_SUCCESS);
253 if (algId == CRYPT_MAC_CBC_MAC_SM4) {
254 ASSERT_EQ(CRYPT_EAL_MacCtrl(ctx, CRYPT_CTRL_SET_CBC_MAC_PADDING, &padType, sizeof(int)), CRYPT_SUCCESS);
255 }
256 ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, pData, data->len), CRYPT_SUCCESS);
257 ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, out, &outLen), CRYPT_SUCCESS);
258 ASSERT_COMPARE("mac result cmp", out, outLen, mac->x, mac->len);
259
260 EXIT:
261 CRYPT_EAL_MacFreeCtx(ctx);
262 }
263 #endif
264
265 #ifdef HITLS_CRYPTO_CIPHER
TestCipherNewCtx(CRYPT_EAL_LibCtx * libCtx,int32_t id,const char * attrName,int isProvider)266 CRYPT_EAL_CipherCtx *TestCipherNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t id, const char *attrName, int isProvider)
267 {
268 #ifdef HITLS_CRYPTO_PROVIDER
269 if (isProvider == 1) {
270 if (CRYPT_EAL_Init(0) != CRYPT_SUCCESS) {
271 return NULL;
272 }
273 return CRYPT_EAL_ProviderCipherNewCtx(libCtx, id, attrName);
274 } else {
275 return CRYPT_EAL_CipherNewCtx(id);
276 }
277 #else
278 (void)libCtx;
279 (void)attrName;
280 (void)isProvider;
281 return CRYPT_EAL_CipherNewCtx(id);
282 #endif
283 }
284 #endif
285
286 #ifdef HITLS_CRYPTO_PKEY
TestPkeyNewCtx(CRYPT_EAL_LibCtx * libCtx,int32_t id,uint32_t operType,const char * attrName,int isProvider)287 CRYPT_EAL_PkeyCtx *TestPkeyNewCtx(
288 CRYPT_EAL_LibCtx *libCtx, int32_t id, uint32_t operType, const char *attrName, int isProvider)
289 {
290 #ifdef HITLS_CRYPTO_PROVIDER
291 if (isProvider == 1) {
292 if (CRYPT_EAL_Init(0) != CRYPT_SUCCESS) {
293 return NULL;
294 }
295 return CRYPT_EAL_ProviderPkeyNewCtx(libCtx, id, operType, attrName);
296 } else {
297 return CRYPT_EAL_PkeyNewCtx(id);
298 }
299 #else
300 (void)libCtx;
301 (void)operType;
302 (void)attrName;
303 (void)isProvider;
304 return CRYPT_EAL_PkeyNewCtx(id);
305 #endif
306 }
307 #endif