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; 47*c781c41cSLin Jinhan const u8 *aad; 48*c781c41cSLin Jinhan u32 aad_len; 49*c781c41cSLin Jinhan const u8 *tag; 50*c781c41cSLin Jinhan u32 tag_len; 51cc6ac5d6SJoseph Chen }; 52cc6ac5d6SJoseph Chen 53495c8ff4SLin Jinhan struct rsa_test_data { 54495c8ff4SLin Jinhan const char *algo_name; 55495c8ff4SLin Jinhan const char *mode_name; 56495c8ff4SLin Jinhan u32 algo; 57495c8ff4SLin Jinhan const u8 *n; 58495c8ff4SLin Jinhan u32 n_len; 59495c8ff4SLin Jinhan const u8 *e; 60495c8ff4SLin Jinhan u32 e_len; 61495c8ff4SLin Jinhan const u8 *d; 62495c8ff4SLin Jinhan u32 d_len; 63495c8ff4SLin Jinhan const u8 *c; 64495c8ff4SLin Jinhan u32 c_len; 65495c8ff4SLin Jinhan const u8 *sign_in; 66495c8ff4SLin Jinhan u32 sign_in_len; 67495c8ff4SLin Jinhan const u8 *sign_out; 68495c8ff4SLin Jinhan u32 sign_out_len; 69cc6ac5d6SJoseph Chen }; 70cc6ac5d6SJoseph Chen 7165ac8e46SLin Jinhan #define IS_MAC_MODE(mode) ((mode) == RK_MODE_CBC_MAC || \ 7265ac8e46SLin Jinhan (mode) == RK_MODE_CMAC) 7365ac8e46SLin Jinhan 74*c781c41cSLin Jinhan #define IS_AE_MODE(mode) ((mode) == RK_MODE_CCM || \ 75*c781c41cSLin Jinhan (mode) == RK_MODE_GCM) 76495c8ff4SLin Jinhan #define HASH_TEST(algo_type, data_in, hash_val) {\ 77495c8ff4SLin Jinhan .algo_name = "HASH", \ 78495c8ff4SLin Jinhan .mode_name = #algo_type, \ 79495c8ff4SLin Jinhan .algo = CRYPTO_##algo_type, \ 80495c8ff4SLin Jinhan .data = (data_in),\ 81495c8ff4SLin Jinhan .data_len = sizeof(data_in), \ 82495c8ff4SLin Jinhan .hash = (hash_val), \ 83495c8ff4SLin Jinhan .hash_len = sizeof(hash_val) \ 84cc6ac5d6SJoseph Chen } 85cc6ac5d6SJoseph Chen 86495c8ff4SLin Jinhan #define HMAC_TEST(algo_type, data_in, hash_val, hmac_key) {\ 87495c8ff4SLin Jinhan .algo_name = "HMAC", \ 88495c8ff4SLin Jinhan .mode_name = #algo_type, \ 89495c8ff4SLin Jinhan .algo = CRYPTO_HMAC_##algo_type, \ 90495c8ff4SLin Jinhan .data = (data_in),\ 91495c8ff4SLin Jinhan .data_len = sizeof(data_in), \ 92495c8ff4SLin Jinhan .hash = (hash_val), \ 93495c8ff4SLin Jinhan .hash_len = sizeof(hash_val), \ 94495c8ff4SLin Jinhan .key = (hmac_key), \ 95495c8ff4SLin Jinhan .key_len = sizeof(hmac_key)\ 96495c8ff4SLin Jinhan } 97495c8ff4SLin Jinhan 98495c8ff4SLin Jinhan #define CIPHER_XTS_TEST(algo_type, mode_type, key1, key2, iv_val, in, out) { \ 99495c8ff4SLin Jinhan .algo_name = #algo_type, \ 100495c8ff4SLin Jinhan .mode_name = #mode_type, \ 101495c8ff4SLin Jinhan .algo = CRYPTO_##algo_type,\ 102495c8ff4SLin Jinhan .mode = RK_MODE_##mode_type, \ 103495c8ff4SLin Jinhan .key = (key1), \ 104495c8ff4SLin Jinhan .twk_key = (key2), \ 105495c8ff4SLin Jinhan .key_len = sizeof(key1), \ 106495c8ff4SLin Jinhan .iv = (iv_val), \ 107495c8ff4SLin Jinhan .iv_len = sizeof(iv_val), \ 108495c8ff4SLin Jinhan .plain = (in), \ 109495c8ff4SLin Jinhan .plain_len = sizeof(in), \ 110495c8ff4SLin Jinhan .cipher = (out), \ 111495c8ff4SLin Jinhan .cipher_len = sizeof(out) \ 112495c8ff4SLin Jinhan } 113495c8ff4SLin Jinhan 114495c8ff4SLin Jinhan #define CIPHER_TEST(algo, mode, key, iv, plain, cipher) \ 115495c8ff4SLin Jinhan CIPHER_XTS_TEST(algo, mode, key, NULL, iv, plain, cipher) 116495c8ff4SLin Jinhan 117*c781c41cSLin Jinhan #define CIPHER_AE_TEST(algo_type, mode_type, key_val, iv_val, \ 118*c781c41cSLin Jinhan in, out, aad_val, tag_val) { \ 119*c781c41cSLin Jinhan .algo_name = #algo_type, \ 120*c781c41cSLin Jinhan .mode_name = #mode_type, \ 121*c781c41cSLin Jinhan .algo = CRYPTO_##algo_type,\ 122*c781c41cSLin Jinhan .mode = RK_MODE_##mode_type, \ 123*c781c41cSLin Jinhan .key = (key_val), \ 124*c781c41cSLin Jinhan .key_len = sizeof(key_val), \ 125*c781c41cSLin Jinhan .iv = (iv_val), \ 126*c781c41cSLin Jinhan .iv_len = sizeof(iv_val), \ 127*c781c41cSLin Jinhan .plain = (in), \ 128*c781c41cSLin Jinhan .plain_len = sizeof(in), \ 129*c781c41cSLin Jinhan .cipher = (out), \ 130*c781c41cSLin Jinhan .cipher_len = sizeof(out), \ 131*c781c41cSLin Jinhan .aad = (aad_val), \ 132*c781c41cSLin Jinhan .aad_len = sizeof(aad_val), \ 133*c781c41cSLin Jinhan .tag = (tag_val), \ 134*c781c41cSLin Jinhan .tag_len = sizeof(tag_val), \ 135*c781c41cSLin Jinhan } 136*c781c41cSLin Jinhan 137495c8ff4SLin Jinhan #define RSA_TEST(nbits, bn, be, bc, bd, in, out) { \ 138495c8ff4SLin Jinhan .algo_name = "RSA", \ 139495c8ff4SLin Jinhan .mode_name = #nbits, \ 140495c8ff4SLin Jinhan .algo = CRYPTO_RSA##nbits, \ 141495c8ff4SLin Jinhan .n = (bn), \ 142495c8ff4SLin Jinhan .n_len = sizeof(bn), \ 143495c8ff4SLin Jinhan .e = (be), \ 144495c8ff4SLin Jinhan .e_len = sizeof(be), \ 145495c8ff4SLin Jinhan .d = (bd), \ 146495c8ff4SLin Jinhan .d_len = sizeof(bd), \ 147495c8ff4SLin Jinhan .c = (bc), \ 148495c8ff4SLin Jinhan .c_len = sizeof(bc), \ 149495c8ff4SLin Jinhan .sign_in = (in), \ 150495c8ff4SLin Jinhan .sign_in_len = sizeof(in), \ 151495c8ff4SLin Jinhan .sign_out = (out), \ 152495c8ff4SLin Jinhan .sign_out_len = sizeof(out) \ 153495c8ff4SLin Jinhan } 154495c8ff4SLin Jinhan 155495c8ff4SLin Jinhan #define EMPTY_TEST() {} 156495c8ff4SLin Jinhan 157495c8ff4SLin Jinhan const struct hash_test_data hash_data_set[] = { 158495c8ff4SLin Jinhan HASH_TEST(MD5, foo_data, hash_md5), 159495c8ff4SLin Jinhan HASH_TEST(SHA1, foo_data, hash_sha1), 160495c8ff4SLin Jinhan HASH_TEST(SHA256, foo_data, hash_sha256), 161495c8ff4SLin Jinhan HASH_TEST(SHA512, foo_data, hash_sha512), 162495c8ff4SLin Jinhan HASH_TEST(SM3, foo_data, hash_sm3), 163495c8ff4SLin Jinhan 164495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 165495c8ff4SLin Jinhan EMPTY_TEST(), 166495c8ff4SLin Jinhan HMAC_TEST(MD5, foo_data, hmac_md5, hmac_key), 167495c8ff4SLin Jinhan HMAC_TEST(SHA1, foo_data, hmac_sha1, hmac_key), 168495c8ff4SLin Jinhan HMAC_TEST(SHA256, foo_data, hmac_sha256, hmac_key), 169495c8ff4SLin Jinhan HMAC_TEST(SHA512, foo_data, hmac_sha512, hmac_key), 170495c8ff4SLin Jinhan HMAC_TEST(SM3, foo_data, hmac_sm3, hmac_key), 171495c8ff4SLin Jinhan #endif 172495c8ff4SLin Jinhan }; 173495c8ff4SLin Jinhan 174495c8ff4SLin Jinhan const struct cipher_test_data cipher_data_set[] = { 175495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 176495c8ff4SLin Jinhan CIPHER_TEST(DES, ECB, des_key, des_iv, foo_data, des_ecb_cipher), 177495c8ff4SLin Jinhan CIPHER_TEST(DES, CBC, des_key, des_iv, foo_data, des_cbc_cipher), 178495c8ff4SLin Jinhan CIPHER_TEST(DES, CFB, des_key, des_iv, foo_data, des_cfb_cipher), 179495c8ff4SLin Jinhan CIPHER_TEST(DES, OFB, des_key, des_iv, foo_data, des_ofb_cipher), 180495c8ff4SLin Jinhan 181495c8ff4SLin Jinhan EMPTY_TEST(), 182495c8ff4SLin Jinhan CIPHER_TEST(DES, ECB, tdes_key, tdes_iv, foo_data, tdes_ecb_cipher), 183495c8ff4SLin Jinhan CIPHER_TEST(DES, CBC, tdes_key, tdes_iv, foo_data, tdes_cbc_cipher), 184495c8ff4SLin Jinhan CIPHER_TEST(DES, CFB, tdes_key, tdes_iv, foo_data, tdes_cfb_cipher), 185495c8ff4SLin Jinhan CIPHER_TEST(DES, OFB, tdes_key, tdes_iv, foo_data, tdes_ofb_cipher), 186495c8ff4SLin Jinhan 187495c8ff4SLin Jinhan EMPTY_TEST(), 188495c8ff4SLin Jinhan CIPHER_TEST(AES, ECB, aes_key, aes_iv, foo_data, aes_ecb_cipher), 189495c8ff4SLin Jinhan CIPHER_TEST(AES, CBC, aes_key, aes_iv, foo_data, aes_cbc_cipher), 190495c8ff4SLin Jinhan CIPHER_TEST(AES, CFB, aes_key, aes_iv, foo_data, aes_cfb_cipher), 191495c8ff4SLin Jinhan CIPHER_TEST(AES, OFB, aes_key, aes_iv, foo_data, aes_ofb_cipher), 192495c8ff4SLin Jinhan CIPHER_TEST(AES, CTS, aes_key, aes_iv, foo_data, aes_cts_cipher), 193495c8ff4SLin Jinhan CIPHER_TEST(AES, CTR, aes_key, aes_iv, foo_data, aes_ctr_cipher), 194495c8ff4SLin Jinhan CIPHER_XTS_TEST(AES, XTS, aes_key, aes_twk_key, 195495c8ff4SLin Jinhan aes_iv, foo_data, aes_xts_cipher), 19665ac8e46SLin Jinhan CIPHER_TEST(AES, CBC_MAC, aes_key, aes_iv, foo_data, aes_cbc_mac), 19765ac8e46SLin Jinhan CIPHER_TEST(AES, CMAC, aes_key, aes_iv, foo_data, aes_cmac), 198*c781c41cSLin Jinhan CIPHER_AE_TEST(AES, CCM, aes_key, aes_ccm_iv, foo_data, aes_ccm_cipher, 199*c781c41cSLin Jinhan ad_data, aes_ccm_tag), 200*c781c41cSLin Jinhan CIPHER_AE_TEST(AES, GCM, aes_key, aes_iv, foo_data, aes_gcm_cipher, 201*c781c41cSLin Jinhan ad_data, aes_gcm_tag), 202495c8ff4SLin Jinhan 203495c8ff4SLin Jinhan EMPTY_TEST(), 204495c8ff4SLin Jinhan CIPHER_TEST(SM4, ECB, sm4_key, sm4_iv, foo_data, sm4_ecb_cipher), 205495c8ff4SLin Jinhan CIPHER_TEST(SM4, CBC, sm4_key, sm4_iv, foo_data, sm4_cbc_cipher), 206495c8ff4SLin Jinhan CIPHER_TEST(SM4, CFB, sm4_key, sm4_iv, foo_data, sm4_cfb_cipher), 207495c8ff4SLin Jinhan CIPHER_TEST(SM4, OFB, sm4_key, sm4_iv, foo_data, sm4_ofb_cipher), 208495c8ff4SLin Jinhan CIPHER_TEST(SM4, CTS, sm4_key, sm4_iv, foo_data, sm4_cts_cipher), 209495c8ff4SLin Jinhan CIPHER_TEST(SM4, CTR, sm4_key, sm4_iv, foo_data, sm4_ctr_cipher), 210495c8ff4SLin Jinhan CIPHER_XTS_TEST(SM4, XTS, sm4_key, sm4_twk_key, 211495c8ff4SLin Jinhan sm4_iv, foo_data, sm4_xts_cipher), 21265ac8e46SLin Jinhan CIPHER_TEST(SM4, CBC_MAC, sm4_key, sm4_iv, foo_data, sm4_cbc_mac), 21365ac8e46SLin Jinhan CIPHER_TEST(SM4, CMAC, sm4_key, sm4_iv, foo_data, sm4_cmac), 214*c781c41cSLin Jinhan CIPHER_AE_TEST(SM4, CCM, sm4_key, sm4_ccm_iv, foo_data, sm4_ccm_cipher, 215*c781c41cSLin Jinhan ad_data, sm4_ccm_tag), 216*c781c41cSLin Jinhan CIPHER_AE_TEST(SM4, GCM, sm4_key, sm4_iv, foo_data, sm4_gcm_cipher, 217*c781c41cSLin Jinhan ad_data, sm4_gcm_tag), 218495c8ff4SLin Jinhan #else 219495c8ff4SLin Jinhan EMPTY_TEST(), 220495c8ff4SLin Jinhan #endif 221495c8ff4SLin Jinhan }; 222495c8ff4SLin Jinhan 223495c8ff4SLin Jinhan const struct rsa_test_data rsa_data_set[] = { 224495c8ff4SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 225415ed02bSLin Jinhan 226415ed02bSLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1 227495c8ff4SLin Jinhan RSA_TEST(2048, rsa2048_n, rsa2048_e, rsa2048_c, rsa2048_d, 228495c8ff4SLin Jinhan rsa2048_sign_in, rsa2048_sign_out), 229495c8ff4SLin Jinhan #else 230415ed02bSLin Jinhan RSA_TEST(4096, rsa4096_n, rsa4096_e, NULL, rsa4096_d, 231415ed02bSLin Jinhan rsa4096_sign_in, rsa4096_sign_out), 232415ed02bSLin Jinhan #endif 233415ed02bSLin Jinhan 234415ed02bSLin Jinhan #else 235495c8ff4SLin Jinhan EMPTY_TEST(), 236495c8ff4SLin Jinhan #endif 237495c8ff4SLin Jinhan }; 238495c8ff4SLin Jinhan 239495c8ff4SLin Jinhan static void dump_hex(const char *name, const u8 *array, u32 len) 24080ca1a53SLin Jinhan { 241495c8ff4SLin Jinhan int i; 242495c8ff4SLin Jinhan 243495c8ff4SLin Jinhan printf("[%s]: %uByte", name, len); 244495c8ff4SLin Jinhan for (i = 0; i < len; i++) { 245495c8ff4SLin Jinhan if (i % 32 == 0) 246495c8ff4SLin Jinhan printf("\n"); 247495c8ff4SLin Jinhan printf("%02x ", array[i]); 248495c8ff4SLin Jinhan } 249495c8ff4SLin Jinhan printf("\n"); 250495c8ff4SLin Jinhan } 251495c8ff4SLin Jinhan 252415ed02bSLin Jinhan static inline void print_result_MBps(const char *algo_name, 253415ed02bSLin Jinhan const char *mode_name, 254415ed02bSLin Jinhan const char *crypt, ulong MBps, 255415ed02bSLin Jinhan const u8 *expect, const u8 *actual, 256415ed02bSLin Jinhan u32 len) 257495c8ff4SLin Jinhan { 258495c8ff4SLin Jinhan if (memcmp(expect, actual, len) == 0) { 259415ed02bSLin Jinhan printf("[%s] %-8s%-8s PASS (%luMBps)\n", 260415ed02bSLin Jinhan algo_name, mode_name, crypt, MBps); 261495c8ff4SLin Jinhan } else { 262495c8ff4SLin Jinhan printf("[%s] %-8s%-8s FAIL\n", 263495c8ff4SLin Jinhan algo_name, mode_name, crypt); 264495c8ff4SLin Jinhan dump_hex("expect", expect, len); 265495c8ff4SLin Jinhan dump_hex("actual", actual, len); 266495c8ff4SLin Jinhan } 267495c8ff4SLin Jinhan } 268495c8ff4SLin Jinhan 269415ed02bSLin Jinhan static inline void print_result_ms(const char *algo_name, const char *mode_name, 270415ed02bSLin Jinhan const char *crypt, ulong time_cost, 271415ed02bSLin Jinhan const u8 *expect, const u8 *actual, u32 len) 272415ed02bSLin Jinhan { 273415ed02bSLin Jinhan if (memcmp(expect, actual, len) == 0) { 274415ed02bSLin Jinhan printf("[%s] %-8s%-8s PASS (%lums)\n", 275415ed02bSLin Jinhan algo_name, mode_name, crypt, time_cost); 276415ed02bSLin Jinhan } else { 277415ed02bSLin Jinhan printf("[%s] %-8s%-8s FAIL\n", 278415ed02bSLin Jinhan algo_name, mode_name, crypt); 279415ed02bSLin Jinhan dump_hex("expect", expect, len); 280415ed02bSLin Jinhan dump_hex("actual", actual, len); 281415ed02bSLin Jinhan } 282415ed02bSLin Jinhan } 283415ed02bSLin Jinhan 284415ed02bSLin Jinhan int test_hash_perf(struct udevice *dev, u32 algo, 285415ed02bSLin Jinhan const u8 *key, u32 key_len, ulong *MBps) 286415ed02bSLin Jinhan { 287415ed02bSLin Jinhan u32 total_size = PERF_TOTAL_SIZE; 288415ed02bSLin Jinhan u32 data_size = PERF_BUFF_SIZE; 289415ed02bSLin Jinhan sha_context ctx; 290415ed02bSLin Jinhan u8 *data = NULL; 291415ed02bSLin Jinhan u8 hash_out[64]; 292415ed02bSLin Jinhan int ret, i; 293415ed02bSLin Jinhan 294415ed02bSLin Jinhan *MBps = 0; 295415ed02bSLin Jinhan 296415ed02bSLin Jinhan ctx.algo = algo; 297415ed02bSLin Jinhan ctx.length = total_size; 298415ed02bSLin Jinhan 299415ed02bSLin Jinhan data = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 300415ed02bSLin Jinhan if (!data) { 301415ed02bSLin Jinhan printf("%s, %d: memalign %u error!\n", 302415ed02bSLin Jinhan __func__, __LINE__, data_size); 303415ed02bSLin Jinhan return -EINVAL; 304415ed02bSLin Jinhan } 305415ed02bSLin Jinhan 306415ed02bSLin Jinhan memset(data, 0xab, data_size); 307415ed02bSLin Jinhan 308415ed02bSLin Jinhan ulong start = get_timer(0); 309415ed02bSLin Jinhan 310415ed02bSLin Jinhan if (key) 311415ed02bSLin Jinhan ret = crypto_hmac_init(dev, &ctx, (u8 *)key, key_len); 312415ed02bSLin Jinhan else 313415ed02bSLin Jinhan ret = crypto_sha_init(dev, &ctx); 314415ed02bSLin Jinhan 315415ed02bSLin Jinhan if (ret) { 316415ed02bSLin Jinhan printf("crypto_sha_init error ret = %d!\n", ret); 317415ed02bSLin Jinhan goto exit; 318415ed02bSLin Jinhan } 319415ed02bSLin Jinhan 320415ed02bSLin Jinhan for (i = 0; i < total_size / data_size; i++) { 321415ed02bSLin Jinhan ret = crypto_sha_update(dev, (u32 *)data, data_size); 322415ed02bSLin Jinhan if (ret) { 323415ed02bSLin Jinhan printf("crypto_sha_update error!\n"); 324415ed02bSLin Jinhan goto exit; 325415ed02bSLin Jinhan } 326415ed02bSLin Jinhan } 327415ed02bSLin Jinhan 328415ed02bSLin Jinhan ret = crypto_sha_final(dev, &ctx, hash_out); 329415ed02bSLin Jinhan if (ret) { 330415ed02bSLin Jinhan printf("crypto_sha_final error ret = %d!\n", ret); 331415ed02bSLin Jinhan goto exit; 332415ed02bSLin Jinhan } 333415ed02bSLin Jinhan 334415ed02bSLin Jinhan ulong time_cost = get_timer(start); 335415ed02bSLin Jinhan 336415ed02bSLin Jinhan *MBps = CALC_RATE_MPBS(total_size, time_cost); 337415ed02bSLin Jinhan 338415ed02bSLin Jinhan exit: 339415ed02bSLin Jinhan free(data); 340415ed02bSLin Jinhan 341415ed02bSLin Jinhan return ret; 342415ed02bSLin Jinhan } 343415ed02bSLin Jinhan 344415ed02bSLin Jinhan int test_cipher_perf(struct udevice *dev, cipher_context *ctx, 345415ed02bSLin Jinhan ulong *MBps, bool enc) 346415ed02bSLin Jinhan { 347415ed02bSLin Jinhan u32 total_size = PERF_TOTAL_SIZE; 348415ed02bSLin Jinhan u32 data_size = PERF_BUFF_SIZE; 349415ed02bSLin Jinhan u8 *plain = NULL, *cipher = NULL; 350*c781c41cSLin Jinhan u8 aad[128], tag[16]; 35165ac8e46SLin Jinhan int ret = 0, i; 352415ed02bSLin Jinhan 353415ed02bSLin Jinhan *MBps = 0; 354415ed02bSLin Jinhan 355415ed02bSLin Jinhan plain = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 356415ed02bSLin Jinhan if (!plain) { 357415ed02bSLin Jinhan printf("%s, %d: memalign %u error!\n", 358415ed02bSLin Jinhan __func__, __LINE__, data_size); 359415ed02bSLin Jinhan return -EINVAL; 360415ed02bSLin Jinhan } 361415ed02bSLin Jinhan 362415ed02bSLin Jinhan cipher = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 363415ed02bSLin Jinhan if (!cipher) { 364415ed02bSLin Jinhan printf("%s, %d: memalign %u error!\n", 365415ed02bSLin Jinhan __func__, __LINE__, data_size); 366415ed02bSLin Jinhan free(plain); 367415ed02bSLin Jinhan return -EINVAL; 368415ed02bSLin Jinhan } 369415ed02bSLin Jinhan 370415ed02bSLin Jinhan memset(plain, 0xab, data_size); 371*c781c41cSLin Jinhan memset(aad, 0xcb, sizeof(aad)); 372415ed02bSLin Jinhan 373415ed02bSLin Jinhan ulong start = get_timer(0); 374415ed02bSLin Jinhan 375415ed02bSLin Jinhan for (i = 0; i < total_size / data_size; i++) { 37665ac8e46SLin Jinhan if (IS_MAC_MODE(ctx->mode)) 37765ac8e46SLin Jinhan ret = crypto_mac(dev, ctx, plain, data_size, cipher); 378*c781c41cSLin Jinhan else if (IS_AE_MODE(ctx->mode)) 379*c781c41cSLin Jinhan ret = crypto_ae(dev, ctx, plain, data_size, 380*c781c41cSLin Jinhan aad, sizeof(aad), cipher, tag); 38165ac8e46SLin Jinhan else 38265ac8e46SLin Jinhan ret = crypto_cipher(dev, ctx, plain, cipher, 38365ac8e46SLin Jinhan data_size, enc); 384415ed02bSLin Jinhan if (ret) { 385*c781c41cSLin Jinhan printf("%s, %d:crypto calc error! ret = %d\n", 38665ac8e46SLin Jinhan __func__, __LINE__, ret); 387415ed02bSLin Jinhan goto exit; 388415ed02bSLin Jinhan } 389415ed02bSLin Jinhan } 390415ed02bSLin Jinhan 391415ed02bSLin Jinhan ulong time_cost = get_timer(start); 392415ed02bSLin Jinhan 393415ed02bSLin Jinhan *MBps = CALC_RATE_MPBS(total_size, time_cost); 394415ed02bSLin Jinhan exit: 395415ed02bSLin Jinhan free(plain); 396415ed02bSLin Jinhan free(cipher); 397415ed02bSLin Jinhan 398415ed02bSLin Jinhan return ret; 399415ed02bSLin Jinhan } 400415ed02bSLin Jinhan 401495c8ff4SLin Jinhan int test_hash_result(void) 402495c8ff4SLin Jinhan { 403495c8ff4SLin Jinhan const struct hash_test_data *test_data = NULL; 404495c8ff4SLin Jinhan sha_context csha_ctx; 405495c8ff4SLin Jinhan struct udevice *dev; 406495c8ff4SLin Jinhan unsigned int i; 407495c8ff4SLin Jinhan u8 out[64]; 40880ca1a53SLin Jinhan int ret; 40980ca1a53SLin Jinhan 410495c8ff4SLin Jinhan printf("\n=================== hash & hmac test ===================\n"); 41180ca1a53SLin Jinhan 412495c8ff4SLin Jinhan for (i = 0; i < ARRAY_SIZE(hash_data_set); i++) { 413495c8ff4SLin Jinhan test_data = &hash_data_set[i]; 414495c8ff4SLin Jinhan if (test_data->algo == 0) { 415495c8ff4SLin Jinhan printf("\n"); 416495c8ff4SLin Jinhan continue; 417495c8ff4SLin Jinhan } 418495c8ff4SLin Jinhan 419495c8ff4SLin Jinhan dev = crypto_get_device(test_data->algo); 420495c8ff4SLin Jinhan if (!dev) { 421495c8ff4SLin Jinhan printf("[%s] %-16s unsupported!!!\n", 422495c8ff4SLin Jinhan test_data->algo_name, 423495c8ff4SLin Jinhan test_data->mode_name); 424495c8ff4SLin Jinhan continue; 425495c8ff4SLin Jinhan } 426495c8ff4SLin Jinhan 427495c8ff4SLin Jinhan csha_ctx.algo = test_data->algo; 428495c8ff4SLin Jinhan csha_ctx.length = test_data->data_len; 429495c8ff4SLin Jinhan 430495c8ff4SLin Jinhan memset(out, 0x00, sizeof(out)); 431495c8ff4SLin Jinhan if (test_data->key) { 432495c8ff4SLin Jinhan ret = crypto_hmac_init(dev, &csha_ctx, 433495c8ff4SLin Jinhan (u8 *)test_data->key, 434495c8ff4SLin Jinhan test_data->key_len); 435495c8ff4SLin Jinhan ret |= crypto_hmac_update(dev, (void *)test_data->data, 436495c8ff4SLin Jinhan test_data->data_len); 437495c8ff4SLin Jinhan ret |= crypto_hmac_final(dev, &csha_ctx, out); 438495c8ff4SLin Jinhan if (ret) { 439495c8ff4SLin Jinhan printf("hmac calc error ret = %d\n", ret); 440495c8ff4SLin Jinhan goto error; 441495c8ff4SLin Jinhan } 442495c8ff4SLin Jinhan } else { 443495c8ff4SLin Jinhan ret = crypto_sha_init(dev, &csha_ctx); 444495c8ff4SLin Jinhan ret |= crypto_sha_update(dev, (void *)test_data->data, 445495c8ff4SLin Jinhan test_data->data_len); 446495c8ff4SLin Jinhan ret |= crypto_sha_final(dev, &csha_ctx, out); 447495c8ff4SLin Jinhan if (ret) { 448495c8ff4SLin Jinhan printf("hash calc error ret = %d\n", ret); 449495c8ff4SLin Jinhan goto error; 450495c8ff4SLin Jinhan } 451495c8ff4SLin Jinhan } 452495c8ff4SLin Jinhan 453415ed02bSLin Jinhan ulong MBps = 0; 454415ed02bSLin Jinhan 455415ed02bSLin Jinhan test_hash_perf(dev, test_data->algo, 456415ed02bSLin Jinhan test_data->key, test_data->key_len, &MBps); 457415ed02bSLin Jinhan print_result_MBps(test_data->algo_name, test_data->mode_name, 458415ed02bSLin Jinhan "", MBps, test_data->hash, out, 459415ed02bSLin Jinhan test_data->hash_len); 460495c8ff4SLin Jinhan printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 461495c8ff4SLin Jinhan } 462495c8ff4SLin Jinhan 463495c8ff4SLin Jinhan return 0; 464495c8ff4SLin Jinhan error: 465495c8ff4SLin Jinhan printf("%s %s test error!\n", 466495c8ff4SLin Jinhan test_data->algo_name, test_data->mode_name); 467495c8ff4SLin Jinhan return ret; 468495c8ff4SLin Jinhan } 469495c8ff4SLin Jinhan 470495c8ff4SLin Jinhan int test_cipher_result(void) 471495c8ff4SLin Jinhan { 472495c8ff4SLin Jinhan const struct cipher_test_data *test_data = NULL; 473495c8ff4SLin Jinhan struct udevice *dev; 474495c8ff4SLin Jinhan cipher_context ctx; 475*c781c41cSLin Jinhan u8 out[256], tag[16]; 476495c8ff4SLin Jinhan int ret; 477495c8ff4SLin Jinhan u32 i; 478495c8ff4SLin Jinhan 479495c8ff4SLin Jinhan printf("\n===================== cipher test ======================\n"); 480495c8ff4SLin Jinhan 481495c8ff4SLin Jinhan for (i = 0; i < ARRAY_SIZE(cipher_data_set); i++) { 482495c8ff4SLin Jinhan test_data = &cipher_data_set[i]; 483495c8ff4SLin Jinhan if (test_data->algo == 0) { 484495c8ff4SLin Jinhan printf("\n"); 485495c8ff4SLin Jinhan continue; 486495c8ff4SLin Jinhan } 487495c8ff4SLin Jinhan 488495c8ff4SLin Jinhan dev = crypto_get_device(test_data->algo); 489495c8ff4SLin Jinhan if (!dev) { 490495c8ff4SLin Jinhan printf("[%s] %-16s unsupported!!!\n", 491495c8ff4SLin Jinhan test_data->algo_name, test_data->mode_name); 492495c8ff4SLin Jinhan continue; 493495c8ff4SLin Jinhan } 494495c8ff4SLin Jinhan 495495c8ff4SLin Jinhan memset(&ctx, 0x00, sizeof(ctx)); 496495c8ff4SLin Jinhan 497495c8ff4SLin Jinhan ctx.algo = test_data->algo; 498495c8ff4SLin Jinhan ctx.mode = test_data->mode; 499495c8ff4SLin Jinhan ctx.key = test_data->key; 500495c8ff4SLin Jinhan ctx.twk_key = test_data->twk_key; 501495c8ff4SLin Jinhan ctx.key_len = test_data->key_len; 502495c8ff4SLin Jinhan ctx.iv = test_data->iv; 503495c8ff4SLin Jinhan ctx.iv_len = test_data->iv_len; 504495c8ff4SLin Jinhan 505415ed02bSLin Jinhan ulong MBps = 0; 506415ed02bSLin Jinhan 507415ed02bSLin Jinhan test_cipher_perf(dev, &ctx, &MBps, true); 508415ed02bSLin Jinhan 50965ac8e46SLin Jinhan /* AES/SM4 mac */ 51065ac8e46SLin Jinhan if (IS_MAC_MODE(ctx.mode)) 51165ac8e46SLin Jinhan ret = crypto_mac(dev, &ctx, test_data->plain, 51265ac8e46SLin Jinhan test_data->plain_len, out); 513*c781c41cSLin Jinhan else if (IS_AE_MODE(ctx.mode)) 514*c781c41cSLin Jinhan ret = crypto_ae(dev, &ctx, 515*c781c41cSLin Jinhan test_data->plain, test_data->plain_len, 516*c781c41cSLin Jinhan test_data->aad, test_data->aad_len, 517*c781c41cSLin Jinhan out, tag); 51865ac8e46SLin Jinhan else 519495c8ff4SLin Jinhan ret = crypto_cipher(dev, &ctx, test_data->plain, 520495c8ff4SLin Jinhan out, test_data->plain_len, true); 521495c8ff4SLin Jinhan if (ret) 522495c8ff4SLin Jinhan goto error; 523495c8ff4SLin Jinhan 524*c781c41cSLin Jinhan if (test_data->tag && 525*c781c41cSLin Jinhan memcmp(test_data->tag, tag, test_data->tag_len) != 0) { 526*c781c41cSLin Jinhan printf("tag mismatch!!!\n"); 527*c781c41cSLin Jinhan dump_hex("expect", test_data->tag, test_data->tag_len); 528*c781c41cSLin Jinhan dump_hex("actual", tag, test_data->tag_len); 529*c781c41cSLin Jinhan goto error; 530*c781c41cSLin Jinhan } 531*c781c41cSLin Jinhan 532415ed02bSLin Jinhan print_result_MBps(test_data->algo_name, test_data->mode_name, 533415ed02bSLin Jinhan "encrypt", MBps, test_data->cipher, out, 534495c8ff4SLin Jinhan test_data->cipher_len); 535495c8ff4SLin Jinhan 536*c781c41cSLin Jinhan if (!IS_MAC_MODE(ctx.mode) && !IS_AE_MODE(ctx.mode)) { 537415ed02bSLin Jinhan test_cipher_perf(dev, &ctx, &MBps, false); 538495c8ff4SLin Jinhan ret = crypto_cipher(dev, &ctx, test_data->cipher, 539495c8ff4SLin Jinhan out, test_data->cipher_len, false); 540495c8ff4SLin Jinhan if (ret) 541495c8ff4SLin Jinhan goto error; 542495c8ff4SLin Jinhan 54365ac8e46SLin Jinhan print_result_MBps(test_data->algo_name, 54465ac8e46SLin Jinhan test_data->mode_name, 54565ac8e46SLin Jinhan "decrypt", MBps, 54665ac8e46SLin Jinhan test_data->plain, out, 547495c8ff4SLin Jinhan test_data->plain_len); 54865ac8e46SLin Jinhan } 549495c8ff4SLin Jinhan printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 550495c8ff4SLin Jinhan } 551495c8ff4SLin Jinhan return 0; 552495c8ff4SLin Jinhan error: 55365ac8e46SLin Jinhan printf("%s %s test error, ret = %d!\n", 55465ac8e46SLin Jinhan test_data->algo_name, test_data->mode_name, ret); 555495c8ff4SLin Jinhan return ret; 556495c8ff4SLin Jinhan } 557495c8ff4SLin Jinhan 558495c8ff4SLin Jinhan int test_rsa_result(void) 559495c8ff4SLin Jinhan { 560495c8ff4SLin Jinhan const struct rsa_test_data *test_data = NULL; 561495c8ff4SLin Jinhan u8 *hard_out = NULL, *e_tmp; 562495c8ff4SLin Jinhan u32 data_size = 4096 / 8; 563415ed02bSLin Jinhan ulong start, time_cost; 564495c8ff4SLin Jinhan struct udevice *dev; 565495c8ff4SLin Jinhan rsa_key rsa_key; 566495c8ff4SLin Jinhan int ret, i; 567495c8ff4SLin Jinhan 568495c8ff4SLin Jinhan hard_out = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 569495c8ff4SLin Jinhan if (!hard_out) { 57080ca1a53SLin Jinhan printf("%s, %d: memalign %u error!\n", 57180ca1a53SLin Jinhan __func__, __LINE__, data_size); 57280ca1a53SLin Jinhan return -EINVAL; 57380ca1a53SLin Jinhan } 57480ca1a53SLin Jinhan 575495c8ff4SLin Jinhan e_tmp = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 576495c8ff4SLin Jinhan if (!e_tmp) { 577495c8ff4SLin Jinhan printf("%s, %d: memalign %u error!\n", 578495c8ff4SLin Jinhan __func__, __LINE__, data_size); 579495c8ff4SLin Jinhan return -EINVAL; 58080ca1a53SLin Jinhan } 58180ca1a53SLin Jinhan 582495c8ff4SLin Jinhan printf("\n====================== rsa test ========================\n"); 583495c8ff4SLin Jinhan for (i = 0; i < ARRAY_SIZE(rsa_data_set); i++) { 584495c8ff4SLin Jinhan test_data = &rsa_data_set[i]; 585495c8ff4SLin Jinhan if (test_data->algo == 0) { 586495c8ff4SLin Jinhan printf("\n"); 587495c8ff4SLin Jinhan continue; 588495c8ff4SLin Jinhan } 58980ca1a53SLin Jinhan 590495c8ff4SLin Jinhan dev = crypto_get_device(test_data->algo); 591495c8ff4SLin Jinhan if (!dev) { 592495c8ff4SLin Jinhan printf("[%s] %-16s unsupported!!!\n", 593495c8ff4SLin Jinhan test_data->algo_name, test_data->mode_name); 594495c8ff4SLin Jinhan continue; 595495c8ff4SLin Jinhan } 59680ca1a53SLin Jinhan 597495c8ff4SLin Jinhan /* sign test */ 598495c8ff4SLin Jinhan memset(&rsa_key, 0x00, sizeof(rsa_key)); 599495c8ff4SLin Jinhan rsa_key.algo = test_data->algo; 600495c8ff4SLin Jinhan rsa_key.n = (u32 *)test_data->n; 601495c8ff4SLin Jinhan rsa_key.e = (u32 *)test_data->d; 602495c8ff4SLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1 603495c8ff4SLin Jinhan rsa_key.c = (u32 *)test_data->c; 604495c8ff4SLin Jinhan #endif 60580ca1a53SLin Jinhan 606415ed02bSLin Jinhan start = get_timer(0); 607495c8ff4SLin Jinhan ret = crypto_rsa_verify(dev, &rsa_key, 608495c8ff4SLin Jinhan (u8 *)test_data->sign_in, hard_out); 609495c8ff4SLin Jinhan if (ret) { 610495c8ff4SLin Jinhan printf("sign test error, ret = %d\n", ret); 611495c8ff4SLin Jinhan goto error; 612495c8ff4SLin Jinhan } 613415ed02bSLin Jinhan time_cost = get_timer(start); 614415ed02bSLin Jinhan print_result_ms(test_data->algo_name, test_data->mode_name, 615415ed02bSLin Jinhan "sign", time_cost, test_data->sign_out, 616495c8ff4SLin Jinhan hard_out, test_data->n_len); 617495c8ff4SLin Jinhan 618495c8ff4SLin Jinhan /* verify test */ 619495c8ff4SLin Jinhan memset(&rsa_key, 0x00, sizeof(rsa_key)); 620495c8ff4SLin Jinhan memset(e_tmp, 0x00, data_size); 621495c8ff4SLin Jinhan memcpy(e_tmp, test_data->e, test_data->e_len); 622495c8ff4SLin Jinhan rsa_key.algo = test_data->algo; 623495c8ff4SLin Jinhan rsa_key.n = (u32 *)test_data->n; 624495c8ff4SLin Jinhan rsa_key.e = (u32 *)e_tmp; 625495c8ff4SLin Jinhan #ifdef CONFIG_ROCKCHIP_CRYPTO_V1 626495c8ff4SLin Jinhan rsa_key.c = (u32 *)test_data->c; 627495c8ff4SLin Jinhan #endif 628495c8ff4SLin Jinhan 629415ed02bSLin Jinhan start = get_timer(0); 630495c8ff4SLin Jinhan ret = crypto_rsa_verify(dev, &rsa_key, 631495c8ff4SLin Jinhan (u8 *)test_data->sign_out, hard_out); 632495c8ff4SLin Jinhan if (ret) { 633495c8ff4SLin Jinhan printf("verify test error, ret = %d\n", ret); 634495c8ff4SLin Jinhan goto error; 635495c8ff4SLin Jinhan } 636415ed02bSLin Jinhan time_cost = get_timer(start); 637495c8ff4SLin Jinhan 638415ed02bSLin Jinhan print_result_ms(test_data->algo_name, test_data->mode_name, 639415ed02bSLin Jinhan "verify", time_cost, test_data->sign_in, 640495c8ff4SLin Jinhan hard_out, test_data->n_len); 641495c8ff4SLin Jinhan 642495c8ff4SLin Jinhan printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 643495c8ff4SLin Jinhan } 644495c8ff4SLin Jinhan 645495c8ff4SLin Jinhan free(hard_out); 646495c8ff4SLin Jinhan free(e_tmp); 647495c8ff4SLin Jinhan 648495c8ff4SLin Jinhan return 0; 649495c8ff4SLin Jinhan error: 650495c8ff4SLin Jinhan free(hard_out); 651495c8ff4SLin Jinhan free(e_tmp); 652495c8ff4SLin Jinhan printf("%s %s test error!\n", 653495c8ff4SLin Jinhan test_data->algo_name, test_data->mode_name); 65480ca1a53SLin Jinhan return ret; 65580ca1a53SLin Jinhan } 65680ca1a53SLin Jinhan 657495c8ff4SLin Jinhan static int test_all_result(void) 658495c8ff4SLin Jinhan { 659495c8ff4SLin Jinhan int ret = 0; 660495c8ff4SLin Jinhan 661495c8ff4SLin Jinhan ret = test_hash_result(); 662495c8ff4SLin Jinhan if (ret) 663495c8ff4SLin Jinhan goto exit; 664495c8ff4SLin Jinhan 665495c8ff4SLin Jinhan ret = test_cipher_result(); 666495c8ff4SLin Jinhan if (ret) 667495c8ff4SLin Jinhan goto exit; 668495c8ff4SLin Jinhan 669495c8ff4SLin Jinhan ret = test_rsa_result(); 670495c8ff4SLin Jinhan if (ret) 671495c8ff4SLin Jinhan goto exit; 672495c8ff4SLin Jinhan 673495c8ff4SLin Jinhan exit: 674495c8ff4SLin Jinhan return 0; 675495c8ff4SLin Jinhan } 676495c8ff4SLin Jinhan 677cc6ac5d6SJoseph Chen static int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 678cc6ac5d6SJoseph Chen { 679495c8ff4SLin Jinhan return test_all_result(); 680cc6ac5d6SJoseph Chen } 681cc6ac5d6SJoseph Chen 682cc6ac5d6SJoseph Chen U_BOOT_CMD( 683cc6ac5d6SJoseph Chen crypto, 1, 1, do_crypto, 684cc6ac5d6SJoseph Chen "crypto test", 685cc6ac5d6SJoseph Chen "" 686cc6ac5d6SJoseph Chen ); 687