xref: /rk3399_rockchip-uboot/cmd/crypto.c (revision 65ac8e46b20981899f99004644294a40485a7ee3)
1cc6ac5d6SJoseph Chen // SPDX-License-Identifier: GPL-2.0
2cc6ac5d6SJoseph Chen /*
3cc6ac5d6SJoseph Chen  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4cc6ac5d6SJoseph Chen  */
5cc6ac5d6SJoseph Chen 
6cc6ac5d6SJoseph Chen #include <common.h>
7cc6ac5d6SJoseph Chen #include <command.h>
8cc6ac5d6SJoseph Chen #include <crypto.h>
9cc6ac5d6SJoseph Chen #include <dm.h>
10cc6ac5d6SJoseph Chen #include <u-boot/md5.h>
11cc6ac5d6SJoseph Chen #include <u-boot/sha1.h>
12cc6ac5d6SJoseph Chen #include <u-boot/sha256.h>
13e7b6c6a9SLin Jinhan #include <u-boot/sha512.h>
14495c8ff4SLin Jinhan #include <rockchip/crypto_fix_test_data.h>
15cc6ac5d6SJoseph Chen 
16415ed02bSLin Jinhan #define PERF_TOTAL_SIZE			(128 * 1024 * 1024)
17415ed02bSLin Jinhan #define PERF_BUFF_SIZE			(4 * 1024 * 1024)
18415ed02bSLin Jinhan 
19415ed02bSLin Jinhan #define CALC_RATE_MPBS(bytes, ms)	(((bytes) / 1024) / (ms))
20415ed02bSLin Jinhan 
21495c8ff4SLin Jinhan struct hash_test_data {
22495c8ff4SLin Jinhan 	const char	*algo_name;
23495c8ff4SLin Jinhan 	const char	*mode_name;
24495c8ff4SLin Jinhan 	u32		algo;
25495c8ff4SLin Jinhan 	const u8	*data;
26495c8ff4SLin Jinhan 	u32		data_len;
27495c8ff4SLin Jinhan 	const u8	*hash;
28495c8ff4SLin Jinhan 	u32		hash_len;
29495c8ff4SLin Jinhan 	const u8	*key;
30495c8ff4SLin Jinhan 	u32		key_len;
31cc6ac5d6SJoseph Chen };
32cc6ac5d6SJoseph Chen 
33495c8ff4SLin Jinhan struct cipher_test_data {
34495c8ff4SLin Jinhan 	const char	*algo_name;
35495c8ff4SLin Jinhan 	const char	*mode_name;
36495c8ff4SLin Jinhan 	u32		algo;
37495c8ff4SLin Jinhan 	u32		mode;
38495c8ff4SLin Jinhan 	const u8	*key;
39495c8ff4SLin Jinhan 	const u8	*twk_key;
40495c8ff4SLin Jinhan 	u32		key_len;
41495c8ff4SLin Jinhan 	const u8	*iv;
42495c8ff4SLin Jinhan 	u32		iv_len;
43495c8ff4SLin Jinhan 	const u8	*plain;
44495c8ff4SLin Jinhan 	u32		plain_len;
45495c8ff4SLin Jinhan 	const u8	*cipher;
46495c8ff4SLin Jinhan 	u32		cipher_len;
47cc6ac5d6SJoseph Chen };
48cc6ac5d6SJoseph Chen 
49495c8ff4SLin Jinhan struct rsa_test_data {
50495c8ff4SLin Jinhan 	const char	*algo_name;
51495c8ff4SLin Jinhan 	const char	*mode_name;
52495c8ff4SLin Jinhan 	u32		algo;
53495c8ff4SLin Jinhan 	const u8	*n;
54495c8ff4SLin Jinhan 	u32		n_len;
55495c8ff4SLin Jinhan 	const u8	*e;
56495c8ff4SLin Jinhan 	u32		e_len;
57495c8ff4SLin Jinhan 	const u8	*d;
58495c8ff4SLin Jinhan 	u32		d_len;
59495c8ff4SLin Jinhan 	const u8	*c;
60495c8ff4SLin Jinhan 	u32		c_len;
61495c8ff4SLin Jinhan 	const u8	*sign_in;
62495c8ff4SLin Jinhan 	u32		sign_in_len;
63495c8ff4SLin Jinhan 	const u8	*sign_out;
64495c8ff4SLin Jinhan 	u32		sign_out_len;
65cc6ac5d6SJoseph Chen };
66cc6ac5d6SJoseph Chen 
67*65ac8e46SLin Jinhan #define IS_MAC_MODE(mode)	((mode) == RK_MODE_CBC_MAC || \
68*65ac8e46SLin Jinhan 				 (mode) == RK_MODE_CMAC)
69*65ac8e46SLin Jinhan 
70495c8ff4SLin Jinhan #define HASH_TEST(algo_type, data_in, hash_val) {\
71495c8ff4SLin Jinhan 	.algo_name = "HASH", \
72495c8ff4SLin Jinhan 	.mode_name = #algo_type, \
73495c8ff4SLin Jinhan 	.algo      = CRYPTO_##algo_type, \
74495c8ff4SLin Jinhan 	.data      = (data_in),\
75495c8ff4SLin Jinhan 	.data_len  = sizeof(data_in), \
76495c8ff4SLin Jinhan 	.hash      = (hash_val), \
77495c8ff4SLin Jinhan 	.hash_len  = sizeof(hash_val) \
78cc6ac5d6SJoseph Chen }
79cc6ac5d6SJoseph Chen 
80495c8ff4SLin Jinhan #define HMAC_TEST(algo_type, data_in, hash_val, hmac_key) {\
81495c8ff4SLin Jinhan 	.algo_name = "HMAC", \
82495c8ff4SLin Jinhan 	.mode_name = #algo_type, \
83495c8ff4SLin Jinhan 	.algo      = CRYPTO_HMAC_##algo_type, \
84495c8ff4SLin Jinhan 	.data      = (data_in),\
85495c8ff4SLin Jinhan 	.data_len  = sizeof(data_in), \
86495c8ff4SLin Jinhan 	.hash      = (hash_val), \
87495c8ff4SLin Jinhan 	.hash_len  = sizeof(hash_val), \
88495c8ff4SLin Jinhan 	.key       = (hmac_key), \
89495c8ff4SLin Jinhan 	.key_len   = sizeof(hmac_key)\
90495c8ff4SLin Jinhan }
91495c8ff4SLin Jinhan 
92495c8ff4SLin Jinhan #define CIPHER_XTS_TEST(algo_type, mode_type, key1, key2, iv_val, in, out) { \
93495c8ff4SLin Jinhan 	.algo_name  = #algo_type, \
94495c8ff4SLin Jinhan 	.mode_name  = #mode_type, \
95495c8ff4SLin Jinhan 	.algo       = CRYPTO_##algo_type,\
96495c8ff4SLin Jinhan 	.mode       = RK_MODE_##mode_type, \
97495c8ff4SLin Jinhan 	.key        = (key1), \
98495c8ff4SLin Jinhan 	.twk_key    = (key2), \
99495c8ff4SLin Jinhan 	.key_len    = sizeof(key1), \
100495c8ff4SLin Jinhan 	.iv         = (iv_val), \
101495c8ff4SLin Jinhan 	.iv_len     = sizeof(iv_val), \
102495c8ff4SLin Jinhan 	.plain      = (in), \
103495c8ff4SLin Jinhan 	.plain_len  = sizeof(in), \
104495c8ff4SLin Jinhan 	.cipher     = (out), \
105495c8ff4SLin Jinhan 	.cipher_len = sizeof(out) \
106495c8ff4SLin Jinhan }
107495c8ff4SLin Jinhan 
108495c8ff4SLin Jinhan #define CIPHER_TEST(algo, mode, key, iv, plain, cipher) \
109495c8ff4SLin Jinhan 		CIPHER_XTS_TEST(algo, mode, key, NULL, iv, plain, cipher)
110495c8ff4SLin Jinhan 
111495c8ff4SLin Jinhan #define RSA_TEST(nbits, bn, be, bc, bd, in, out) { \
112495c8ff4SLin Jinhan 	.algo_name    = "RSA", \
113495c8ff4SLin Jinhan 	.mode_name    = #nbits, \
114495c8ff4SLin Jinhan 	.algo         = CRYPTO_RSA##nbits, \
115495c8ff4SLin Jinhan 	.n            = (bn), \
116495c8ff4SLin Jinhan 	.n_len        = sizeof(bn), \
117495c8ff4SLin Jinhan 	.e            = (be), \
118495c8ff4SLin Jinhan 	.e_len        = sizeof(be), \
119495c8ff4SLin Jinhan 	.d            = (bd), \
120495c8ff4SLin Jinhan 	.d_len        = sizeof(bd), \
121495c8ff4SLin Jinhan 	.c            = (bc), \
122495c8ff4SLin Jinhan 	.c_len        = sizeof(bc), \
123495c8ff4SLin Jinhan 	.sign_in      = (in), \
124495c8ff4SLin Jinhan 	.sign_in_len  = sizeof(in), \
125495c8ff4SLin Jinhan 	.sign_out     = (out), \
126495c8ff4SLin Jinhan 	.sign_out_len = sizeof(out) \
127495c8ff4SLin Jinhan }
128495c8ff4SLin Jinhan 
129495c8ff4SLin Jinhan #define EMPTY_TEST() {}
130495c8ff4SLin Jinhan 
131495c8ff4SLin Jinhan const struct hash_test_data hash_data_set[] = {
132495c8ff4SLin Jinhan 	HASH_TEST(MD5,    foo_data, hash_md5),
133495c8ff4SLin Jinhan 	HASH_TEST(SHA1,   foo_data, hash_sha1),
134495c8ff4SLin Jinhan 	HASH_TEST(SHA256, foo_data, hash_sha256),
135495c8ff4SLin Jinhan 	HASH_TEST(SHA512, foo_data, hash_sha512),
136495c8ff4SLin Jinhan 	HASH_TEST(SM3,    foo_data, hash_sm3),
137495c8ff4SLin Jinhan 
138495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC)
139495c8ff4SLin Jinhan 	EMPTY_TEST(),
140495c8ff4SLin Jinhan 	HMAC_TEST(MD5,    foo_data, hmac_md5,    hmac_key),
141495c8ff4SLin Jinhan 	HMAC_TEST(SHA1,   foo_data, hmac_sha1,   hmac_key),
142495c8ff4SLin Jinhan 	HMAC_TEST(SHA256, foo_data, hmac_sha256, hmac_key),
143495c8ff4SLin Jinhan 	HMAC_TEST(SHA512, foo_data, hmac_sha512, hmac_key),
144495c8ff4SLin Jinhan 	HMAC_TEST(SM3,    foo_data, hmac_sm3,    hmac_key),
145495c8ff4SLin Jinhan #endif
146495c8ff4SLin Jinhan };
147495c8ff4SLin Jinhan 
148495c8ff4SLin Jinhan const struct cipher_test_data cipher_data_set[] = {
149495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)
150495c8ff4SLin Jinhan 	CIPHER_TEST(DES, ECB, des_key, des_iv, foo_data, des_ecb_cipher),
151495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CBC, des_key, des_iv, foo_data, des_cbc_cipher),
152495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CFB, des_key, des_iv, foo_data, des_cfb_cipher),
153495c8ff4SLin Jinhan 	CIPHER_TEST(DES, OFB, des_key, des_iv, foo_data, des_ofb_cipher),
154495c8ff4SLin Jinhan 
155495c8ff4SLin Jinhan 	EMPTY_TEST(),
156495c8ff4SLin Jinhan 	CIPHER_TEST(DES, ECB, tdes_key, tdes_iv, foo_data, tdes_ecb_cipher),
157495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CBC, tdes_key, tdes_iv, foo_data, tdes_cbc_cipher),
158495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CFB, tdes_key, tdes_iv, foo_data, tdes_cfb_cipher),
159495c8ff4SLin Jinhan 	CIPHER_TEST(DES, OFB, tdes_key, tdes_iv, foo_data, tdes_ofb_cipher),
160495c8ff4SLin Jinhan 
161495c8ff4SLin Jinhan 	EMPTY_TEST(),
162495c8ff4SLin Jinhan 	CIPHER_TEST(AES, ECB, aes_key, aes_iv, foo_data, aes_ecb_cipher),
163495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CBC, aes_key, aes_iv, foo_data, aes_cbc_cipher),
164495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CFB, aes_key, aes_iv, foo_data, aes_cfb_cipher),
165495c8ff4SLin Jinhan 	CIPHER_TEST(AES, OFB, aes_key, aes_iv, foo_data, aes_ofb_cipher),
166495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CTS, aes_key, aes_iv, foo_data, aes_cts_cipher),
167495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CTR, aes_key, aes_iv, foo_data, aes_ctr_cipher),
168495c8ff4SLin Jinhan 	CIPHER_XTS_TEST(AES, XTS, aes_key, aes_twk_key,
169495c8ff4SLin Jinhan 			aes_iv, foo_data, aes_xts_cipher),
170*65ac8e46SLin Jinhan 	CIPHER_TEST(AES, CBC_MAC, aes_key, aes_iv, foo_data, aes_cbc_mac),
171*65ac8e46SLin Jinhan 	CIPHER_TEST(AES, CMAC, aes_key, aes_iv, foo_data, aes_cmac),
172495c8ff4SLin Jinhan 
173495c8ff4SLin Jinhan 	EMPTY_TEST(),
174495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, ECB, sm4_key, sm4_iv, foo_data, sm4_ecb_cipher),
175495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CBC, sm4_key, sm4_iv, foo_data, sm4_cbc_cipher),
176495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CFB, sm4_key, sm4_iv, foo_data, sm4_cfb_cipher),
177495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, OFB, sm4_key, sm4_iv, foo_data, sm4_ofb_cipher),
178495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CTS, sm4_key, sm4_iv, foo_data, sm4_cts_cipher),
179495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CTR, sm4_key, sm4_iv, foo_data, sm4_ctr_cipher),
180495c8ff4SLin Jinhan 	CIPHER_XTS_TEST(SM4, XTS, sm4_key, sm4_twk_key,
181495c8ff4SLin Jinhan 			sm4_iv, foo_data, sm4_xts_cipher),
182*65ac8e46SLin Jinhan 	CIPHER_TEST(SM4, CBC_MAC, sm4_key, sm4_iv, foo_data, sm4_cbc_mac),
183*65ac8e46SLin Jinhan 	CIPHER_TEST(SM4, CMAC, sm4_key, sm4_iv, foo_data, sm4_cmac),
184495c8ff4SLin Jinhan #else
185495c8ff4SLin Jinhan 	EMPTY_TEST(),
186495c8ff4SLin Jinhan #endif
187495c8ff4SLin Jinhan };
188495c8ff4SLin Jinhan 
189495c8ff4SLin Jinhan const struct rsa_test_data rsa_data_set[] = {
190495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA)
191415ed02bSLin Jinhan 
192415ed02bSLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
193495c8ff4SLin Jinhan 	RSA_TEST(2048, rsa2048_n, rsa2048_e, rsa2048_c, rsa2048_d,
194495c8ff4SLin Jinhan 		 rsa2048_sign_in, rsa2048_sign_out),
195495c8ff4SLin Jinhan #else
196415ed02bSLin Jinhan 	RSA_TEST(4096, rsa4096_n, rsa4096_e, NULL, rsa4096_d,
197415ed02bSLin Jinhan 		 rsa4096_sign_in, rsa4096_sign_out),
198415ed02bSLin Jinhan #endif
199415ed02bSLin Jinhan 
200415ed02bSLin Jinhan #else
201495c8ff4SLin Jinhan 	EMPTY_TEST(),
202495c8ff4SLin Jinhan #endif
203495c8ff4SLin Jinhan };
204495c8ff4SLin Jinhan 
205495c8ff4SLin Jinhan static void dump_hex(const char *name, const u8 *array, u32 len)
20680ca1a53SLin Jinhan {
207495c8ff4SLin Jinhan 	int i;
208495c8ff4SLin Jinhan 
209495c8ff4SLin Jinhan 	printf("[%s]: %uByte", name, len);
210495c8ff4SLin Jinhan 	for (i = 0; i < len; i++) {
211495c8ff4SLin Jinhan 		if (i % 32 == 0)
212495c8ff4SLin Jinhan 			printf("\n");
213495c8ff4SLin Jinhan 		printf("%02x ", array[i]);
214495c8ff4SLin Jinhan 	}
215495c8ff4SLin Jinhan 	printf("\n");
216495c8ff4SLin Jinhan }
217495c8ff4SLin Jinhan 
218415ed02bSLin Jinhan static inline void print_result_MBps(const char *algo_name,
219415ed02bSLin Jinhan 				     const char *mode_name,
220415ed02bSLin Jinhan 				     const char *crypt, ulong MBps,
221415ed02bSLin Jinhan 				     const u8 *expect, const u8 *actual,
222415ed02bSLin Jinhan 				     u32 len)
223495c8ff4SLin Jinhan {
224495c8ff4SLin Jinhan 	if (memcmp(expect, actual, len) == 0) {
225415ed02bSLin Jinhan 		printf("[%s] %-8s%-8s PASS    (%luMBps)\n",
226415ed02bSLin Jinhan 		       algo_name, mode_name, crypt, MBps);
227495c8ff4SLin Jinhan 	} else {
228495c8ff4SLin Jinhan 		printf("[%s] %-8s%-8s FAIL\n",
229495c8ff4SLin Jinhan 		       algo_name, mode_name, crypt);
230495c8ff4SLin Jinhan 		dump_hex("expect", expect, len);
231495c8ff4SLin Jinhan 		dump_hex("actual", actual, len);
232495c8ff4SLin Jinhan 	}
233495c8ff4SLin Jinhan }
234495c8ff4SLin Jinhan 
235415ed02bSLin Jinhan static inline void print_result_ms(const char *algo_name, const char *mode_name,
236415ed02bSLin Jinhan 				   const char *crypt, ulong time_cost,
237415ed02bSLin Jinhan 				   const u8 *expect, const u8 *actual, u32 len)
238415ed02bSLin Jinhan {
239415ed02bSLin Jinhan 	if (memcmp(expect, actual, len) == 0) {
240415ed02bSLin Jinhan 		printf("[%s] %-8s%-8s PASS    (%lums)\n",
241415ed02bSLin Jinhan 		       algo_name, mode_name, crypt, time_cost);
242415ed02bSLin Jinhan 	} else {
243415ed02bSLin Jinhan 		printf("[%s] %-8s%-8s FAIL\n",
244415ed02bSLin Jinhan 		       algo_name, mode_name, crypt);
245415ed02bSLin Jinhan 		dump_hex("expect", expect, len);
246415ed02bSLin Jinhan 		dump_hex("actual", actual, len);
247415ed02bSLin Jinhan 	}
248415ed02bSLin Jinhan }
249415ed02bSLin Jinhan 
250415ed02bSLin Jinhan int test_hash_perf(struct udevice *dev, u32 algo,
251415ed02bSLin Jinhan 		   const u8 *key, u32 key_len, ulong *MBps)
252415ed02bSLin Jinhan {
253415ed02bSLin Jinhan 	u32 total_size = PERF_TOTAL_SIZE;
254415ed02bSLin Jinhan 	u32 data_size = PERF_BUFF_SIZE;
255415ed02bSLin Jinhan 	sha_context ctx;
256415ed02bSLin Jinhan 	u8 *data = NULL;
257415ed02bSLin Jinhan 	u8 hash_out[64];
258415ed02bSLin Jinhan 	int ret, i;
259415ed02bSLin Jinhan 
260415ed02bSLin Jinhan 	*MBps = 0;
261415ed02bSLin Jinhan 
262415ed02bSLin Jinhan 	ctx.algo = algo;
263415ed02bSLin Jinhan 	ctx.length = total_size;
264415ed02bSLin Jinhan 
265415ed02bSLin Jinhan 	data = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
266415ed02bSLin Jinhan 	if (!data) {
267415ed02bSLin Jinhan 		printf("%s, %d: memalign %u error!\n",
268415ed02bSLin Jinhan 		       __func__, __LINE__, data_size);
269415ed02bSLin Jinhan 		return -EINVAL;
270415ed02bSLin Jinhan 	}
271415ed02bSLin Jinhan 
272415ed02bSLin Jinhan 	memset(data, 0xab, data_size);
273415ed02bSLin Jinhan 
274415ed02bSLin Jinhan 	ulong start = get_timer(0);
275415ed02bSLin Jinhan 
276415ed02bSLin Jinhan 	if (key)
277415ed02bSLin Jinhan 		ret = crypto_hmac_init(dev, &ctx, (u8 *)key, key_len);
278415ed02bSLin Jinhan 	else
279415ed02bSLin Jinhan 		ret = crypto_sha_init(dev, &ctx);
280415ed02bSLin Jinhan 
281415ed02bSLin Jinhan 	if (ret) {
282415ed02bSLin Jinhan 		printf("crypto_sha_init error ret = %d!\n", ret);
283415ed02bSLin Jinhan 		goto exit;
284415ed02bSLin Jinhan 	}
285415ed02bSLin Jinhan 
286415ed02bSLin Jinhan 	for (i = 0; i < total_size / data_size; i++) {
287415ed02bSLin Jinhan 		ret = crypto_sha_update(dev, (u32 *)data, data_size);
288415ed02bSLin Jinhan 		if (ret) {
289415ed02bSLin Jinhan 			printf("crypto_sha_update error!\n");
290415ed02bSLin Jinhan 			goto exit;
291415ed02bSLin Jinhan 		}
292415ed02bSLin Jinhan 	}
293415ed02bSLin Jinhan 
294415ed02bSLin Jinhan 	ret = crypto_sha_final(dev, &ctx, hash_out);
295415ed02bSLin Jinhan 	if (ret) {
296415ed02bSLin Jinhan 		printf("crypto_sha_final error ret = %d!\n", ret);
297415ed02bSLin Jinhan 		goto exit;
298415ed02bSLin Jinhan 	}
299415ed02bSLin Jinhan 
300415ed02bSLin Jinhan 	ulong time_cost = get_timer(start);
301415ed02bSLin Jinhan 
302415ed02bSLin Jinhan 	*MBps = CALC_RATE_MPBS(total_size, time_cost);
303415ed02bSLin Jinhan 
304415ed02bSLin Jinhan exit:
305415ed02bSLin Jinhan 	free(data);
306415ed02bSLin Jinhan 
307415ed02bSLin Jinhan 	return ret;
308415ed02bSLin Jinhan }
309415ed02bSLin Jinhan 
310415ed02bSLin Jinhan int test_cipher_perf(struct udevice *dev, cipher_context *ctx,
311415ed02bSLin Jinhan 		     ulong *MBps, bool enc)
312415ed02bSLin Jinhan {
313415ed02bSLin Jinhan 	u32 total_size = PERF_TOTAL_SIZE;
314415ed02bSLin Jinhan 	u32 data_size = PERF_BUFF_SIZE;
315415ed02bSLin Jinhan 	u8 *plain = NULL, *cipher = NULL;
316*65ac8e46SLin Jinhan 	int ret = 0, i;
317415ed02bSLin Jinhan 
318415ed02bSLin Jinhan 	*MBps = 0;
319415ed02bSLin Jinhan 
320415ed02bSLin Jinhan 	plain = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
321415ed02bSLin Jinhan 	if (!plain) {
322415ed02bSLin Jinhan 		printf("%s, %d: memalign %u error!\n",
323415ed02bSLin Jinhan 		       __func__, __LINE__, data_size);
324415ed02bSLin Jinhan 		return -EINVAL;
325415ed02bSLin Jinhan 	}
326415ed02bSLin Jinhan 
327415ed02bSLin Jinhan 	cipher = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
328415ed02bSLin Jinhan 	if (!cipher) {
329415ed02bSLin Jinhan 		printf("%s, %d: memalign %u error!\n",
330415ed02bSLin Jinhan 		       __func__, __LINE__, data_size);
331415ed02bSLin Jinhan 		free(plain);
332415ed02bSLin Jinhan 		return -EINVAL;
333415ed02bSLin Jinhan 	}
334415ed02bSLin Jinhan 
335415ed02bSLin Jinhan 	memset(plain, 0xab, data_size);
336415ed02bSLin Jinhan 
337415ed02bSLin Jinhan 	ulong start = get_timer(0);
338415ed02bSLin Jinhan 
339415ed02bSLin Jinhan 	for (i = 0; i < total_size / data_size; i++) {
340*65ac8e46SLin Jinhan 		if (IS_MAC_MODE(ctx->mode))
341*65ac8e46SLin Jinhan 			ret = crypto_mac(dev, ctx, plain, data_size, cipher);
342*65ac8e46SLin Jinhan 		else
343*65ac8e46SLin Jinhan 			ret = crypto_cipher(dev, ctx, plain, cipher,
344*65ac8e46SLin Jinhan 					    data_size, enc);
345415ed02bSLin Jinhan 		if (ret) {
346*65ac8e46SLin Jinhan 			printf("%s, %d:crypto_aes error! ret = %d\n",
347*65ac8e46SLin Jinhan 			       __func__, __LINE__, ret);
348415ed02bSLin Jinhan 			goto exit;
349415ed02bSLin Jinhan 		}
350415ed02bSLin Jinhan 	}
351415ed02bSLin Jinhan 
352415ed02bSLin Jinhan 	ulong time_cost = get_timer(start);
353415ed02bSLin Jinhan 
354415ed02bSLin Jinhan 	*MBps = CALC_RATE_MPBS(total_size, time_cost);
355415ed02bSLin Jinhan exit:
356415ed02bSLin Jinhan 	free(plain);
357415ed02bSLin Jinhan 	free(cipher);
358415ed02bSLin Jinhan 
359415ed02bSLin Jinhan 	return ret;
360415ed02bSLin Jinhan }
361415ed02bSLin Jinhan 
362495c8ff4SLin Jinhan int test_hash_result(void)
363495c8ff4SLin Jinhan {
364495c8ff4SLin Jinhan 	const struct hash_test_data *test_data = NULL;
365495c8ff4SLin Jinhan 	sha_context csha_ctx;
366495c8ff4SLin Jinhan 	struct udevice *dev;
367495c8ff4SLin Jinhan 	unsigned int i;
368495c8ff4SLin Jinhan 	u8 out[64];
36980ca1a53SLin Jinhan 	int ret;
37080ca1a53SLin Jinhan 
371495c8ff4SLin Jinhan 	printf("\n=================== hash & hmac test ===================\n");
37280ca1a53SLin Jinhan 
373495c8ff4SLin Jinhan 	for (i = 0; i < ARRAY_SIZE(hash_data_set); i++) {
374495c8ff4SLin Jinhan 		test_data = &hash_data_set[i];
375495c8ff4SLin Jinhan 		if (test_data->algo == 0) {
376495c8ff4SLin Jinhan 			printf("\n");
377495c8ff4SLin Jinhan 			continue;
378495c8ff4SLin Jinhan 		}
379495c8ff4SLin Jinhan 
380495c8ff4SLin Jinhan 		dev = crypto_get_device(test_data->algo);
381495c8ff4SLin Jinhan 		if (!dev) {
382495c8ff4SLin Jinhan 			printf("[%s] %-16s unsupported!!!\n",
383495c8ff4SLin Jinhan 			       test_data->algo_name,
384495c8ff4SLin Jinhan 			       test_data->mode_name);
385495c8ff4SLin Jinhan 			continue;
386495c8ff4SLin Jinhan 		}
387495c8ff4SLin Jinhan 
388495c8ff4SLin Jinhan 		csha_ctx.algo   = test_data->algo;
389495c8ff4SLin Jinhan 		csha_ctx.length = test_data->data_len;
390495c8ff4SLin Jinhan 
391495c8ff4SLin Jinhan 		memset(out, 0x00, sizeof(out));
392495c8ff4SLin Jinhan 		if (test_data->key) {
393495c8ff4SLin Jinhan 			ret = crypto_hmac_init(dev, &csha_ctx,
394495c8ff4SLin Jinhan 					       (u8 *)test_data->key,
395495c8ff4SLin Jinhan 					       test_data->key_len);
396495c8ff4SLin Jinhan 			ret |= crypto_hmac_update(dev, (void *)test_data->data,
397495c8ff4SLin Jinhan 						  test_data->data_len);
398495c8ff4SLin Jinhan 			ret |= crypto_hmac_final(dev, &csha_ctx, out);
399495c8ff4SLin Jinhan 			if (ret) {
400495c8ff4SLin Jinhan 				printf("hmac calc error ret = %d\n", ret);
401495c8ff4SLin Jinhan 				goto error;
402495c8ff4SLin Jinhan 			}
403495c8ff4SLin Jinhan 		} else {
404495c8ff4SLin Jinhan 			ret = crypto_sha_init(dev, &csha_ctx);
405495c8ff4SLin Jinhan 			ret |= crypto_sha_update(dev, (void *)test_data->data,
406495c8ff4SLin Jinhan 						 test_data->data_len);
407495c8ff4SLin Jinhan 			ret |= crypto_sha_final(dev, &csha_ctx, out);
408495c8ff4SLin Jinhan 			if (ret) {
409495c8ff4SLin Jinhan 				printf("hash calc error ret = %d\n", ret);
410495c8ff4SLin Jinhan 				goto error;
411495c8ff4SLin Jinhan 			}
412495c8ff4SLin Jinhan 		}
413495c8ff4SLin Jinhan 
414415ed02bSLin Jinhan 		ulong MBps = 0;
415415ed02bSLin Jinhan 
416415ed02bSLin Jinhan 		test_hash_perf(dev, test_data->algo,
417415ed02bSLin Jinhan 			       test_data->key, test_data->key_len, &MBps);
418415ed02bSLin Jinhan 		print_result_MBps(test_data->algo_name, test_data->mode_name,
419415ed02bSLin Jinhan 				  "", MBps, test_data->hash, out,
420415ed02bSLin Jinhan 				  test_data->hash_len);
421495c8ff4SLin Jinhan 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
422495c8ff4SLin Jinhan 	}
423495c8ff4SLin Jinhan 
424495c8ff4SLin Jinhan 	return 0;
425495c8ff4SLin Jinhan error:
426495c8ff4SLin Jinhan 	printf("%s %s test error!\n",
427495c8ff4SLin Jinhan 	       test_data->algo_name, test_data->mode_name);
428495c8ff4SLin Jinhan 	return ret;
429495c8ff4SLin Jinhan }
430495c8ff4SLin Jinhan 
431495c8ff4SLin Jinhan int test_cipher_result(void)
432495c8ff4SLin Jinhan {
433495c8ff4SLin Jinhan 	const struct cipher_test_data *test_data = NULL;
434495c8ff4SLin Jinhan 	struct udevice *dev;
435495c8ff4SLin Jinhan 	cipher_context ctx;
436495c8ff4SLin Jinhan 	u8 out[256];
437495c8ff4SLin Jinhan 	int ret;
438495c8ff4SLin Jinhan 	u32 i;
439495c8ff4SLin Jinhan 
440495c8ff4SLin Jinhan 	printf("\n===================== cipher test ======================\n");
441495c8ff4SLin Jinhan 
442495c8ff4SLin Jinhan 	for (i = 0; i < ARRAY_SIZE(cipher_data_set); i++) {
443495c8ff4SLin Jinhan 		test_data = &cipher_data_set[i];
444495c8ff4SLin Jinhan 		if (test_data->algo == 0) {
445495c8ff4SLin Jinhan 			printf("\n");
446495c8ff4SLin Jinhan 			continue;
447495c8ff4SLin Jinhan 		}
448495c8ff4SLin Jinhan 
449495c8ff4SLin Jinhan 		dev = crypto_get_device(test_data->algo);
450495c8ff4SLin Jinhan 		if (!dev) {
451495c8ff4SLin Jinhan 			printf("[%s] %-16s unsupported!!!\n",
452495c8ff4SLin Jinhan 			       test_data->algo_name, test_data->mode_name);
453495c8ff4SLin Jinhan 			continue;
454495c8ff4SLin Jinhan 		}
455495c8ff4SLin Jinhan 
456495c8ff4SLin Jinhan 		memset(&ctx, 0x00, sizeof(ctx));
457495c8ff4SLin Jinhan 
458495c8ff4SLin Jinhan 		ctx.algo    = test_data->algo;
459495c8ff4SLin Jinhan 		ctx.mode    = test_data->mode;
460495c8ff4SLin Jinhan 		ctx.key     = test_data->key;
461495c8ff4SLin Jinhan 		ctx.twk_key = test_data->twk_key;
462495c8ff4SLin Jinhan 		ctx.key_len = test_data->key_len;
463495c8ff4SLin Jinhan 		ctx.iv      = test_data->iv;
464495c8ff4SLin Jinhan 		ctx.iv_len  = test_data->iv_len;
465495c8ff4SLin Jinhan 
466415ed02bSLin Jinhan 		ulong MBps = 0;
467415ed02bSLin Jinhan 
468415ed02bSLin Jinhan 		test_cipher_perf(dev, &ctx, &MBps, true);
469415ed02bSLin Jinhan 
470*65ac8e46SLin Jinhan 		/* AES/SM4 mac */
471*65ac8e46SLin Jinhan 		if (IS_MAC_MODE(ctx.mode))
472*65ac8e46SLin Jinhan 			ret = crypto_mac(dev, &ctx, test_data->plain,
473*65ac8e46SLin Jinhan 					 test_data->plain_len, out);
474*65ac8e46SLin Jinhan 		else
475495c8ff4SLin Jinhan 			ret = crypto_cipher(dev, &ctx, test_data->plain,
476495c8ff4SLin Jinhan 					    out, test_data->plain_len, true);
477495c8ff4SLin Jinhan 		if (ret)
478495c8ff4SLin Jinhan 			goto error;
479495c8ff4SLin Jinhan 
480415ed02bSLin Jinhan 		print_result_MBps(test_data->algo_name, test_data->mode_name,
481415ed02bSLin Jinhan 				  "encrypt", MBps, test_data->cipher, out,
482495c8ff4SLin Jinhan 				  test_data->cipher_len);
483495c8ff4SLin Jinhan 
484*65ac8e46SLin Jinhan 		if (!IS_MAC_MODE(ctx.mode)) {
485415ed02bSLin Jinhan 			test_cipher_perf(dev, &ctx, &MBps, false);
486495c8ff4SLin Jinhan 			ret = crypto_cipher(dev, &ctx, test_data->cipher,
487495c8ff4SLin Jinhan 					    out, test_data->cipher_len, false);
488495c8ff4SLin Jinhan 			if (ret)
489495c8ff4SLin Jinhan 				goto error;
490495c8ff4SLin Jinhan 
491*65ac8e46SLin Jinhan 			print_result_MBps(test_data->algo_name,
492*65ac8e46SLin Jinhan 					  test_data->mode_name,
493*65ac8e46SLin Jinhan 					  "decrypt", MBps,
494*65ac8e46SLin Jinhan 					  test_data->plain, out,
495495c8ff4SLin Jinhan 					  test_data->plain_len);
496*65ac8e46SLin Jinhan 		}
497495c8ff4SLin Jinhan 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
498495c8ff4SLin Jinhan 	}
499495c8ff4SLin Jinhan 	return 0;
500495c8ff4SLin Jinhan error:
501*65ac8e46SLin Jinhan 	printf("%s %s test error, ret = %d!\n",
502*65ac8e46SLin Jinhan 	       test_data->algo_name, test_data->mode_name, ret);
503495c8ff4SLin Jinhan 	return ret;
504495c8ff4SLin Jinhan }
505495c8ff4SLin Jinhan 
506495c8ff4SLin Jinhan int test_rsa_result(void)
507495c8ff4SLin Jinhan {
508495c8ff4SLin Jinhan 	const struct rsa_test_data *test_data = NULL;
509495c8ff4SLin Jinhan 	u8 *hard_out = NULL, *e_tmp;
510495c8ff4SLin Jinhan 	u32 data_size = 4096 / 8;
511415ed02bSLin Jinhan 	ulong start, time_cost;
512495c8ff4SLin Jinhan 	struct udevice *dev;
513495c8ff4SLin Jinhan 	rsa_key rsa_key;
514495c8ff4SLin Jinhan 	int ret, i;
515495c8ff4SLin Jinhan 
516495c8ff4SLin Jinhan 	hard_out = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
517495c8ff4SLin Jinhan 	if (!hard_out) {
51880ca1a53SLin Jinhan 		printf("%s, %d: memalign %u error!\n",
51980ca1a53SLin Jinhan 		       __func__, __LINE__, data_size);
52080ca1a53SLin Jinhan 		return -EINVAL;
52180ca1a53SLin Jinhan 	}
52280ca1a53SLin Jinhan 
523495c8ff4SLin Jinhan 	e_tmp = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
524495c8ff4SLin Jinhan 	if (!e_tmp) {
525495c8ff4SLin Jinhan 		printf("%s, %d: memalign %u error!\n",
526495c8ff4SLin Jinhan 		       __func__, __LINE__, data_size);
527495c8ff4SLin Jinhan 		return -EINVAL;
52880ca1a53SLin Jinhan 	}
52980ca1a53SLin Jinhan 
530495c8ff4SLin Jinhan 	printf("\n====================== rsa test ========================\n");
531495c8ff4SLin Jinhan 	for (i = 0; i < ARRAY_SIZE(rsa_data_set); i++) {
532495c8ff4SLin Jinhan 		test_data = &rsa_data_set[i];
533495c8ff4SLin Jinhan 		if (test_data->algo == 0) {
534495c8ff4SLin Jinhan 			printf("\n");
535495c8ff4SLin Jinhan 			continue;
536495c8ff4SLin Jinhan 		}
53780ca1a53SLin Jinhan 
538495c8ff4SLin Jinhan 		dev = crypto_get_device(test_data->algo);
539495c8ff4SLin Jinhan 		if (!dev) {
540495c8ff4SLin Jinhan 			printf("[%s] %-16s unsupported!!!\n",
541495c8ff4SLin Jinhan 			       test_data->algo_name, test_data->mode_name);
542495c8ff4SLin Jinhan 			continue;
543495c8ff4SLin Jinhan 		}
54480ca1a53SLin Jinhan 
545495c8ff4SLin Jinhan 		/* sign test */
546495c8ff4SLin Jinhan 		memset(&rsa_key, 0x00, sizeof(rsa_key));
547495c8ff4SLin Jinhan 		rsa_key.algo = test_data->algo;
548495c8ff4SLin Jinhan 		rsa_key.n = (u32 *)test_data->n;
549495c8ff4SLin Jinhan 		rsa_key.e = (u32 *)test_data->d;
550495c8ff4SLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
551495c8ff4SLin Jinhan 		rsa_key.c = (u32 *)test_data->c;
552495c8ff4SLin Jinhan #endif
55380ca1a53SLin Jinhan 
554415ed02bSLin Jinhan 		start = get_timer(0);
555495c8ff4SLin Jinhan 		ret = crypto_rsa_verify(dev, &rsa_key,
556495c8ff4SLin Jinhan 					(u8 *)test_data->sign_in, hard_out);
557495c8ff4SLin Jinhan 		if (ret) {
558495c8ff4SLin Jinhan 			printf("sign test error, ret = %d\n", ret);
559495c8ff4SLin Jinhan 			goto error;
560495c8ff4SLin Jinhan 		}
561415ed02bSLin Jinhan 		time_cost = get_timer(start);
562415ed02bSLin Jinhan 		print_result_ms(test_data->algo_name, test_data->mode_name,
563415ed02bSLin Jinhan 				"sign", time_cost, test_data->sign_out,
564495c8ff4SLin Jinhan 				hard_out, test_data->n_len);
565495c8ff4SLin Jinhan 
566495c8ff4SLin Jinhan 		/* verify test */
567495c8ff4SLin Jinhan 		memset(&rsa_key, 0x00, sizeof(rsa_key));
568495c8ff4SLin Jinhan 		memset(e_tmp, 0x00, data_size);
569495c8ff4SLin Jinhan 		memcpy(e_tmp, test_data->e, test_data->e_len);
570495c8ff4SLin Jinhan 		rsa_key.algo = test_data->algo;
571495c8ff4SLin Jinhan 		rsa_key.n = (u32 *)test_data->n;
572495c8ff4SLin Jinhan 		rsa_key.e = (u32 *)e_tmp;
573495c8ff4SLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
574495c8ff4SLin Jinhan 		rsa_key.c = (u32 *)test_data->c;
575495c8ff4SLin Jinhan #endif
576495c8ff4SLin Jinhan 
577415ed02bSLin Jinhan 		start = get_timer(0);
578495c8ff4SLin Jinhan 		ret = crypto_rsa_verify(dev, &rsa_key,
579495c8ff4SLin Jinhan 					(u8 *)test_data->sign_out, hard_out);
580495c8ff4SLin Jinhan 		if (ret) {
581495c8ff4SLin Jinhan 			printf("verify test error, ret = %d\n", ret);
582495c8ff4SLin Jinhan 			goto error;
583495c8ff4SLin Jinhan 		}
584415ed02bSLin Jinhan 		time_cost = get_timer(start);
585495c8ff4SLin Jinhan 
586415ed02bSLin Jinhan 		print_result_ms(test_data->algo_name, test_data->mode_name,
587415ed02bSLin Jinhan 				"verify", time_cost, test_data->sign_in,
588495c8ff4SLin Jinhan 				hard_out, test_data->n_len);
589495c8ff4SLin Jinhan 
590495c8ff4SLin Jinhan 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
591495c8ff4SLin Jinhan 	}
592495c8ff4SLin Jinhan 
593495c8ff4SLin Jinhan 	free(hard_out);
594495c8ff4SLin Jinhan 	free(e_tmp);
595495c8ff4SLin Jinhan 
596495c8ff4SLin Jinhan 	return 0;
597495c8ff4SLin Jinhan error:
598495c8ff4SLin Jinhan 	free(hard_out);
599495c8ff4SLin Jinhan 	free(e_tmp);
600495c8ff4SLin Jinhan 	printf("%s %s test error!\n",
601495c8ff4SLin Jinhan 	       test_data->algo_name, test_data->mode_name);
60280ca1a53SLin Jinhan 	return ret;
60380ca1a53SLin Jinhan }
60480ca1a53SLin Jinhan 
605495c8ff4SLin Jinhan static int test_all_result(void)
606495c8ff4SLin Jinhan {
607495c8ff4SLin Jinhan 	int ret = 0;
608495c8ff4SLin Jinhan 
609495c8ff4SLin Jinhan 	ret = test_hash_result();
610495c8ff4SLin Jinhan 	if (ret)
611495c8ff4SLin Jinhan 		goto exit;
612495c8ff4SLin Jinhan 
613495c8ff4SLin Jinhan 	ret = test_cipher_result();
614495c8ff4SLin Jinhan 	if (ret)
615495c8ff4SLin Jinhan 		goto exit;
616495c8ff4SLin Jinhan 
617495c8ff4SLin Jinhan 	ret = test_rsa_result();
618495c8ff4SLin Jinhan 	if (ret)
619495c8ff4SLin Jinhan 		goto exit;
620495c8ff4SLin Jinhan 
621495c8ff4SLin Jinhan exit:
622495c8ff4SLin Jinhan 	return 0;
623495c8ff4SLin Jinhan }
624495c8ff4SLin Jinhan 
625cc6ac5d6SJoseph Chen static int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
626cc6ac5d6SJoseph Chen {
627495c8ff4SLin Jinhan 	return test_all_result();
628cc6ac5d6SJoseph Chen }
629cc6ac5d6SJoseph Chen 
630cc6ac5d6SJoseph Chen U_BOOT_CMD(
631cc6ac5d6SJoseph Chen 	crypto, 1, 1, do_crypto,
632cc6ac5d6SJoseph Chen 	"crypto test",
633cc6ac5d6SJoseph Chen 	""
634cc6ac5d6SJoseph Chen );
635