xref: /rk3399_rockchip-uboot/cmd/crypto.c (revision 415ed02b36e045a6c767da1d596a1c602f906662)
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 
16*415ed02bSLin Jinhan #define PERF_TOTAL_SIZE			(128 * 1024 * 1024)
17*415ed02bSLin Jinhan #define PERF_BUFF_SIZE			(4 * 1024 * 1024)
18*415ed02bSLin Jinhan 
19*415ed02bSLin Jinhan #define CALC_RATE_MPBS(bytes, ms)	(((bytes) / 1024) / (ms))
20*415ed02bSLin 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 
67495c8ff4SLin Jinhan #define HASH_TEST(algo_type, data_in, hash_val) {\
68495c8ff4SLin Jinhan 	.algo_name = "HASH", \
69495c8ff4SLin Jinhan 	.mode_name = #algo_type, \
70495c8ff4SLin Jinhan 	.algo      = CRYPTO_##algo_type, \
71495c8ff4SLin Jinhan 	.data      = (data_in),\
72495c8ff4SLin Jinhan 	.data_len  = sizeof(data_in), \
73495c8ff4SLin Jinhan 	.hash      = (hash_val), \
74495c8ff4SLin Jinhan 	.hash_len  = sizeof(hash_val) \
75cc6ac5d6SJoseph Chen }
76cc6ac5d6SJoseph Chen 
77495c8ff4SLin Jinhan #define HMAC_TEST(algo_type, data_in, hash_val, hmac_key) {\
78495c8ff4SLin Jinhan 	.algo_name = "HMAC", \
79495c8ff4SLin Jinhan 	.mode_name = #algo_type, \
80495c8ff4SLin Jinhan 	.algo      = CRYPTO_HMAC_##algo_type, \
81495c8ff4SLin Jinhan 	.data      = (data_in),\
82495c8ff4SLin Jinhan 	.data_len  = sizeof(data_in), \
83495c8ff4SLin Jinhan 	.hash      = (hash_val), \
84495c8ff4SLin Jinhan 	.hash_len  = sizeof(hash_val), \
85495c8ff4SLin Jinhan 	.key       = (hmac_key), \
86495c8ff4SLin Jinhan 	.key_len   = sizeof(hmac_key)\
87495c8ff4SLin Jinhan }
88495c8ff4SLin Jinhan 
89495c8ff4SLin Jinhan #define CIPHER_XTS_TEST(algo_type, mode_type, key1, key2, iv_val, in, out) { \
90495c8ff4SLin Jinhan 	.algo_name  = #algo_type, \
91495c8ff4SLin Jinhan 	.mode_name  = #mode_type, \
92495c8ff4SLin Jinhan 	.algo       = CRYPTO_##algo_type,\
93495c8ff4SLin Jinhan 	.mode       = RK_MODE_##mode_type, \
94495c8ff4SLin Jinhan 	.key        = (key1), \
95495c8ff4SLin Jinhan 	.twk_key    = (key2), \
96495c8ff4SLin Jinhan 	.key_len    = sizeof(key1), \
97495c8ff4SLin Jinhan 	.iv         = (iv_val), \
98495c8ff4SLin Jinhan 	.iv_len     = sizeof(iv_val), \
99495c8ff4SLin Jinhan 	.plain      = (in), \
100495c8ff4SLin Jinhan 	.plain_len  = sizeof(in), \
101495c8ff4SLin Jinhan 	.cipher     = (out), \
102495c8ff4SLin Jinhan 	.cipher_len = sizeof(out) \
103495c8ff4SLin Jinhan }
104495c8ff4SLin Jinhan 
105495c8ff4SLin Jinhan #define CIPHER_TEST(algo, mode, key, iv, plain, cipher) \
106495c8ff4SLin Jinhan 		CIPHER_XTS_TEST(algo, mode, key, NULL, iv, plain, cipher)
107495c8ff4SLin Jinhan 
108495c8ff4SLin Jinhan #define RSA_TEST(nbits, bn, be, bc, bd, in, out) { \
109495c8ff4SLin Jinhan 	.algo_name    = "RSA", \
110495c8ff4SLin Jinhan 	.mode_name    = #nbits, \
111495c8ff4SLin Jinhan 	.algo         = CRYPTO_RSA##nbits, \
112495c8ff4SLin Jinhan 	.n            = (bn), \
113495c8ff4SLin Jinhan 	.n_len        = sizeof(bn), \
114495c8ff4SLin Jinhan 	.e            = (be), \
115495c8ff4SLin Jinhan 	.e_len        = sizeof(be), \
116495c8ff4SLin Jinhan 	.d            = (bd), \
117495c8ff4SLin Jinhan 	.d_len        = sizeof(bd), \
118495c8ff4SLin Jinhan 	.c            = (bc), \
119495c8ff4SLin Jinhan 	.c_len        = sizeof(bc), \
120495c8ff4SLin Jinhan 	.sign_in      = (in), \
121495c8ff4SLin Jinhan 	.sign_in_len  = sizeof(in), \
122495c8ff4SLin Jinhan 	.sign_out     = (out), \
123495c8ff4SLin Jinhan 	.sign_out_len = sizeof(out) \
124495c8ff4SLin Jinhan }
125495c8ff4SLin Jinhan 
126495c8ff4SLin Jinhan #define EMPTY_TEST() {}
127495c8ff4SLin Jinhan 
128495c8ff4SLin Jinhan const struct hash_test_data hash_data_set[] = {
129495c8ff4SLin Jinhan 	HASH_TEST(MD5,    foo_data, hash_md5),
130495c8ff4SLin Jinhan 	HASH_TEST(SHA1,   foo_data, hash_sha1),
131495c8ff4SLin Jinhan 	HASH_TEST(SHA256, foo_data, hash_sha256),
132495c8ff4SLin Jinhan 	HASH_TEST(SHA512, foo_data, hash_sha512),
133495c8ff4SLin Jinhan 	HASH_TEST(SM3,    foo_data, hash_sm3),
134495c8ff4SLin Jinhan 
135495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC)
136495c8ff4SLin Jinhan 	EMPTY_TEST(),
137495c8ff4SLin Jinhan 	HMAC_TEST(MD5,    foo_data, hmac_md5,    hmac_key),
138495c8ff4SLin Jinhan 	HMAC_TEST(SHA1,   foo_data, hmac_sha1,   hmac_key),
139495c8ff4SLin Jinhan 	HMAC_TEST(SHA256, foo_data, hmac_sha256, hmac_key),
140495c8ff4SLin Jinhan 	HMAC_TEST(SHA512, foo_data, hmac_sha512, hmac_key),
141495c8ff4SLin Jinhan 	HMAC_TEST(SM3,    foo_data, hmac_sm3,    hmac_key),
142495c8ff4SLin Jinhan #endif
143495c8ff4SLin Jinhan };
144495c8ff4SLin Jinhan 
145495c8ff4SLin Jinhan const struct cipher_test_data cipher_data_set[] = {
146495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)
147495c8ff4SLin Jinhan 	CIPHER_TEST(DES, ECB, des_key, des_iv, foo_data, des_ecb_cipher),
148495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CBC, des_key, des_iv, foo_data, des_cbc_cipher),
149495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CFB, des_key, des_iv, foo_data, des_cfb_cipher),
150495c8ff4SLin Jinhan 	CIPHER_TEST(DES, OFB, des_key, des_iv, foo_data, des_ofb_cipher),
151495c8ff4SLin Jinhan 
152495c8ff4SLin Jinhan 	EMPTY_TEST(),
153495c8ff4SLin Jinhan 	CIPHER_TEST(DES, ECB, tdes_key, tdes_iv, foo_data, tdes_ecb_cipher),
154495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CBC, tdes_key, tdes_iv, foo_data, tdes_cbc_cipher),
155495c8ff4SLin Jinhan 	CIPHER_TEST(DES, CFB, tdes_key, tdes_iv, foo_data, tdes_cfb_cipher),
156495c8ff4SLin Jinhan 	CIPHER_TEST(DES, OFB, tdes_key, tdes_iv, foo_data, tdes_ofb_cipher),
157495c8ff4SLin Jinhan 
158495c8ff4SLin Jinhan 	EMPTY_TEST(),
159495c8ff4SLin Jinhan 	CIPHER_TEST(AES, ECB, aes_key, aes_iv, foo_data, aes_ecb_cipher),
160495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CBC, aes_key, aes_iv, foo_data, aes_cbc_cipher),
161495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CFB, aes_key, aes_iv, foo_data, aes_cfb_cipher),
162495c8ff4SLin Jinhan 	CIPHER_TEST(AES, OFB, aes_key, aes_iv, foo_data, aes_ofb_cipher),
163495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CTS, aes_key, aes_iv, foo_data, aes_cts_cipher),
164495c8ff4SLin Jinhan 	CIPHER_TEST(AES, CTR, aes_key, aes_iv, foo_data, aes_ctr_cipher),
165495c8ff4SLin Jinhan 	CIPHER_XTS_TEST(AES, XTS, aes_key, aes_twk_key,
166495c8ff4SLin Jinhan 			aes_iv, foo_data, aes_xts_cipher),
167495c8ff4SLin Jinhan 
168495c8ff4SLin Jinhan 	EMPTY_TEST(),
169495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, ECB, sm4_key, sm4_iv, foo_data, sm4_ecb_cipher),
170495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CBC, sm4_key, sm4_iv, foo_data, sm4_cbc_cipher),
171495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CFB, sm4_key, sm4_iv, foo_data, sm4_cfb_cipher),
172495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, OFB, sm4_key, sm4_iv, foo_data, sm4_ofb_cipher),
173495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CTS, sm4_key, sm4_iv, foo_data, sm4_cts_cipher),
174495c8ff4SLin Jinhan 	CIPHER_TEST(SM4, CTR, sm4_key, sm4_iv, foo_data, sm4_ctr_cipher),
175495c8ff4SLin Jinhan 	CIPHER_XTS_TEST(SM4, XTS, sm4_key, sm4_twk_key,
176495c8ff4SLin Jinhan 			sm4_iv, foo_data, sm4_xts_cipher),
177495c8ff4SLin Jinhan #else
178495c8ff4SLin Jinhan 	EMPTY_TEST(),
179495c8ff4SLin Jinhan #endif
180495c8ff4SLin Jinhan };
181495c8ff4SLin Jinhan 
182495c8ff4SLin Jinhan const struct rsa_test_data rsa_data_set[] = {
183495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA)
184*415ed02bSLin Jinhan 
185*415ed02bSLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
186495c8ff4SLin Jinhan 	RSA_TEST(2048, rsa2048_n, rsa2048_e, rsa2048_c, rsa2048_d,
187495c8ff4SLin Jinhan 		 rsa2048_sign_in, rsa2048_sign_out),
188495c8ff4SLin Jinhan #else
189*415ed02bSLin Jinhan 	RSA_TEST(4096, rsa4096_n, rsa4096_e, NULL, rsa4096_d,
190*415ed02bSLin Jinhan 		 rsa4096_sign_in, rsa4096_sign_out),
191*415ed02bSLin Jinhan #endif
192*415ed02bSLin Jinhan 
193*415ed02bSLin Jinhan #else
194495c8ff4SLin Jinhan 	EMPTY_TEST(),
195495c8ff4SLin Jinhan #endif
196495c8ff4SLin Jinhan };
197495c8ff4SLin Jinhan 
198495c8ff4SLin Jinhan static void dump_hex(const char *name, const u8 *array, u32 len)
19980ca1a53SLin Jinhan {
200495c8ff4SLin Jinhan 	int i;
201495c8ff4SLin Jinhan 
202495c8ff4SLin Jinhan 	printf("[%s]: %uByte", name, len);
203495c8ff4SLin Jinhan 	for (i = 0; i < len; i++) {
204495c8ff4SLin Jinhan 		if (i % 32 == 0)
205495c8ff4SLin Jinhan 			printf("\n");
206495c8ff4SLin Jinhan 		printf("%02x ", array[i]);
207495c8ff4SLin Jinhan 	}
208495c8ff4SLin Jinhan 	printf("\n");
209495c8ff4SLin Jinhan }
210495c8ff4SLin Jinhan 
211*415ed02bSLin Jinhan static inline void print_result_MBps(const char *algo_name,
212*415ed02bSLin Jinhan 				     const char *mode_name,
213*415ed02bSLin Jinhan 				     const char *crypt, ulong MBps,
214*415ed02bSLin Jinhan 				     const u8 *expect, const u8 *actual,
215*415ed02bSLin Jinhan 				     u32 len)
216495c8ff4SLin Jinhan {
217495c8ff4SLin Jinhan 	if (memcmp(expect, actual, len) == 0) {
218*415ed02bSLin Jinhan 		printf("[%s] %-8s%-8s PASS    (%luMBps)\n",
219*415ed02bSLin Jinhan 		       algo_name, mode_name, crypt, MBps);
220495c8ff4SLin Jinhan 	} else {
221495c8ff4SLin Jinhan 		printf("[%s] %-8s%-8s FAIL\n",
222495c8ff4SLin Jinhan 		       algo_name, mode_name, crypt);
223495c8ff4SLin Jinhan 		dump_hex("expect", expect, len);
224495c8ff4SLin Jinhan 		dump_hex("actual", actual, len);
225495c8ff4SLin Jinhan 	}
226495c8ff4SLin Jinhan }
227495c8ff4SLin Jinhan 
228*415ed02bSLin Jinhan static inline void print_result_ms(const char *algo_name, const char *mode_name,
229*415ed02bSLin Jinhan 				   const char *crypt, ulong time_cost,
230*415ed02bSLin Jinhan 				   const u8 *expect, const u8 *actual, u32 len)
231*415ed02bSLin Jinhan {
232*415ed02bSLin Jinhan 	if (memcmp(expect, actual, len) == 0) {
233*415ed02bSLin Jinhan 		printf("[%s] %-8s%-8s PASS    (%lums)\n",
234*415ed02bSLin Jinhan 		       algo_name, mode_name, crypt, time_cost);
235*415ed02bSLin Jinhan 	} else {
236*415ed02bSLin Jinhan 		printf("[%s] %-8s%-8s FAIL\n",
237*415ed02bSLin Jinhan 		       algo_name, mode_name, crypt);
238*415ed02bSLin Jinhan 		dump_hex("expect", expect, len);
239*415ed02bSLin Jinhan 		dump_hex("actual", actual, len);
240*415ed02bSLin Jinhan 	}
241*415ed02bSLin Jinhan }
242*415ed02bSLin Jinhan 
243*415ed02bSLin Jinhan int test_hash_perf(struct udevice *dev, u32 algo,
244*415ed02bSLin Jinhan 		   const u8 *key, u32 key_len, ulong *MBps)
245*415ed02bSLin Jinhan {
246*415ed02bSLin Jinhan 	u32 total_size = PERF_TOTAL_SIZE;
247*415ed02bSLin Jinhan 	u32 data_size = PERF_BUFF_SIZE;
248*415ed02bSLin Jinhan 	sha_context ctx;
249*415ed02bSLin Jinhan 	u8 *data = NULL;
250*415ed02bSLin Jinhan 	u8 hash_out[64];
251*415ed02bSLin Jinhan 	int ret, i;
252*415ed02bSLin Jinhan 
253*415ed02bSLin Jinhan 	*MBps = 0;
254*415ed02bSLin Jinhan 
255*415ed02bSLin Jinhan 	ctx.algo = algo;
256*415ed02bSLin Jinhan 	ctx.length = total_size;
257*415ed02bSLin Jinhan 
258*415ed02bSLin Jinhan 	data = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
259*415ed02bSLin Jinhan 	if (!data) {
260*415ed02bSLin Jinhan 		printf("%s, %d: memalign %u error!\n",
261*415ed02bSLin Jinhan 		       __func__, __LINE__, data_size);
262*415ed02bSLin Jinhan 		return -EINVAL;
263*415ed02bSLin Jinhan 	}
264*415ed02bSLin Jinhan 
265*415ed02bSLin Jinhan 	memset(data, 0xab, data_size);
266*415ed02bSLin Jinhan 
267*415ed02bSLin Jinhan 	ulong start = get_timer(0);
268*415ed02bSLin Jinhan 
269*415ed02bSLin Jinhan 	if (key)
270*415ed02bSLin Jinhan 		ret = crypto_hmac_init(dev, &ctx, (u8 *)key, key_len);
271*415ed02bSLin Jinhan 	else
272*415ed02bSLin Jinhan 		ret = crypto_sha_init(dev, &ctx);
273*415ed02bSLin Jinhan 
274*415ed02bSLin Jinhan 	if (ret) {
275*415ed02bSLin Jinhan 		printf("crypto_sha_init error ret = %d!\n", ret);
276*415ed02bSLin Jinhan 		goto exit;
277*415ed02bSLin Jinhan 	}
278*415ed02bSLin Jinhan 
279*415ed02bSLin Jinhan 	for (i = 0; i < total_size / data_size; i++) {
280*415ed02bSLin Jinhan 		ret = crypto_sha_update(dev, (u32 *)data, data_size);
281*415ed02bSLin Jinhan 		if (ret) {
282*415ed02bSLin Jinhan 			printf("crypto_sha_update error!\n");
283*415ed02bSLin Jinhan 			goto exit;
284*415ed02bSLin Jinhan 		}
285*415ed02bSLin Jinhan 	}
286*415ed02bSLin Jinhan 
287*415ed02bSLin Jinhan 	ret = crypto_sha_final(dev, &ctx, hash_out);
288*415ed02bSLin Jinhan 	if (ret) {
289*415ed02bSLin Jinhan 		printf("crypto_sha_final error ret = %d!\n", ret);
290*415ed02bSLin Jinhan 		goto exit;
291*415ed02bSLin Jinhan 	}
292*415ed02bSLin Jinhan 
293*415ed02bSLin Jinhan 	ulong time_cost = get_timer(start);
294*415ed02bSLin Jinhan 
295*415ed02bSLin Jinhan 	*MBps = CALC_RATE_MPBS(total_size, time_cost);
296*415ed02bSLin Jinhan 
297*415ed02bSLin Jinhan exit:
298*415ed02bSLin Jinhan 	free(data);
299*415ed02bSLin Jinhan 
300*415ed02bSLin Jinhan 	return ret;
301*415ed02bSLin Jinhan }
302*415ed02bSLin Jinhan 
303*415ed02bSLin Jinhan int test_cipher_perf(struct udevice *dev, cipher_context *ctx,
304*415ed02bSLin Jinhan 		     ulong *MBps, bool enc)
305*415ed02bSLin Jinhan {
306*415ed02bSLin Jinhan 	u32 total_size = PERF_TOTAL_SIZE;
307*415ed02bSLin Jinhan 	u32 data_size = PERF_BUFF_SIZE;
308*415ed02bSLin Jinhan 	u8 *plain = NULL, *cipher = NULL;
309*415ed02bSLin Jinhan 	int ret, i;
310*415ed02bSLin Jinhan 
311*415ed02bSLin Jinhan 	*MBps = 0;
312*415ed02bSLin Jinhan 
313*415ed02bSLin Jinhan 	plain = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
314*415ed02bSLin Jinhan 	if (!plain) {
315*415ed02bSLin Jinhan 		printf("%s, %d: memalign %u error!\n",
316*415ed02bSLin Jinhan 		       __func__, __LINE__, data_size);
317*415ed02bSLin Jinhan 		return -EINVAL;
318*415ed02bSLin Jinhan 	}
319*415ed02bSLin Jinhan 
320*415ed02bSLin Jinhan 	cipher = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
321*415ed02bSLin Jinhan 	if (!cipher) {
322*415ed02bSLin Jinhan 		printf("%s, %d: memalign %u error!\n",
323*415ed02bSLin Jinhan 		       __func__, __LINE__, data_size);
324*415ed02bSLin Jinhan 		free(plain);
325*415ed02bSLin Jinhan 		return -EINVAL;
326*415ed02bSLin Jinhan 	}
327*415ed02bSLin Jinhan 
328*415ed02bSLin Jinhan 	memset(plain, 0xab, data_size);
329*415ed02bSLin Jinhan 
330*415ed02bSLin Jinhan 	ulong start = get_timer(0);
331*415ed02bSLin Jinhan 
332*415ed02bSLin Jinhan 	for (i = 0; i < total_size / data_size; i++) {
333*415ed02bSLin Jinhan 		ret = crypto_cipher(dev, ctx, plain, cipher, data_size, enc);
334*415ed02bSLin Jinhan 		if (ret) {
335*415ed02bSLin Jinhan 			printf("crypto_aes error!\n");
336*415ed02bSLin Jinhan 			goto exit;
337*415ed02bSLin Jinhan 		}
338*415ed02bSLin Jinhan 	}
339*415ed02bSLin Jinhan 
340*415ed02bSLin Jinhan 	ulong time_cost = get_timer(start);
341*415ed02bSLin Jinhan 
342*415ed02bSLin Jinhan 	*MBps = CALC_RATE_MPBS(total_size, time_cost);
343*415ed02bSLin Jinhan exit:
344*415ed02bSLin Jinhan 	free(plain);
345*415ed02bSLin Jinhan 	free(cipher);
346*415ed02bSLin Jinhan 
347*415ed02bSLin Jinhan 	return ret;
348*415ed02bSLin Jinhan }
349*415ed02bSLin Jinhan 
350495c8ff4SLin Jinhan int test_hash_result(void)
351495c8ff4SLin Jinhan {
352495c8ff4SLin Jinhan 	const struct hash_test_data *test_data = NULL;
353495c8ff4SLin Jinhan 	sha_context csha_ctx;
354495c8ff4SLin Jinhan 	struct udevice *dev;
355495c8ff4SLin Jinhan 	unsigned int i;
356495c8ff4SLin Jinhan 	u8 out[64];
35780ca1a53SLin Jinhan 	int ret;
35880ca1a53SLin Jinhan 
359495c8ff4SLin Jinhan 	printf("\n=================== hash & hmac test ===================\n");
36080ca1a53SLin Jinhan 
361495c8ff4SLin Jinhan 	for (i = 0; i < ARRAY_SIZE(hash_data_set); i++) {
362495c8ff4SLin Jinhan 		test_data = &hash_data_set[i];
363495c8ff4SLin Jinhan 		if (test_data->algo == 0) {
364495c8ff4SLin Jinhan 			printf("\n");
365495c8ff4SLin Jinhan 			continue;
366495c8ff4SLin Jinhan 		}
367495c8ff4SLin Jinhan 
368495c8ff4SLin Jinhan 		dev = crypto_get_device(test_data->algo);
369495c8ff4SLin Jinhan 		if (!dev) {
370495c8ff4SLin Jinhan 			printf("[%s] %-16s unsupported!!!\n",
371495c8ff4SLin Jinhan 			       test_data->algo_name,
372495c8ff4SLin Jinhan 			       test_data->mode_name);
373495c8ff4SLin Jinhan 			continue;
374495c8ff4SLin Jinhan 		}
375495c8ff4SLin Jinhan 
376495c8ff4SLin Jinhan 		csha_ctx.algo   = test_data->algo;
377495c8ff4SLin Jinhan 		csha_ctx.length = test_data->data_len;
378495c8ff4SLin Jinhan 
379495c8ff4SLin Jinhan 		memset(out, 0x00, sizeof(out));
380495c8ff4SLin Jinhan 		if (test_data->key) {
381495c8ff4SLin Jinhan 			ret = crypto_hmac_init(dev, &csha_ctx,
382495c8ff4SLin Jinhan 					       (u8 *)test_data->key,
383495c8ff4SLin Jinhan 					       test_data->key_len);
384495c8ff4SLin Jinhan 			ret |= crypto_hmac_update(dev, (void *)test_data->data,
385495c8ff4SLin Jinhan 						  test_data->data_len);
386495c8ff4SLin Jinhan 			ret |= crypto_hmac_final(dev, &csha_ctx, out);
387495c8ff4SLin Jinhan 			if (ret) {
388495c8ff4SLin Jinhan 				printf("hmac calc error ret = %d\n", ret);
389495c8ff4SLin Jinhan 				goto error;
390495c8ff4SLin Jinhan 			}
391495c8ff4SLin Jinhan 		} else {
392495c8ff4SLin Jinhan 			ret = crypto_sha_init(dev, &csha_ctx);
393495c8ff4SLin Jinhan 			ret |= crypto_sha_update(dev, (void *)test_data->data,
394495c8ff4SLin Jinhan 						 test_data->data_len);
395495c8ff4SLin Jinhan 			ret |= crypto_sha_final(dev, &csha_ctx, out);
396495c8ff4SLin Jinhan 			if (ret) {
397495c8ff4SLin Jinhan 				printf("hash calc error ret = %d\n", ret);
398495c8ff4SLin Jinhan 				goto error;
399495c8ff4SLin Jinhan 			}
400495c8ff4SLin Jinhan 		}
401495c8ff4SLin Jinhan 
402*415ed02bSLin Jinhan 		ulong MBps = 0;
403*415ed02bSLin Jinhan 
404*415ed02bSLin Jinhan 		test_hash_perf(dev, test_data->algo,
405*415ed02bSLin Jinhan 			       test_data->key, test_data->key_len, &MBps);
406*415ed02bSLin Jinhan 		print_result_MBps(test_data->algo_name, test_data->mode_name,
407*415ed02bSLin Jinhan 				  "", MBps, test_data->hash, out,
408*415ed02bSLin Jinhan 				  test_data->hash_len);
409495c8ff4SLin Jinhan 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
410495c8ff4SLin Jinhan 	}
411495c8ff4SLin Jinhan 
412495c8ff4SLin Jinhan 	return 0;
413495c8ff4SLin Jinhan error:
414495c8ff4SLin Jinhan 	printf("%s %s test error!\n",
415495c8ff4SLin Jinhan 	       test_data->algo_name, test_data->mode_name);
416495c8ff4SLin Jinhan 	return ret;
417495c8ff4SLin Jinhan }
418495c8ff4SLin Jinhan 
419495c8ff4SLin Jinhan int test_cipher_result(void)
420495c8ff4SLin Jinhan {
421495c8ff4SLin Jinhan 	const struct cipher_test_data *test_data = NULL;
422495c8ff4SLin Jinhan 	struct udevice *dev;
423495c8ff4SLin Jinhan 	cipher_context ctx;
424495c8ff4SLin Jinhan 	u8 out[256];
425495c8ff4SLin Jinhan 	int ret;
426495c8ff4SLin Jinhan 	u32 i;
427495c8ff4SLin Jinhan 
428495c8ff4SLin Jinhan 	printf("\n===================== cipher test ======================\n");
429495c8ff4SLin Jinhan 
430495c8ff4SLin Jinhan 	for (i = 0; i < ARRAY_SIZE(cipher_data_set); i++) {
431495c8ff4SLin Jinhan 		test_data = &cipher_data_set[i];
432495c8ff4SLin Jinhan 		if (test_data->algo == 0) {
433495c8ff4SLin Jinhan 			printf("\n");
434495c8ff4SLin Jinhan 			continue;
435495c8ff4SLin Jinhan 		}
436495c8ff4SLin Jinhan 
437495c8ff4SLin Jinhan 		dev = crypto_get_device(test_data->algo);
438495c8ff4SLin Jinhan 		if (!dev) {
439495c8ff4SLin Jinhan 			printf("[%s] %-16s unsupported!!!\n",
440495c8ff4SLin Jinhan 			       test_data->algo_name, test_data->mode_name);
441495c8ff4SLin Jinhan 			continue;
442495c8ff4SLin Jinhan 		}
443495c8ff4SLin Jinhan 
444495c8ff4SLin Jinhan 		memset(&ctx, 0x00, sizeof(ctx));
445495c8ff4SLin Jinhan 
446495c8ff4SLin Jinhan 		ctx.algo    = test_data->algo;
447495c8ff4SLin Jinhan 		ctx.mode    = test_data->mode;
448495c8ff4SLin Jinhan 		ctx.key     = test_data->key;
449495c8ff4SLin Jinhan 		ctx.twk_key = test_data->twk_key;
450495c8ff4SLin Jinhan 		ctx.key_len = test_data->key_len;
451495c8ff4SLin Jinhan 		ctx.iv      = test_data->iv;
452495c8ff4SLin Jinhan 		ctx.iv_len  = test_data->iv_len;
453495c8ff4SLin Jinhan 
454*415ed02bSLin Jinhan 		ulong MBps = 0;
455*415ed02bSLin Jinhan 
456*415ed02bSLin Jinhan 		test_cipher_perf(dev, &ctx, &MBps, true);
457*415ed02bSLin Jinhan 
458495c8ff4SLin Jinhan 		ret = crypto_cipher(dev, &ctx, test_data->plain,
459495c8ff4SLin Jinhan 				    out, test_data->plain_len, true);
460495c8ff4SLin Jinhan 		if (ret)
461495c8ff4SLin Jinhan 			goto error;
462495c8ff4SLin Jinhan 
463*415ed02bSLin Jinhan 		print_result_MBps(test_data->algo_name, test_data->mode_name,
464*415ed02bSLin Jinhan 				  "encrypt", MBps, test_data->cipher, out,
465495c8ff4SLin Jinhan 				  test_data->cipher_len);
466495c8ff4SLin Jinhan 
467*415ed02bSLin Jinhan 		test_cipher_perf(dev, &ctx, &MBps, false);
468*415ed02bSLin Jinhan 
469495c8ff4SLin Jinhan 		ret = crypto_cipher(dev, &ctx, test_data->cipher,
470495c8ff4SLin Jinhan 				    out, test_data->cipher_len, false);
471495c8ff4SLin Jinhan 		if (ret)
472495c8ff4SLin Jinhan 			goto error;
473495c8ff4SLin Jinhan 
474*415ed02bSLin Jinhan 		print_result_MBps(test_data->algo_name, test_data->mode_name,
475*415ed02bSLin Jinhan 				  "decrypt", MBps, test_data->plain, out,
476495c8ff4SLin Jinhan 				  test_data->plain_len);
477495c8ff4SLin Jinhan 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
478495c8ff4SLin Jinhan 	}
479495c8ff4SLin Jinhan 	return 0;
480495c8ff4SLin Jinhan error:
481495c8ff4SLin Jinhan 	printf("%s %s test error!\n",
482495c8ff4SLin Jinhan 	       test_data->algo_name, test_data->mode_name);
483495c8ff4SLin Jinhan 	return ret;
484495c8ff4SLin Jinhan }
485495c8ff4SLin Jinhan 
486495c8ff4SLin Jinhan int test_rsa_result(void)
487495c8ff4SLin Jinhan {
488495c8ff4SLin Jinhan 	const struct rsa_test_data *test_data = NULL;
489495c8ff4SLin Jinhan 	u8 *hard_out = NULL, *e_tmp;
490495c8ff4SLin Jinhan 	u32 data_size = 4096 / 8;
491*415ed02bSLin Jinhan 	ulong start, time_cost;
492495c8ff4SLin Jinhan 	struct udevice *dev;
493495c8ff4SLin Jinhan 	rsa_key rsa_key;
494495c8ff4SLin Jinhan 	int ret, i;
495495c8ff4SLin Jinhan 
496495c8ff4SLin Jinhan 	hard_out = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
497495c8ff4SLin Jinhan 	if (!hard_out) {
49880ca1a53SLin Jinhan 		printf("%s, %d: memalign %u error!\n",
49980ca1a53SLin Jinhan 		       __func__, __LINE__, data_size);
50080ca1a53SLin Jinhan 		return -EINVAL;
50180ca1a53SLin Jinhan 	}
50280ca1a53SLin Jinhan 
503495c8ff4SLin Jinhan 	e_tmp = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
504495c8ff4SLin Jinhan 	if (!e_tmp) {
505495c8ff4SLin Jinhan 		printf("%s, %d: memalign %u error!\n",
506495c8ff4SLin Jinhan 		       __func__, __LINE__, data_size);
507495c8ff4SLin Jinhan 		return -EINVAL;
50880ca1a53SLin Jinhan 	}
50980ca1a53SLin Jinhan 
510495c8ff4SLin Jinhan 	printf("\n====================== rsa test ========================\n");
511495c8ff4SLin Jinhan 	for (i = 0; i < ARRAY_SIZE(rsa_data_set); i++) {
512495c8ff4SLin Jinhan 		test_data = &rsa_data_set[i];
513495c8ff4SLin Jinhan 		if (test_data->algo == 0) {
514495c8ff4SLin Jinhan 			printf("\n");
515495c8ff4SLin Jinhan 			continue;
516495c8ff4SLin Jinhan 		}
51780ca1a53SLin Jinhan 
518495c8ff4SLin Jinhan 		dev = crypto_get_device(test_data->algo);
519495c8ff4SLin Jinhan 		if (!dev) {
520495c8ff4SLin Jinhan 			printf("[%s] %-16s unsupported!!!\n",
521495c8ff4SLin Jinhan 			       test_data->algo_name, test_data->mode_name);
522495c8ff4SLin Jinhan 			continue;
523495c8ff4SLin Jinhan 		}
52480ca1a53SLin Jinhan 
525495c8ff4SLin Jinhan 		/* sign test */
526495c8ff4SLin Jinhan 		memset(&rsa_key, 0x00, sizeof(rsa_key));
527495c8ff4SLin Jinhan 		rsa_key.algo = test_data->algo;
528495c8ff4SLin Jinhan 		rsa_key.n = (u32 *)test_data->n;
529495c8ff4SLin Jinhan 		rsa_key.e = (u32 *)test_data->d;
530495c8ff4SLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
531495c8ff4SLin Jinhan 		rsa_key.c = (u32 *)test_data->c;
532495c8ff4SLin Jinhan #endif
53380ca1a53SLin Jinhan 
534*415ed02bSLin Jinhan 		start = get_timer(0);
535495c8ff4SLin Jinhan 		ret = crypto_rsa_verify(dev, &rsa_key,
536495c8ff4SLin Jinhan 					(u8 *)test_data->sign_in, hard_out);
537495c8ff4SLin Jinhan 		if (ret) {
538495c8ff4SLin Jinhan 			printf("sign test error, ret = %d\n", ret);
539495c8ff4SLin Jinhan 			goto error;
540495c8ff4SLin Jinhan 		}
541*415ed02bSLin Jinhan 		time_cost = get_timer(start);
542*415ed02bSLin Jinhan 		print_result_ms(test_data->algo_name, test_data->mode_name,
543*415ed02bSLin Jinhan 				"sign", time_cost, test_data->sign_out,
544495c8ff4SLin Jinhan 				hard_out, test_data->n_len);
545495c8ff4SLin Jinhan 
546495c8ff4SLin Jinhan 		/* verify test */
547495c8ff4SLin Jinhan 		memset(&rsa_key, 0x00, sizeof(rsa_key));
548495c8ff4SLin Jinhan 		memset(e_tmp, 0x00, data_size);
549495c8ff4SLin Jinhan 		memcpy(e_tmp, test_data->e, test_data->e_len);
550495c8ff4SLin Jinhan 		rsa_key.algo = test_data->algo;
551495c8ff4SLin Jinhan 		rsa_key.n = (u32 *)test_data->n;
552495c8ff4SLin Jinhan 		rsa_key.e = (u32 *)e_tmp;
553495c8ff4SLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
554495c8ff4SLin Jinhan 		rsa_key.c = (u32 *)test_data->c;
555495c8ff4SLin Jinhan #endif
556495c8ff4SLin Jinhan 
557*415ed02bSLin Jinhan 		start = get_timer(0);
558495c8ff4SLin Jinhan 		ret = crypto_rsa_verify(dev, &rsa_key,
559495c8ff4SLin Jinhan 					(u8 *)test_data->sign_out, hard_out);
560495c8ff4SLin Jinhan 		if (ret) {
561495c8ff4SLin Jinhan 			printf("verify test error, ret = %d\n", ret);
562495c8ff4SLin Jinhan 			goto error;
563495c8ff4SLin Jinhan 		}
564*415ed02bSLin Jinhan 		time_cost = get_timer(start);
565495c8ff4SLin Jinhan 
566*415ed02bSLin Jinhan 		print_result_ms(test_data->algo_name, test_data->mode_name,
567*415ed02bSLin Jinhan 				"verify", time_cost, test_data->sign_in,
568495c8ff4SLin Jinhan 				hard_out, test_data->n_len);
569495c8ff4SLin Jinhan 
570495c8ff4SLin Jinhan 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
571495c8ff4SLin Jinhan 	}
572495c8ff4SLin Jinhan 
573495c8ff4SLin Jinhan 	free(hard_out);
574495c8ff4SLin Jinhan 	free(e_tmp);
575495c8ff4SLin Jinhan 
576495c8ff4SLin Jinhan 	return 0;
577495c8ff4SLin Jinhan error:
578495c8ff4SLin Jinhan 	free(hard_out);
579495c8ff4SLin Jinhan 	free(e_tmp);
580495c8ff4SLin Jinhan 	printf("%s %s test error!\n",
581495c8ff4SLin Jinhan 	       test_data->algo_name, test_data->mode_name);
58280ca1a53SLin Jinhan 	return ret;
58380ca1a53SLin Jinhan }
58480ca1a53SLin Jinhan 
585495c8ff4SLin Jinhan static int test_all_result(void)
586495c8ff4SLin Jinhan {
587495c8ff4SLin Jinhan 	int ret = 0;
588495c8ff4SLin Jinhan 
589495c8ff4SLin Jinhan 	ret = test_hash_result();
590495c8ff4SLin Jinhan 	if (ret)
591495c8ff4SLin Jinhan 		goto exit;
592495c8ff4SLin Jinhan 
593495c8ff4SLin Jinhan 	ret = test_cipher_result();
594495c8ff4SLin Jinhan 	if (ret)
595495c8ff4SLin Jinhan 		goto exit;
596495c8ff4SLin Jinhan 
597495c8ff4SLin Jinhan 	ret = test_rsa_result();
598495c8ff4SLin Jinhan 	if (ret)
599495c8ff4SLin Jinhan 		goto exit;
600495c8ff4SLin Jinhan 
601495c8ff4SLin Jinhan exit:
602495c8ff4SLin Jinhan 	return 0;
603495c8ff4SLin Jinhan }
604495c8ff4SLin Jinhan 
605cc6ac5d6SJoseph Chen static int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
606cc6ac5d6SJoseph Chen {
607495c8ff4SLin Jinhan 	return test_all_result();
608cc6ac5d6SJoseph Chen }
609cc6ac5d6SJoseph Chen 
610cc6ac5d6SJoseph Chen U_BOOT_CMD(
611cc6ac5d6SJoseph Chen 	crypto, 1, 1, do_crypto,
612cc6ac5d6SJoseph Chen 	"crypto test",
613cc6ac5d6SJoseph Chen 	""
614cc6ac5d6SJoseph Chen );
615