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 struct hash_test_data { 17 const char *algo_name; 18 const char *mode_name; 19 u32 algo; 20 const u8 *data; 21 u32 data_len; 22 const u8 *hash; 23 u32 hash_len; 24 const u8 *key; 25 u32 key_len; 26 }; 27 28 struct cipher_test_data { 29 const char *algo_name; 30 const char *mode_name; 31 u32 algo; 32 u32 mode; 33 const u8 *key; 34 const u8 *twk_key; 35 u32 key_len; 36 const u8 *iv; 37 u32 iv_len; 38 const u8 *plain; 39 u32 plain_len; 40 const u8 *cipher; 41 u32 cipher_len; 42 }; 43 44 struct rsa_test_data { 45 const char *algo_name; 46 const char *mode_name; 47 u32 algo; 48 const u8 *n; 49 u32 n_len; 50 const u8 *e; 51 u32 e_len; 52 const u8 *d; 53 u32 d_len; 54 const u8 *c; 55 u32 c_len; 56 const u8 *sign_in; 57 u32 sign_in_len; 58 const u8 *sign_out; 59 u32 sign_out_len; 60 }; 61 62 #define HASH_TEST(algo_type, data_in, hash_val) {\ 63 .algo_name = "HASH", \ 64 .mode_name = #algo_type, \ 65 .algo = CRYPTO_##algo_type, \ 66 .data = (data_in),\ 67 .data_len = sizeof(data_in), \ 68 .hash = (hash_val), \ 69 .hash_len = sizeof(hash_val) \ 70 } 71 72 #define HMAC_TEST(algo_type, data_in, hash_val, hmac_key) {\ 73 .algo_name = "HMAC", \ 74 .mode_name = #algo_type, \ 75 .algo = CRYPTO_HMAC_##algo_type, \ 76 .data = (data_in),\ 77 .data_len = sizeof(data_in), \ 78 .hash = (hash_val), \ 79 .hash_len = sizeof(hash_val), \ 80 .key = (hmac_key), \ 81 .key_len = sizeof(hmac_key)\ 82 } 83 84 #define CIPHER_XTS_TEST(algo_type, mode_type, key1, key2, iv_val, in, out) { \ 85 .algo_name = #algo_type, \ 86 .mode_name = #mode_type, \ 87 .algo = CRYPTO_##algo_type,\ 88 .mode = RK_MODE_##mode_type, \ 89 .key = (key1), \ 90 .twk_key = (key2), \ 91 .key_len = sizeof(key1), \ 92 .iv = (iv_val), \ 93 .iv_len = sizeof(iv_val), \ 94 .plain = (in), \ 95 .plain_len = sizeof(in), \ 96 .cipher = (out), \ 97 .cipher_len = sizeof(out) \ 98 } 99 100 #define CIPHER_TEST(algo, mode, key, iv, plain, cipher) \ 101 CIPHER_XTS_TEST(algo, mode, key, NULL, iv, plain, cipher) 102 103 #define RSA_TEST(nbits, bn, be, bc, bd, in, out) { \ 104 .algo_name = "RSA", \ 105 .mode_name = #nbits, \ 106 .algo = CRYPTO_RSA##nbits, \ 107 .n = (bn), \ 108 .n_len = sizeof(bn), \ 109 .e = (be), \ 110 .e_len = sizeof(be), \ 111 .d = (bd), \ 112 .d_len = sizeof(bd), \ 113 .c = (bc), \ 114 .c_len = sizeof(bc), \ 115 .sign_in = (in), \ 116 .sign_in_len = sizeof(in), \ 117 .sign_out = (out), \ 118 .sign_out_len = sizeof(out) \ 119 } 120 121 #define EMPTY_TEST() {} 122 123 const struct hash_test_data hash_data_set[] = { 124 HASH_TEST(MD5, foo_data, hash_md5), 125 HASH_TEST(SHA1, foo_data, hash_sha1), 126 HASH_TEST(SHA256, foo_data, hash_sha256), 127 HASH_TEST(SHA512, foo_data, hash_sha512), 128 HASH_TEST(SM3, foo_data, hash_sm3), 129 130 #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 131 EMPTY_TEST(), 132 HMAC_TEST(MD5, foo_data, hmac_md5, hmac_key), 133 HMAC_TEST(SHA1, foo_data, hmac_sha1, hmac_key), 134 HMAC_TEST(SHA256, foo_data, hmac_sha256, hmac_key), 135 HMAC_TEST(SHA512, foo_data, hmac_sha512, hmac_key), 136 HMAC_TEST(SM3, foo_data, hmac_sm3, hmac_key), 137 #endif 138 }; 139 140 const struct cipher_test_data cipher_data_set[] = { 141 #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 142 CIPHER_TEST(DES, ECB, des_key, des_iv, foo_data, des_ecb_cipher), 143 CIPHER_TEST(DES, CBC, des_key, des_iv, foo_data, des_cbc_cipher), 144 CIPHER_TEST(DES, CFB, des_key, des_iv, foo_data, des_cfb_cipher), 145 CIPHER_TEST(DES, OFB, des_key, des_iv, foo_data, des_ofb_cipher), 146 147 EMPTY_TEST(), 148 CIPHER_TEST(DES, ECB, tdes_key, tdes_iv, foo_data, tdes_ecb_cipher), 149 CIPHER_TEST(DES, CBC, tdes_key, tdes_iv, foo_data, tdes_cbc_cipher), 150 CIPHER_TEST(DES, CFB, tdes_key, tdes_iv, foo_data, tdes_cfb_cipher), 151 CIPHER_TEST(DES, OFB, tdes_key, tdes_iv, foo_data, tdes_ofb_cipher), 152 153 EMPTY_TEST(), 154 CIPHER_TEST(AES, ECB, aes_key, aes_iv, foo_data, aes_ecb_cipher), 155 CIPHER_TEST(AES, CBC, aes_key, aes_iv, foo_data, aes_cbc_cipher), 156 CIPHER_TEST(AES, CFB, aes_key, aes_iv, foo_data, aes_cfb_cipher), 157 CIPHER_TEST(AES, OFB, aes_key, aes_iv, foo_data, aes_ofb_cipher), 158 CIPHER_TEST(AES, CTS, aes_key, aes_iv, foo_data, aes_cts_cipher), 159 CIPHER_TEST(AES, CTR, aes_key, aes_iv, foo_data, aes_ctr_cipher), 160 CIPHER_XTS_TEST(AES, XTS, aes_key, aes_twk_key, 161 aes_iv, foo_data, aes_xts_cipher), 162 163 EMPTY_TEST(), 164 CIPHER_TEST(SM4, ECB, sm4_key, sm4_iv, foo_data, sm4_ecb_cipher), 165 CIPHER_TEST(SM4, CBC, sm4_key, sm4_iv, foo_data, sm4_cbc_cipher), 166 CIPHER_TEST(SM4, CFB, sm4_key, sm4_iv, foo_data, sm4_cfb_cipher), 167 CIPHER_TEST(SM4, OFB, sm4_key, sm4_iv, foo_data, sm4_ofb_cipher), 168 CIPHER_TEST(SM4, CTS, sm4_key, sm4_iv, foo_data, sm4_cts_cipher), 169 CIPHER_TEST(SM4, CTR, sm4_key, sm4_iv, foo_data, sm4_ctr_cipher), 170 CIPHER_XTS_TEST(SM4, XTS, sm4_key, sm4_twk_key, 171 sm4_iv, foo_data, sm4_xts_cipher), 172 #else 173 EMPTY_TEST(), 174 #endif 175 }; 176 177 const struct rsa_test_data rsa_data_set[] = { 178 #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 179 RSA_TEST(2048, rsa2048_n, rsa2048_e, rsa2048_c, rsa2048_d, 180 rsa2048_sign_in, rsa2048_sign_out), 181 #else 182 EMPTY_TEST(), 183 #endif 184 }; 185 186 static void dump_hex(const char *name, const u8 *array, u32 len) 187 { 188 int i; 189 190 printf("[%s]: %uByte", name, len); 191 for (i = 0; i < len; i++) { 192 if (i % 32 == 0) 193 printf("\n"); 194 printf("%02x ", array[i]); 195 } 196 printf("\n"); 197 } 198 199 static inline void check_result(const char *algo_name, const char *mode_name, 200 const char *crypt, 201 const u8 *expect, const u8 *actual, u32 len) 202 { 203 if (memcmp(expect, actual, len) == 0) { 204 printf("[%s] %-8s%-8s PASS\n", 205 algo_name, mode_name, crypt); 206 } else { 207 printf("[%s] %-8s%-8s FAIL\n", 208 algo_name, mode_name, crypt); 209 dump_hex("expect", expect, len); 210 dump_hex("actual", actual, len); 211 } 212 } 213 214 int test_hash_result(void) 215 { 216 const struct hash_test_data *test_data = NULL; 217 sha_context csha_ctx; 218 struct udevice *dev; 219 unsigned int i; 220 u8 out[64]; 221 int ret; 222 223 printf("\n=================== hash & hmac test ===================\n"); 224 225 for (i = 0; i < ARRAY_SIZE(hash_data_set); i++) { 226 test_data = &hash_data_set[i]; 227 if (test_data->algo == 0) { 228 printf("\n"); 229 continue; 230 } 231 232 dev = crypto_get_device(test_data->algo); 233 if (!dev) { 234 printf("[%s] %-16s unsupported!!!\n", 235 test_data->algo_name, 236 test_data->mode_name); 237 continue; 238 } 239 240 csha_ctx.algo = test_data->algo; 241 csha_ctx.length = test_data->data_len; 242 243 memset(out, 0x00, sizeof(out)); 244 if (test_data->key) { 245 ret = crypto_hmac_init(dev, &csha_ctx, 246 (u8 *)test_data->key, 247 test_data->key_len); 248 ret |= crypto_hmac_update(dev, (void *)test_data->data, 249 test_data->data_len); 250 ret |= crypto_hmac_final(dev, &csha_ctx, out); 251 if (ret) { 252 printf("hmac calc error ret = %d\n", ret); 253 goto error; 254 } 255 } else { 256 ret = crypto_sha_init(dev, &csha_ctx); 257 ret |= crypto_sha_update(dev, (void *)test_data->data, 258 test_data->data_len); 259 ret |= crypto_sha_final(dev, &csha_ctx, out); 260 if (ret) { 261 printf("hash calc error ret = %d\n", ret); 262 goto error; 263 } 264 } 265 266 check_result(test_data->algo_name, test_data->mode_name, 267 "", test_data->hash, out, test_data->hash_len); 268 printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 269 } 270 271 return 0; 272 error: 273 printf("%s %s test error!\n", 274 test_data->algo_name, test_data->mode_name); 275 return ret; 276 } 277 278 int test_cipher_result(void) 279 { 280 const struct cipher_test_data *test_data = NULL; 281 struct udevice *dev; 282 cipher_context ctx; 283 u8 out[256]; 284 int ret; 285 u32 i; 286 287 printf("\n===================== cipher test ======================\n"); 288 289 for (i = 0; i < ARRAY_SIZE(cipher_data_set); i++) { 290 test_data = &cipher_data_set[i]; 291 if (test_data->algo == 0) { 292 printf("\n"); 293 continue; 294 } 295 296 dev = crypto_get_device(test_data->algo); 297 if (!dev) { 298 printf("[%s] %-16s unsupported!!!\n", 299 test_data->algo_name, test_data->mode_name); 300 continue; 301 } 302 303 memset(&ctx, 0x00, sizeof(ctx)); 304 305 ctx.algo = test_data->algo; 306 ctx.mode = test_data->mode; 307 ctx.key = test_data->key; 308 ctx.twk_key = test_data->twk_key; 309 ctx.key_len = test_data->key_len; 310 ctx.iv = test_data->iv; 311 ctx.iv_len = test_data->iv_len; 312 313 ret = crypto_cipher(dev, &ctx, test_data->plain, 314 out, test_data->plain_len, true); 315 if (ret) 316 goto error; 317 318 check_result(test_data->algo_name, test_data->mode_name, 319 "encrypt", test_data->cipher, out, 320 test_data->cipher_len); 321 322 ret = crypto_cipher(dev, &ctx, test_data->cipher, 323 out, test_data->cipher_len, false); 324 if (ret) 325 goto error; 326 327 check_result(test_data->algo_name, test_data->mode_name, 328 "decrypt", test_data->plain, out, 329 test_data->plain_len); 330 printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 331 } 332 return 0; 333 error: 334 printf("%s %s test error!\n", 335 test_data->algo_name, test_data->mode_name); 336 return ret; 337 } 338 339 int test_rsa_result(void) 340 { 341 const struct rsa_test_data *test_data = NULL; 342 u8 *hard_out = NULL, *e_tmp; 343 u32 data_size = 4096 / 8; 344 struct udevice *dev; 345 rsa_key rsa_key; 346 int ret, i; 347 348 hard_out = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 349 if (!hard_out) { 350 printf("%s, %d: memalign %u error!\n", 351 __func__, __LINE__, data_size); 352 return -EINVAL; 353 } 354 355 e_tmp = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size); 356 if (!e_tmp) { 357 printf("%s, %d: memalign %u error!\n", 358 __func__, __LINE__, data_size); 359 return -EINVAL; 360 } 361 362 printf("\n====================== rsa test ========================\n"); 363 for (i = 0; i < ARRAY_SIZE(rsa_data_set); i++) { 364 test_data = &rsa_data_set[i]; 365 if (test_data->algo == 0) { 366 printf("\n"); 367 continue; 368 } 369 370 dev = crypto_get_device(test_data->algo); 371 if (!dev) { 372 printf("[%s] %-16s unsupported!!!\n", 373 test_data->algo_name, test_data->mode_name); 374 continue; 375 } 376 377 /* sign test */ 378 memset(&rsa_key, 0x00, sizeof(rsa_key)); 379 rsa_key.algo = test_data->algo; 380 rsa_key.n = (u32 *)test_data->n; 381 rsa_key.e = (u32 *)test_data->d; 382 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1 383 rsa_key.c = (u32 *)test_data->c; 384 #endif 385 386 ret = crypto_rsa_verify(dev, &rsa_key, 387 (u8 *)test_data->sign_in, hard_out); 388 if (ret) { 389 printf("sign test error, ret = %d\n", ret); 390 goto error; 391 } 392 393 check_result(test_data->algo_name, test_data->mode_name, 394 "sign", test_data->sign_out, 395 hard_out, test_data->n_len); 396 397 /* verify test */ 398 memset(&rsa_key, 0x00, sizeof(rsa_key)); 399 memset(e_tmp, 0x00, data_size); 400 memcpy(e_tmp, test_data->e, test_data->e_len); 401 rsa_key.algo = test_data->algo; 402 rsa_key.n = (u32 *)test_data->n; 403 rsa_key.e = (u32 *)e_tmp; 404 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1 405 rsa_key.c = (u32 *)test_data->c; 406 #endif 407 408 ret = crypto_rsa_verify(dev, &rsa_key, 409 (u8 *)test_data->sign_out, hard_out); 410 if (ret) { 411 printf("verify test error, ret = %d\n", ret); 412 goto error; 413 } 414 415 check_result(test_data->algo_name, test_data->mode_name, 416 "verify", test_data->sign_in, 417 hard_out, test_data->n_len); 418 419 printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 420 } 421 422 free(hard_out); 423 free(e_tmp); 424 425 return 0; 426 error: 427 free(hard_out); 428 free(e_tmp); 429 printf("%s %s test error!\n", 430 test_data->algo_name, test_data->mode_name); 431 return ret; 432 } 433 434 static int test_all_result(void) 435 { 436 int ret = 0; 437 438 ret = test_hash_result(); 439 if (ret) 440 goto exit; 441 442 ret = test_cipher_result(); 443 if (ret) 444 goto exit; 445 446 ret = test_rsa_result(); 447 if (ret) 448 goto exit; 449 450 exit: 451 return 0; 452 } 453 454 static int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 455 { 456 return test_all_result(); 457 } 458 459 U_BOOT_CMD( 460 crypto, 1, 1, do_crypto, 461 "crypto test", 462 "" 463 ); 464