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