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