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