xref: /OK3568_Linux_fs/external/security/librkcrypto/test/test_hash.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
3*4882a593Smuzhiyun  */
4*4882a593Smuzhiyun #include <stdlib.h>
5*4882a593Smuzhiyun #include <string.h>
6*4882a593Smuzhiyun #include <time.h>
7*4882a593Smuzhiyun #include "rkcrypto_core.h"
8*4882a593Smuzhiyun #include "rkcrypto_mem.h"
9*4882a593Smuzhiyun #include "rkcrypto_trace.h"
10*4882a593Smuzhiyun #include "cmode_adapter.h"
11*4882a593Smuzhiyun #include "test_hash.h"
12*4882a593Smuzhiyun #include "test_utils.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define HASH_MAX_LEN	64
15*4882a593Smuzhiyun #define TEST_DATA_MAX	(1024 * 1024 - 31)
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun struct test_hash_item {
18*4882a593Smuzhiyun 	uint32_t algo;
19*4882a593Smuzhiyun 	uint32_t blocksize;
20*4882a593Smuzhiyun };
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun static struct test_hash_item test_hash_tbl[] = {
23*4882a593Smuzhiyun 	{RK_ALGO_MD5,        MD5_BLOCK_SIZE},
24*4882a593Smuzhiyun 	{RK_ALGO_SHA1,       SHA1_BLOCK_SIZE},
25*4882a593Smuzhiyun 	{RK_ALGO_SHA256,     SHA256_BLOCK_SIZE},
26*4882a593Smuzhiyun 	{RK_ALGO_SHA224,     SHA224_BLOCK_SIZE},
27*4882a593Smuzhiyun 	{RK_ALGO_SHA512,     SHA512_BLOCK_SIZE},
28*4882a593Smuzhiyun 	{RK_ALGO_SHA384,     SHA384_BLOCK_SIZE},
29*4882a593Smuzhiyun 	{RK_ALGO_SHA512_224, SHA512_224_BLOCK_SIZE},
30*4882a593Smuzhiyun 	{RK_ALGO_SHA512_256, SHA512_256_BLOCK_SIZE},
31*4882a593Smuzhiyun 	{RK_ALGO_SM3,        SM3_BLOCK_SIZE},
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun static struct test_hash_item test_hmac_tbl[] = {
35*4882a593Smuzhiyun 	{RK_ALGO_HMAC_MD5,    MD5_BLOCK_SIZE},
36*4882a593Smuzhiyun 	{RK_ALGO_HMAC_SHA1,   SHA1_BLOCK_SIZE},
37*4882a593Smuzhiyun 	{RK_ALGO_HMAC_SHA256, SHA256_BLOCK_SIZE},
38*4882a593Smuzhiyun 	{RK_ALGO_HMAC_SHA512, SHA512_BLOCK_SIZE},
39*4882a593Smuzhiyun 	{RK_ALGO_HMAC_SM3,    SM3_BLOCK_SIZE},
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
test_hash_item_virt(const struct test_hash_item * item,uint8_t * buffer,uint32_t buffer_len,bool is_hmac,int verbose)42*4882a593Smuzhiyun static RK_RES test_hash_item_virt(const struct test_hash_item *item,
43*4882a593Smuzhiyun 				  uint8_t *buffer, uint32_t buffer_len, bool is_hmac, int verbose)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
46*4882a593Smuzhiyun 	uint32_t data_block = 32 * 1024;
47*4882a593Smuzhiyun 	uint32_t out_len, tmp_len;
48*4882a593Smuzhiyun 	uint8_t hash_soft[HASH_MAX_LEN], hash_hard[HASH_MAX_LEN];
49*4882a593Smuzhiyun 	uint8_t key[MAX_HASH_BLOCK_SIZE];
50*4882a593Smuzhiyun 	uint8_t *tmp_data;
51*4882a593Smuzhiyun 	const char *test_name = "hash";
52*4882a593Smuzhiyun 	rk_handle hash_hdl = 0;
53*4882a593Smuzhiyun 	rk_hash_config hash_cfg;
54*4882a593Smuzhiyun 	uint32_t algo, key_len;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	test_get_rng(buffer, buffer_len);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	memset(hash_soft, 0x00, sizeof(hash_soft));
59*4882a593Smuzhiyun 	memset(hash_hard, 0x00, sizeof(hash_hard));
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	algo    = item->algo;
62*4882a593Smuzhiyun 	key_len = item->blocksize;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	memset(&hash_cfg, 0x00, sizeof(hash_cfg));
65*4882a593Smuzhiyun 	hash_cfg.algo = algo;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	if (is_hmac) {
68*4882a593Smuzhiyun 		test_get_rng(key, key_len);
69*4882a593Smuzhiyun 		hash_cfg.key     = key;
70*4882a593Smuzhiyun 		hash_cfg.key_len = key_len;
71*4882a593Smuzhiyun 		test_name = "hmac";
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	res = rk_hash_init(&hash_cfg, &hash_hdl);
75*4882a593Smuzhiyun 	if (res) {
76*4882a593Smuzhiyun 		if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
77*4882a593Smuzhiyun 			E_TRACE("rk_hash_init error[%x]\n", res);
78*4882a593Smuzhiyun 			goto exit;
79*4882a593Smuzhiyun 		}
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 		if (verbose)
82*4882a593Smuzhiyun 			printf("virt:\t[%12s]\tN/A\n", test_algo_name(algo));
83*4882a593Smuzhiyun 		return RK_CRYPTO_SUCCESS;
84*4882a593Smuzhiyun 	}
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	tmp_len  = buffer_len;
87*4882a593Smuzhiyun 	tmp_data = buffer;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	while (tmp_len) {
90*4882a593Smuzhiyun 		data_block = tmp_len > data_block ? data_block : tmp_len;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 		res = rk_hash_update_virt(hash_hdl, tmp_data, data_block);
93*4882a593Smuzhiyun 		if (res) {
94*4882a593Smuzhiyun 			rk_hash_final(hash_hdl, NULL);
95*4882a593Smuzhiyun 			E_TRACE("rk_hash_update_virt[%lu/%u] error = %d\n",
96*4882a593Smuzhiyun 				(unsigned long)(tmp_data - buffer), tmp_len, res);
97*4882a593Smuzhiyun 			goto exit;
98*4882a593Smuzhiyun 		}
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 		tmp_len -= data_block;
101*4882a593Smuzhiyun 		tmp_data += data_block;
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	rk_hash_final(hash_hdl, hash_hard);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	if (is_hmac)
107*4882a593Smuzhiyun 		res = soft_hmac(algo, key, key_len, buffer, buffer_len, hash_soft, &out_len);
108*4882a593Smuzhiyun 	else
109*4882a593Smuzhiyun 		res = soft_hash(algo, buffer, buffer_len, hash_soft, &out_len);
110*4882a593Smuzhiyun 	if (res) {
111*4882a593Smuzhiyun 		E_TRACE("soft_%s error[%x]\n", test_name, res);
112*4882a593Smuzhiyun 		goto exit;
113*4882a593Smuzhiyun 	}
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	/* Verify the result */
116*4882a593Smuzhiyun 	if (memcmp(hash_hard, hash_soft, out_len) != 0) {
117*4882a593Smuzhiyun 		E_TRACE("test_%s_item_virt compare failed.\n", test_name);
118*4882a593Smuzhiyun 		test_dump_hex("hash_hard", hash_hard, out_len);
119*4882a593Smuzhiyun 		test_dump_hex("hash_soft", hash_soft, out_len);
120*4882a593Smuzhiyun 		res = RK_CRYPTO_ERR_GENERIC;
121*4882a593Smuzhiyun 		goto exit;
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	hash_hdl = 0;
125*4882a593Smuzhiyun 	if (verbose)
126*4882a593Smuzhiyun 		printf("virt:\t[%12s]\tPASS\n", test_algo_name(algo));
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	res = RK_CRYPTO_SUCCESS;
129*4882a593Smuzhiyun exit:
130*4882a593Smuzhiyun 	if (res)
131*4882a593Smuzhiyun 		printf("virt:\t[%12s]\tFAIL\n", test_algo_name(algo));
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	return res;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun 
test_hash_item_fd(const struct test_hash_item * item,rk_crypto_mem * buffer,bool is_hmac,int verbose)136*4882a593Smuzhiyun static RK_RES test_hash_item_fd(const struct test_hash_item *item,
137*4882a593Smuzhiyun 				rk_crypto_mem *buffer, bool is_hmac, int verbose)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
140*4882a593Smuzhiyun 	uint32_t out_len;
141*4882a593Smuzhiyun 	uint8_t hash_soft[HASH_MAX_LEN], hash_hard[HASH_MAX_LEN];
142*4882a593Smuzhiyun 	uint8_t key[MAX_HASH_BLOCK_SIZE];
143*4882a593Smuzhiyun 	const char *test_name = "hash";
144*4882a593Smuzhiyun 	rk_handle hash_hdl = 0;
145*4882a593Smuzhiyun 	rk_hash_config hash_cfg;
146*4882a593Smuzhiyun 	uint32_t algo, key_len;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	test_get_rng(buffer->vaddr, buffer->size);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	memset(hash_soft, 0x00, sizeof(hash_soft));
151*4882a593Smuzhiyun 	memset(hash_hard, 0x00, sizeof(hash_hard));
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	algo    = item->algo;
154*4882a593Smuzhiyun 	key_len = item->blocksize;
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	memset(&hash_cfg, 0x00, sizeof(hash_cfg));
157*4882a593Smuzhiyun 	hash_cfg.algo = algo;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (is_hmac) {
160*4882a593Smuzhiyun 		test_get_rng(key, key_len);
161*4882a593Smuzhiyun 		hash_cfg.key     = key;
162*4882a593Smuzhiyun 		hash_cfg.key_len = key_len;
163*4882a593Smuzhiyun 		test_name = "hmac";
164*4882a593Smuzhiyun 	}
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	res = rk_hash_init(&hash_cfg, &hash_hdl);
167*4882a593Smuzhiyun 	if (res) {
168*4882a593Smuzhiyun 		if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
169*4882a593Smuzhiyun 			E_TRACE("rk_hash_init error[%x]\n", res);
170*4882a593Smuzhiyun 			goto exit;
171*4882a593Smuzhiyun 		}
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 		if (verbose)
174*4882a593Smuzhiyun 			printf("dma_fd:\t[%12s]\tN/A\n", test_algo_name(algo));
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 		return RK_CRYPTO_SUCCESS;
177*4882a593Smuzhiyun 	}
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	res = rk_hash_update(hash_hdl, buffer->dma_fd, buffer->size);
180*4882a593Smuzhiyun 	if (res) {
181*4882a593Smuzhiyun 		rk_hash_final(hash_hdl, NULL);
182*4882a593Smuzhiyun 		E_TRACE("rk_hash_update error = %d\n", res);
183*4882a593Smuzhiyun 		goto exit;
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	rk_hash_final(hash_hdl, hash_hard);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	if (is_hmac)
189*4882a593Smuzhiyun 		res = soft_hmac(algo, key, key_len, buffer->vaddr, buffer->size,
190*4882a593Smuzhiyun 				hash_soft, &out_len);
191*4882a593Smuzhiyun 	else
192*4882a593Smuzhiyun 		res = soft_hash(algo, buffer->vaddr, buffer->size, hash_soft, &out_len);
193*4882a593Smuzhiyun 	if (res) {
194*4882a593Smuzhiyun 		E_TRACE("soft_%s error[%x]\n", test_name, res);
195*4882a593Smuzhiyun 		goto exit;
196*4882a593Smuzhiyun 	}
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	/* Verify the result */
199*4882a593Smuzhiyun 	if (memcmp(hash_hard, hash_soft, out_len) != 0) {
200*4882a593Smuzhiyun 		E_TRACE("test_%s_item_fd compare failed.\n", test_name);
201*4882a593Smuzhiyun 		test_dump_hex("buffer", buffer->vaddr, buffer->size);
202*4882a593Smuzhiyun 		test_dump_hex("hash_hard", hash_hard, out_len);
203*4882a593Smuzhiyun 		test_dump_hex("hash_soft", hash_soft, out_len);
204*4882a593Smuzhiyun 		res = RK_CRYPTO_ERR_GENERIC;
205*4882a593Smuzhiyun 		goto exit;
206*4882a593Smuzhiyun 	}
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	hash_hdl = 0;
210*4882a593Smuzhiyun 	if (verbose)
211*4882a593Smuzhiyun 		printf("dma_fd:\t[%12s]\tPASS\n", test_algo_name(algo));
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	res = RK_CRYPTO_SUCCESS;
214*4882a593Smuzhiyun exit:
215*4882a593Smuzhiyun 	if (res)
216*4882a593Smuzhiyun 		printf("dma_fd:\t[%12s]\tFAIL\n", test_algo_name(algo));
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	return res;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
test_hash(int verbose)221*4882a593Smuzhiyun RK_RES test_hash(int verbose)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
224*4882a593Smuzhiyun 	uint8_t *buffer = NULL;
225*4882a593Smuzhiyun 	uint32_t buffer_len = TEST_DATA_MAX;
226*4882a593Smuzhiyun 	rk_crypto_mem *mem_buf = NULL;
227*4882a593Smuzhiyun 	uint32_t i;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	res = rk_crypto_init();
230*4882a593Smuzhiyun 	if (res) {
231*4882a593Smuzhiyun 		printf("rk_crypto_init error %08x\n", res);
232*4882a593Smuzhiyun 		return res;
233*4882a593Smuzhiyun 	}
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	buffer = malloc(buffer_len);
236*4882a593Smuzhiyun 	if (!buffer) {
237*4882a593Smuzhiyun 		E_TRACE("test hash malloc buffer %uByte error!\n", buffer_len);
238*4882a593Smuzhiyun 		goto exit;
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	mem_buf = rk_crypto_mem_alloc(buffer_len);
242*4882a593Smuzhiyun 	if (!mem_buf) {
243*4882a593Smuzhiyun 		E_TRACE("test hash rk_crypto_mem_alloc %uByte error!\n", buffer_len);
244*4882a593Smuzhiyun 		goto exit;
245*4882a593Smuzhiyun 	}
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(test_hash_tbl); i++) {
248*4882a593Smuzhiyun 		res = test_hash_item_virt(&test_hash_tbl[i], buffer, buffer_len, false, verbose);
249*4882a593Smuzhiyun 		if (res)
250*4882a593Smuzhiyun 			goto exit;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 		res = test_hash_item_fd(&test_hash_tbl[i], mem_buf, false, verbose);
253*4882a593Smuzhiyun 		if (res)
254*4882a593Smuzhiyun 			goto exit;
255*4882a593Smuzhiyun 	}
256*4882a593Smuzhiyun exit:
257*4882a593Smuzhiyun 	rk_crypto_mem_free(mem_buf);
258*4882a593Smuzhiyun 	rk_crypto_deinit();
259*4882a593Smuzhiyun 	if (buffer)
260*4882a593Smuzhiyun 		free(buffer);
261*4882a593Smuzhiyun 	return res;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
test_hmac(int verbose)264*4882a593Smuzhiyun RK_RES test_hmac(int verbose)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
267*4882a593Smuzhiyun 	uint8_t *buffer = NULL;
268*4882a593Smuzhiyun 	uint32_t buffer_len = TEST_DATA_MAX;
269*4882a593Smuzhiyun 	rk_crypto_mem *mem_buf = NULL;
270*4882a593Smuzhiyun 	uint32_t i;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	res = rk_crypto_init();
273*4882a593Smuzhiyun 	if (res) {
274*4882a593Smuzhiyun 		printf("rk_crypto_init error %08x\n", res);
275*4882a593Smuzhiyun 		return res;
276*4882a593Smuzhiyun 	}
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	buffer = malloc(buffer_len);
279*4882a593Smuzhiyun 	if (!buffer) {
280*4882a593Smuzhiyun 		E_TRACE("test hmac malloc buffer %uByte error!\n", buffer_len);
281*4882a593Smuzhiyun 		goto exit;
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	mem_buf = rk_crypto_mem_alloc(buffer_len);
285*4882a593Smuzhiyun 	if (!mem_buf) {
286*4882a593Smuzhiyun 		E_TRACE("test hmac rk_crypto_mem_alloc %uByte error!\n", buffer_len);
287*4882a593Smuzhiyun 		goto exit;
288*4882a593Smuzhiyun 	}
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(test_hmac_tbl); i++) {
291*4882a593Smuzhiyun 		res = test_hash_item_virt(&test_hmac_tbl[i], buffer, buffer_len, true, verbose);
292*4882a593Smuzhiyun 		if (res)
293*4882a593Smuzhiyun 			goto exit;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 		res = test_hash_item_fd(&test_hmac_tbl[i], mem_buf, true, verbose);
296*4882a593Smuzhiyun 		if (res)
297*4882a593Smuzhiyun 			goto exit;
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun exit:
300*4882a593Smuzhiyun 	rk_crypto_mem_free(mem_buf);
301*4882a593Smuzhiyun 	rk_crypto_deinit();
302*4882a593Smuzhiyun 	if (buffer)
303*4882a593Smuzhiyun 		free(buffer);
304*4882a593Smuzhiyun 	return res;
305*4882a593Smuzhiyun }
306