xref: /rk3399_rockchip-uboot/cmd/crypto.c (revision 495c8ff485bc8cfdba6b11a32566b33b6bb0c373)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <command.h>
8 #include <crypto.h>
9 #include <dm.h>
10 #include <u-boot/md5.h>
11 #include <u-boot/sha1.h>
12 #include <u-boot/sha256.h>
13 #include <u-boot/sha512.h>
14 #include <rockchip/crypto_fix_test_data.h>
15 
16 struct hash_test_data {
17 	const char	*algo_name;
18 	const char	*mode_name;
19 	u32		algo;
20 	const u8	*data;
21 	u32		data_len;
22 	const u8	*hash;
23 	u32		hash_len;
24 	const u8	*key;
25 	u32		key_len;
26 };
27 
28 struct cipher_test_data {
29 	const char	*algo_name;
30 	const char	*mode_name;
31 	u32		algo;
32 	u32		mode;
33 	const u8	*key;
34 	const u8	*twk_key;
35 	u32		key_len;
36 	const u8	*iv;
37 	u32		iv_len;
38 	const u8	*plain;
39 	u32		plain_len;
40 	const u8	*cipher;
41 	u32		cipher_len;
42 };
43 
44 struct rsa_test_data {
45 	const char	*algo_name;
46 	const char	*mode_name;
47 	u32		algo;
48 	const u8	*n;
49 	u32		n_len;
50 	const u8	*e;
51 	u32		e_len;
52 	const u8	*d;
53 	u32		d_len;
54 	const u8	*c;
55 	u32		c_len;
56 	const u8	*sign_in;
57 	u32		sign_in_len;
58 	const u8	*sign_out;
59 	u32		sign_out_len;
60 };
61 
62 #define HASH_TEST(algo_type, data_in, hash_val) {\
63 	.algo_name = "HASH", \
64 	.mode_name = #algo_type, \
65 	.algo      = CRYPTO_##algo_type, \
66 	.data      = (data_in),\
67 	.data_len  = sizeof(data_in), \
68 	.hash      = (hash_val), \
69 	.hash_len  = sizeof(hash_val) \
70 }
71 
72 #define HMAC_TEST(algo_type, data_in, hash_val, hmac_key) {\
73 	.algo_name = "HMAC", \
74 	.mode_name = #algo_type, \
75 	.algo      = CRYPTO_HMAC_##algo_type, \
76 	.data      = (data_in),\
77 	.data_len  = sizeof(data_in), \
78 	.hash      = (hash_val), \
79 	.hash_len  = sizeof(hash_val), \
80 	.key       = (hmac_key), \
81 	.key_len   = sizeof(hmac_key)\
82 }
83 
84 #define CIPHER_XTS_TEST(algo_type, mode_type, key1, key2, iv_val, in, out) { \
85 	.algo_name  = #algo_type, \
86 	.mode_name  = #mode_type, \
87 	.algo       = CRYPTO_##algo_type,\
88 	.mode       = RK_MODE_##mode_type, \
89 	.key        = (key1), \
90 	.twk_key    = (key2), \
91 	.key_len    = sizeof(key1), \
92 	.iv         = (iv_val), \
93 	.iv_len     = sizeof(iv_val), \
94 	.plain      = (in), \
95 	.plain_len  = sizeof(in), \
96 	.cipher     = (out), \
97 	.cipher_len = sizeof(out) \
98 }
99 
100 #define CIPHER_TEST(algo, mode, key, iv, plain, cipher) \
101 		CIPHER_XTS_TEST(algo, mode, key, NULL, iv, plain, cipher)
102 
103 #define RSA_TEST(nbits, bn, be, bc, bd, in, out) { \
104 	.algo_name    = "RSA", \
105 	.mode_name    = #nbits, \
106 	.algo         = CRYPTO_RSA##nbits, \
107 	.n            = (bn), \
108 	.n_len        = sizeof(bn), \
109 	.e            = (be), \
110 	.e_len        = sizeof(be), \
111 	.d            = (bd), \
112 	.d_len        = sizeof(bd), \
113 	.c            = (bc), \
114 	.c_len        = sizeof(bc), \
115 	.sign_in      = (in), \
116 	.sign_in_len  = sizeof(in), \
117 	.sign_out     = (out), \
118 	.sign_out_len = sizeof(out) \
119 }
120 
121 #define EMPTY_TEST() {}
122 
123 const struct hash_test_data hash_data_set[] = {
124 	HASH_TEST(MD5,    foo_data, hash_md5),
125 	HASH_TEST(SHA1,   foo_data, hash_sha1),
126 	HASH_TEST(SHA256, foo_data, hash_sha256),
127 	HASH_TEST(SHA512, foo_data, hash_sha512),
128 	HASH_TEST(SM3,    foo_data, hash_sm3),
129 
130 #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC)
131 	EMPTY_TEST(),
132 	HMAC_TEST(MD5,    foo_data, hmac_md5,    hmac_key),
133 	HMAC_TEST(SHA1,   foo_data, hmac_sha1,   hmac_key),
134 	HMAC_TEST(SHA256, foo_data, hmac_sha256, hmac_key),
135 	HMAC_TEST(SHA512, foo_data, hmac_sha512, hmac_key),
136 	HMAC_TEST(SM3,    foo_data, hmac_sm3,    hmac_key),
137 #endif
138 };
139 
140 const struct cipher_test_data cipher_data_set[] = {
141 #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)
142 	CIPHER_TEST(DES, ECB, des_key, des_iv, foo_data, des_ecb_cipher),
143 	CIPHER_TEST(DES, CBC, des_key, des_iv, foo_data, des_cbc_cipher),
144 	CIPHER_TEST(DES, CFB, des_key, des_iv, foo_data, des_cfb_cipher),
145 	CIPHER_TEST(DES, OFB, des_key, des_iv, foo_data, des_ofb_cipher),
146 
147 	EMPTY_TEST(),
148 	CIPHER_TEST(DES, ECB, tdes_key, tdes_iv, foo_data, tdes_ecb_cipher),
149 	CIPHER_TEST(DES, CBC, tdes_key, tdes_iv, foo_data, tdes_cbc_cipher),
150 	CIPHER_TEST(DES, CFB, tdes_key, tdes_iv, foo_data, tdes_cfb_cipher),
151 	CIPHER_TEST(DES, OFB, tdes_key, tdes_iv, foo_data, tdes_ofb_cipher),
152 
153 	EMPTY_TEST(),
154 	CIPHER_TEST(AES, ECB, aes_key, aes_iv, foo_data, aes_ecb_cipher),
155 	CIPHER_TEST(AES, CBC, aes_key, aes_iv, foo_data, aes_cbc_cipher),
156 	CIPHER_TEST(AES, CFB, aes_key, aes_iv, foo_data, aes_cfb_cipher),
157 	CIPHER_TEST(AES, OFB, aes_key, aes_iv, foo_data, aes_ofb_cipher),
158 	CIPHER_TEST(AES, CTS, aes_key, aes_iv, foo_data, aes_cts_cipher),
159 	CIPHER_TEST(AES, CTR, aes_key, aes_iv, foo_data, aes_ctr_cipher),
160 	CIPHER_XTS_TEST(AES, XTS, aes_key, aes_twk_key,
161 			aes_iv, foo_data, aes_xts_cipher),
162 
163 	EMPTY_TEST(),
164 	CIPHER_TEST(SM4, ECB, sm4_key, sm4_iv, foo_data, sm4_ecb_cipher),
165 	CIPHER_TEST(SM4, CBC, sm4_key, sm4_iv, foo_data, sm4_cbc_cipher),
166 	CIPHER_TEST(SM4, CFB, sm4_key, sm4_iv, foo_data, sm4_cfb_cipher),
167 	CIPHER_TEST(SM4, OFB, sm4_key, sm4_iv, foo_data, sm4_ofb_cipher),
168 	CIPHER_TEST(SM4, CTS, sm4_key, sm4_iv, foo_data, sm4_cts_cipher),
169 	CIPHER_TEST(SM4, CTR, sm4_key, sm4_iv, foo_data, sm4_ctr_cipher),
170 	CIPHER_XTS_TEST(SM4, XTS, sm4_key, sm4_twk_key,
171 			sm4_iv, foo_data, sm4_xts_cipher),
172 #else
173 	EMPTY_TEST(),
174 #endif
175 };
176 
177 const struct rsa_test_data rsa_data_set[] = {
178 #if CONFIG_IS_ENABLED(ROCKCHIP_RSA)
179 	RSA_TEST(2048, rsa2048_n, rsa2048_e, rsa2048_c, rsa2048_d,
180 		 rsa2048_sign_in, rsa2048_sign_out),
181 #else
182 	EMPTY_TEST(),
183 #endif
184 };
185 
186 static void dump_hex(const char *name, const u8 *array, u32 len)
187 {
188 	int i;
189 
190 	printf("[%s]: %uByte", name, len);
191 	for (i = 0; i < len; i++) {
192 		if (i % 32 == 0)
193 			printf("\n");
194 		printf("%02x ", array[i]);
195 	}
196 	printf("\n");
197 }
198 
199 static inline void check_result(const char *algo_name, const char *mode_name,
200 				const char *crypt,
201 				const u8 *expect, const u8 *actual, u32 len)
202 {
203 	if (memcmp(expect, actual, len) == 0) {
204 		printf("[%s] %-8s%-8s PASS\n",
205 		       algo_name, mode_name, crypt);
206 	} else {
207 		printf("[%s] %-8s%-8s FAIL\n",
208 		       algo_name, mode_name, crypt);
209 		dump_hex("expect", expect, len);
210 		dump_hex("actual", actual, len);
211 	}
212 }
213 
214 int test_hash_result(void)
215 {
216 	const struct hash_test_data *test_data = NULL;
217 	sha_context csha_ctx;
218 	struct udevice *dev;
219 	unsigned int i;
220 	u8 out[64];
221 	int ret;
222 
223 	printf("\n=================== hash & hmac test ===================\n");
224 
225 	for (i = 0; i < ARRAY_SIZE(hash_data_set); i++) {
226 		test_data = &hash_data_set[i];
227 		if (test_data->algo == 0) {
228 			printf("\n");
229 			continue;
230 		}
231 
232 		dev = crypto_get_device(test_data->algo);
233 		if (!dev) {
234 			printf("[%s] %-16s unsupported!!!\n",
235 			       test_data->algo_name,
236 			       test_data->mode_name);
237 			continue;
238 		}
239 
240 		csha_ctx.algo   = test_data->algo;
241 		csha_ctx.length = test_data->data_len;
242 
243 		memset(out, 0x00, sizeof(out));
244 		if (test_data->key) {
245 			ret = crypto_hmac_init(dev, &csha_ctx,
246 					       (u8 *)test_data->key,
247 					       test_data->key_len);
248 			ret |= crypto_hmac_update(dev, (void *)test_data->data,
249 						  test_data->data_len);
250 			ret |= crypto_hmac_final(dev, &csha_ctx, out);
251 			if (ret) {
252 				printf("hmac calc error ret = %d\n", ret);
253 				goto error;
254 			}
255 		} else {
256 			ret = crypto_sha_init(dev, &csha_ctx);
257 			ret |= crypto_sha_update(dev, (void *)test_data->data,
258 						 test_data->data_len);
259 			ret |= crypto_sha_final(dev, &csha_ctx, out);
260 			if (ret) {
261 				printf("hash calc error ret = %d\n", ret);
262 				goto error;
263 			}
264 		}
265 
266 		check_result(test_data->algo_name, test_data->mode_name,
267 			     "", test_data->hash, out, test_data->hash_len);
268 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
269 	}
270 
271 	return 0;
272 error:
273 	printf("%s %s test error!\n",
274 	       test_data->algo_name, test_data->mode_name);
275 	return ret;
276 }
277 
278 int test_cipher_result(void)
279 {
280 	const struct cipher_test_data *test_data = NULL;
281 	struct udevice *dev;
282 	cipher_context ctx;
283 	u8 out[256];
284 	int ret;
285 	u32 i;
286 
287 	printf("\n===================== cipher test ======================\n");
288 
289 	for (i = 0; i < ARRAY_SIZE(cipher_data_set); i++) {
290 		test_data = &cipher_data_set[i];
291 		if (test_data->algo == 0) {
292 			printf("\n");
293 			continue;
294 		}
295 
296 		dev = crypto_get_device(test_data->algo);
297 		if (!dev) {
298 			printf("[%s] %-16s unsupported!!!\n",
299 			       test_data->algo_name, test_data->mode_name);
300 			continue;
301 		}
302 
303 		memset(&ctx, 0x00, sizeof(ctx));
304 
305 		ctx.algo    = test_data->algo;
306 		ctx.mode    = test_data->mode;
307 		ctx.key     = test_data->key;
308 		ctx.twk_key = test_data->twk_key;
309 		ctx.key_len = test_data->key_len;
310 		ctx.iv      = test_data->iv;
311 		ctx.iv_len  = test_data->iv_len;
312 
313 		ret = crypto_cipher(dev, &ctx, test_data->plain,
314 				    out, test_data->plain_len, true);
315 		if (ret)
316 			goto error;
317 
318 		check_result(test_data->algo_name, test_data->mode_name,
319 			     "encrypt", test_data->cipher, out,
320 			     test_data->cipher_len);
321 
322 		ret = crypto_cipher(dev, &ctx, test_data->cipher,
323 				    out, test_data->cipher_len, false);
324 		if (ret)
325 			goto error;
326 
327 		check_result(test_data->algo_name, test_data->mode_name,
328 			     "decrypt", test_data->plain, out,
329 			     test_data->plain_len);
330 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
331 	}
332 	return 0;
333 error:
334 	printf("%s %s test error!\n",
335 	       test_data->algo_name, test_data->mode_name);
336 	return ret;
337 }
338 
339 int test_rsa_result(void)
340 {
341 	const struct rsa_test_data *test_data = NULL;
342 	u8 *hard_out = NULL, *e_tmp;
343 	u32 data_size = 4096 / 8;
344 	struct udevice *dev;
345 	rsa_key rsa_key;
346 	int ret, i;
347 
348 	hard_out = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
349 	if (!hard_out) {
350 		printf("%s, %d: memalign %u error!\n",
351 		       __func__, __LINE__, data_size);
352 		return -EINVAL;
353 	}
354 
355 	e_tmp = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
356 	if (!e_tmp) {
357 		printf("%s, %d: memalign %u error!\n",
358 		       __func__, __LINE__, data_size);
359 		return -EINVAL;
360 	}
361 
362 	printf("\n====================== rsa test ========================\n");
363 	for (i = 0; i < ARRAY_SIZE(rsa_data_set); i++) {
364 		test_data = &rsa_data_set[i];
365 		if (test_data->algo == 0) {
366 			printf("\n");
367 			continue;
368 		}
369 
370 		dev = crypto_get_device(test_data->algo);
371 		if (!dev) {
372 			printf("[%s] %-16s unsupported!!!\n",
373 			       test_data->algo_name, test_data->mode_name);
374 			continue;
375 		}
376 
377 		/* sign test */
378 		memset(&rsa_key, 0x00, sizeof(rsa_key));
379 		rsa_key.algo = test_data->algo;
380 		rsa_key.n = (u32 *)test_data->n;
381 		rsa_key.e = (u32 *)test_data->d;
382 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
383 		rsa_key.c = (u32 *)test_data->c;
384 #endif
385 
386 		ret = crypto_rsa_verify(dev, &rsa_key,
387 					(u8 *)test_data->sign_in, hard_out);
388 		if (ret) {
389 			printf("sign test error, ret = %d\n", ret);
390 			goto error;
391 		}
392 
393 		check_result(test_data->algo_name, test_data->mode_name,
394 			     "sign", test_data->sign_out,
395 			     hard_out, test_data->n_len);
396 
397 		/* verify test */
398 		memset(&rsa_key, 0x00, sizeof(rsa_key));
399 		memset(e_tmp, 0x00, data_size);
400 		memcpy(e_tmp, test_data->e, test_data->e_len);
401 		rsa_key.algo = test_data->algo;
402 		rsa_key.n = (u32 *)test_data->n;
403 		rsa_key.e = (u32 *)e_tmp;
404 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
405 		rsa_key.c = (u32 *)test_data->c;
406 #endif
407 
408 		ret = crypto_rsa_verify(dev, &rsa_key,
409 					(u8 *)test_data->sign_out, hard_out);
410 		if (ret) {
411 			printf("verify test error, ret = %d\n", ret);
412 			goto error;
413 		}
414 
415 		check_result(test_data->algo_name, test_data->mode_name,
416 			     "verify", test_data->sign_in,
417 			     hard_out, test_data->n_len);
418 
419 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
420 	}
421 
422 	free(hard_out);
423 	free(e_tmp);
424 
425 	return 0;
426 error:
427 	free(hard_out);
428 	free(e_tmp);
429 	printf("%s %s test error!\n",
430 	       test_data->algo_name, test_data->mode_name);
431 	return ret;
432 }
433 
434 static int test_all_result(void)
435 {
436 	int ret = 0;
437 
438 	ret = test_hash_result();
439 	if (ret)
440 		goto exit;
441 
442 	ret = test_cipher_result();
443 	if (ret)
444 		goto exit;
445 
446 	ret = test_rsa_result();
447 	if (ret)
448 		goto exit;
449 
450 exit:
451 	return 0;
452 }
453 
454 static int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
455 {
456 	return test_all_result();
457 }
458 
459 U_BOOT_CMD(
460 	crypto, 1, 1, do_crypto,
461 	"crypto test",
462 	""
463 );
464