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