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 <clk.h> 8 #include <crypto.h> 9 #include <dm.h> 10 #include <asm/io.h> 11 #include <asm/arch/hardware.h> 12 #include <asm/arch/clock.h> 13 #include <rockchip/crypto_v2.h> 14 #include <rockchip/crypto_v2_pka.h> 15 16 struct rockchip_crypto_priv { 17 fdt_addr_t reg; 18 struct clk clk; 19 u32 frequency; 20 char *clocks; 21 u32 *frequencies; 22 u32 nclocks; 23 u32 length; 24 struct rk_hash_ctx *hw_ctx; 25 }; 26 27 #define LLI_ADDR_ALIGIN_SIZE 8 28 #define DATA_ADDR_ALIGIN_SIZE 8 29 #define DATA_LEN_ALIGIN_SIZE 64 30 31 #define RK_CRYPTO_TIME_OUT 50000 /* max 50ms */ 32 33 #define RK_WHILE_TIME_OUT(condition, timeout, ret) { \ 34 u32 time_out = timeout; \ 35 ret = 0; \ 36 while (condition) { \ 37 if (time_out-- == 0) { \ 38 debug("[%s] %d: time out!\n", __func__,\ 39 __LINE__); \ 40 ret = -ETIME; \ 41 break; \ 42 } \ 43 udelay(1); \ 44 } \ 45 } while (0) 46 47 typedef u32 paddr_t; 48 #define virt_to_phys(addr) (((unsigned long)addr) & 0xffffffff) 49 #define phys_to_virt(addr, area) ((unsigned long)addr) 50 51 static const u8 null_hash_sha1_value[] = { 52 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 53 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 54 0xaf, 0xd8, 0x07, 0x09 55 }; 56 57 static const u8 null_hash_md5_value[] = { 58 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 59 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e 60 }; 61 62 static const u8 null_hash_sha256_value[] = { 63 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 64 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 65 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 66 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 67 }; 68 69 static const u8 null_hash_sha512_value[] = { 70 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 71 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 72 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 73 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 74 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 75 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 76 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 77 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e 78 }; 79 80 fdt_addr_t crypto_base; 81 82 static void word2byte(u32 word, u8 *ch, u32 endian) 83 { 84 /* 0: Big-Endian 1: Little-Endian */ 85 if (endian == BIG_ENDIAN) { 86 ch[0] = (word >> 24) & 0xff; 87 ch[1] = (word >> 16) & 0xff; 88 ch[2] = (word >> 8) & 0xff; 89 ch[3] = (word >> 0) & 0xff; 90 } else if (endian == LITTLE_ENDIAN) { 91 ch[0] = (word >> 0) & 0xff; 92 ch[1] = (word >> 8) & 0xff; 93 ch[2] = (word >> 16) & 0xff; 94 ch[3] = (word >> 24) & 0xff; 95 } else { 96 ch[0] = 0; 97 ch[1] = 0; 98 ch[2] = 0; 99 ch[3] = 0; 100 } 101 } 102 103 static void rk_flush_cache_align(ulong addr, ulong size, ulong alignment) 104 { 105 ulong aligned_input, aligned_len; 106 107 /* Must flush dcache before crypto DMA fetch data region */ 108 aligned_input = round_down(addr, alignment); 109 aligned_len = round_up(size + (addr - aligned_input), alignment); 110 flush_cache(aligned_input, aligned_len); 111 } 112 113 static inline void clear_hash_out_reg(void) 114 { 115 int i; 116 117 /*clear out register*/ 118 for (i = 0; i < 16; i++) 119 crypto_write(0, CRYPTO_HASH_DOUT_0 + 4 * i); 120 } 121 122 static int hw_crypto_reset(void) 123 { 124 u32 tmp = 0, tmp_mask = 0; 125 int ret; 126 127 tmp = CRYPTO_SW_PKA_RESET | CRYPTO_SW_CC_RESET; 128 tmp_mask = tmp << CRYPTO_WRITE_MASK_SHIFT; 129 130 /* reset pka and crypto modules*/ 131 crypto_write(tmp | tmp_mask, CRYPTO_RST_CTL); 132 133 /* wait reset compelete */ 134 RK_WHILE_TIME_OUT(crypto_read(CRYPTO_RST_CTL), 135 RK_CRYPTO_TIME_OUT, ret); 136 return ret; 137 } 138 139 static void hw_hash_clean_ctx(struct rk_hash_ctx *ctx) 140 { 141 /* clear hash status */ 142 crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 143 144 assert(ctx); 145 assert(ctx->magic == RK_HASH_CTX_MAGIC); 146 147 if (ctx->cache) 148 free(ctx->cache); 149 150 memset(ctx, 0x00, sizeof(*ctx)); 151 } 152 153 int rk_hash_init(void *hw_ctx, u32 algo, u32 length) 154 { 155 struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)hw_ctx; 156 u32 reg_ctrl = 0; 157 int ret; 158 159 if (!tmp_ctx) 160 return -EINVAL; 161 162 memset(tmp_ctx, 0x00, sizeof(*tmp_ctx)); 163 164 reg_ctrl = CRYPTO_SW_CC_RESET; 165 crypto_write(reg_ctrl | (reg_ctrl << CRYPTO_WRITE_MASK_SHIFT), 166 CRYPTO_RST_CTL); 167 168 /* wait reset compelete */ 169 RK_WHILE_TIME_OUT(crypto_read(CRYPTO_RST_CTL), 170 RK_CRYPTO_TIME_OUT, ret); 171 172 reg_ctrl = 0; 173 tmp_ctx->algo = algo; 174 switch (algo) { 175 case CRYPTO_MD5: 176 reg_ctrl |= CRYPTO_MODE_MD5; 177 tmp_ctx->digest_size = 16; 178 tmp_ctx->null_hash = null_hash_md5_value; 179 break; 180 case CRYPTO_SHA1: 181 reg_ctrl |= CRYPTO_MODE_SHA1; 182 tmp_ctx->digest_size = 20; 183 tmp_ctx->null_hash = null_hash_sha1_value; 184 break; 185 case CRYPTO_SHA256: 186 reg_ctrl |= CRYPTO_MODE_SHA256; 187 tmp_ctx->digest_size = 32; 188 tmp_ctx->null_hash = null_hash_sha256_value; 189 break; 190 case CRYPTO_SHA512: 191 reg_ctrl |= CRYPTO_MODE_SHA512; 192 tmp_ctx->digest_size = 64; 193 tmp_ctx->null_hash = null_hash_sha512_value; 194 break; 195 196 default: 197 ret = -EINVAL; 198 goto exit; 199 } 200 201 clear_hash_out_reg(); 202 203 /* enable hardware padding */ 204 reg_ctrl |= CRYPTO_HW_PAD_ENABLE; 205 crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 206 207 /* FIFO input and output data byte swap */ 208 /* such as B0, B1, B2, B3 -> B3, B2, B1, B0 */ 209 reg_ctrl = CRYPTO_DOUT_BYTESWAP | CRYPTO_DOIN_BYTESWAP; 210 crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_FIFO_CTL); 211 212 /* enable src_item_done interrupt */ 213 crypto_write(CRYPTO_SRC_ITEM_INT_EN, CRYPTO_DMA_INT_EN); 214 215 tmp_ctx->magic = RK_HASH_CTX_MAGIC; 216 tmp_ctx->left_len = length; 217 218 return 0; 219 exit: 220 /* clear hash setting if init failed */ 221 crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 222 223 return ret; 224 } 225 226 static int rk_hash_direct_calc(struct crypto_lli_desc *lli, const u8 *data, 227 u32 data_len, u8 *started_flag, u8 is_last) 228 { 229 int ret = -EINVAL; 230 u32 tmp = 0; 231 232 assert(IS_ALIGNED((ulong)data, DATA_ADDR_ALIGIN_SIZE)); 233 assert(is_last || IS_ALIGNED(data_len, DATA_LEN_ALIGIN_SIZE)); 234 235 debug("%s: data = %p, len = %u, s = %x, l = %x\n", 236 __func__, data, data_len, *started_flag, is_last); 237 238 memset(lli, 0x00, sizeof(*lli)); 239 lli->src_addr = (u32)virt_to_phys(data); 240 lli->src_len = data_len; 241 lli->dma_ctrl = LLI_DMA_CTRL_SRC_DONE; 242 243 if (is_last) { 244 lli->user_define |= LLI_USER_STRING_LAST; 245 lli->dma_ctrl |= LLI_DMA_CTRL_LAST; 246 } else { 247 lli->next_addr = (u32)virt_to_phys(lli); 248 lli->dma_ctrl |= LLI_DMA_CTRL_PAUSE; 249 } 250 251 if (!(*started_flag)) { 252 lli->user_define |= 253 (LLI_USER_STRING_START | LLI_USER_CPIHER_START); 254 crypto_write((u32)virt_to_phys(lli), CRYPTO_DMA_LLI_ADDR); 255 crypto_write((CRYPTO_HASH_ENABLE << CRYPTO_WRITE_MASK_SHIFT) | 256 CRYPTO_HASH_ENABLE, CRYPTO_HASH_CTL); 257 tmp = CRYPTO_DMA_START; 258 *started_flag = 1; 259 } else { 260 tmp = CRYPTO_DMA_RESTART; 261 } 262 263 /* flush cache */ 264 rk_flush_cache_align((ulong)lli, sizeof(*lli), 265 CONFIG_SYS_CACHELINE_SIZE); 266 rk_flush_cache_align((ulong)data, data_len, CONFIG_SYS_CACHELINE_SIZE); 267 268 /* start calculate */ 269 crypto_write(tmp << CRYPTO_WRITE_MASK_SHIFT | tmp, 270 CRYPTO_DMA_CTL); 271 272 /* wait calc ok */ 273 RK_WHILE_TIME_OUT(!crypto_read(CRYPTO_DMA_INT_ST), 274 RK_CRYPTO_TIME_OUT, ret); 275 276 /* clear interrupt status */ 277 tmp = crypto_read(CRYPTO_DMA_INT_ST); 278 crypto_write(tmp, CRYPTO_DMA_INT_ST); 279 280 if (tmp != CRYPTO_SRC_ITEM_DONE_INT_ST && 281 tmp != CRYPTO_ZERO_LEN_INT_ST) { 282 debug("[%s] %d: CRYPTO_DMA_INT_ST = 0x%x\n", 283 __func__, __LINE__, tmp); 284 goto exit; 285 } 286 287 exit: 288 return ret; 289 } 290 291 static int rk_hash_cache_calc(struct rk_hash_ctx *tmp_ctx, const u8 *data, 292 u32 data_len, u8 is_last) 293 { 294 u32 left_len; 295 int ret = 0; 296 297 if (!tmp_ctx->cache) { 298 tmp_ctx->cache = (u8 *)memalign(DATA_ADDR_ALIGIN_SIZE, 299 HASH_CACHE_SIZE); 300 if (!tmp_ctx->cache) 301 goto error; 302 303 tmp_ctx->cache_size = 0; 304 } 305 306 left_len = tmp_ctx->left_len; 307 308 while (1) { 309 u32 tmp_len = 0; 310 311 if (tmp_ctx->cache_size + data_len <= HASH_CACHE_SIZE) { 312 /* copy to cache */ 313 debug("%s, %d: copy to cache %u\n", 314 __func__, __LINE__, data_len); 315 memcpy(tmp_ctx->cache + tmp_ctx->cache_size, data, 316 data_len); 317 tmp_ctx->cache_size += data_len; 318 319 /* if last one calc cache immediately */ 320 if (is_last) { 321 debug("%s, %d: last one calc cache %u\n", 322 __func__, __LINE__, tmp_ctx->cache_size); 323 ret = rk_hash_direct_calc(&tmp_ctx->data_lli, 324 tmp_ctx->cache, 325 tmp_ctx->cache_size, 326 &tmp_ctx->is_started, 327 is_last); 328 if (ret) 329 goto error; 330 } 331 left_len -= data_len; 332 break; 333 } 334 335 /* 1. make cache be full */ 336 /* 2. calc cache */ 337 tmp_len = HASH_CACHE_SIZE - tmp_ctx->cache_size; 338 debug("%s, %d: make cache be full %u\n", 339 __func__, __LINE__, tmp_len); 340 memcpy(tmp_ctx->cache + tmp_ctx->cache_size, data, tmp_len); 341 342 ret = rk_hash_direct_calc(&tmp_ctx->data_lli, 343 tmp_ctx->cache, 344 HASH_CACHE_SIZE, 345 &tmp_ctx->is_started, 346 0); 347 if (ret) 348 goto error; 349 350 data += tmp_len; 351 data_len -= tmp_len; 352 left_len -= tmp_len; 353 tmp_ctx->cache_size = 0; 354 } 355 356 return ret; 357 error: 358 return -EINVAL; 359 } 360 361 int rk_hash_update(void *ctx, const u8 *data, u32 data_len) 362 { 363 struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 364 const u8 *direct_data = NULL, *cache_data = NULL; 365 u32 direct_data_len = 0, cache_data_len = 0; 366 int ret = 0; 367 u8 is_last = 0; 368 369 debug("\n"); 370 if (!tmp_ctx || !data) 371 goto error; 372 373 if (tmp_ctx->digest_size == 0 || tmp_ctx->magic != RK_HASH_CTX_MAGIC) 374 goto error; 375 376 if (tmp_ctx->left_len < data_len) 377 goto error; 378 379 is_last = tmp_ctx->left_len == data_len ? 1 : 0; 380 381 if (!tmp_ctx->use_cache && 382 IS_ALIGNED((ulong)data, DATA_ADDR_ALIGIN_SIZE)) { 383 direct_data = data; 384 if (IS_ALIGNED(data_len, DATA_LEN_ALIGIN_SIZE) || is_last) { 385 /* calc all directly */ 386 debug("%s, %d: calc all directly\n", 387 __func__, __LINE__); 388 direct_data_len = data_len; 389 } else { 390 /* calc some directly calc some in cache */ 391 debug("%s, %d: calc some directly calc some in cache\n", 392 __func__, __LINE__); 393 direct_data_len = round_down((ulong)data_len, 394 DATA_LEN_ALIGIN_SIZE); 395 cache_data = direct_data + direct_data_len; 396 cache_data_len = data_len % DATA_LEN_ALIGIN_SIZE; 397 tmp_ctx->use_cache = 1; 398 } 399 } else { 400 /* calc all in cache */ 401 debug("%s, %d: calc all in cache\n", __func__, __LINE__); 402 cache_data = data; 403 cache_data_len = data_len; 404 tmp_ctx->use_cache = 1; 405 } 406 407 if (direct_data_len) { 408 debug("%s, %d: calc direct data %u\n", 409 __func__, __LINE__, direct_data_len); 410 ret = rk_hash_direct_calc(&tmp_ctx->data_lli, direct_data, 411 direct_data_len, 412 &tmp_ctx->is_started, is_last); 413 if (ret) 414 goto error; 415 tmp_ctx->left_len -= direct_data_len; 416 } 417 418 if (cache_data_len) { 419 debug("%s, %d: calc cache data %u\n", 420 __func__, __LINE__, cache_data_len); 421 ret = rk_hash_cache_calc(tmp_ctx, cache_data, 422 cache_data_len, is_last); 423 if (ret) 424 goto error; 425 tmp_ctx->left_len -= cache_data_len; 426 } 427 428 return ret; 429 error: 430 /* free lli list */ 431 hw_hash_clean_ctx(tmp_ctx); 432 433 return -EINVAL; 434 } 435 436 int rk_hash_final(void *ctx, u8 *digest, size_t len) 437 { 438 struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 439 int ret = -EINVAL; 440 u32 i; 441 442 if (!digest) 443 goto exit; 444 445 if (!tmp_ctx || 446 tmp_ctx->digest_size == 0 || 447 len > tmp_ctx->digest_size || 448 tmp_ctx->magic != RK_HASH_CTX_MAGIC) { 449 goto exit; 450 } 451 452 /* wait hash value ok */ 453 RK_WHILE_TIME_OUT(!crypto_read(CRYPTO_HASH_VALID), 454 RK_CRYPTO_TIME_OUT, ret); 455 456 for (i = 0; i < len / 4; i++) 457 word2byte(crypto_read(CRYPTO_HASH_DOUT_0 + i * 4), 458 digest + i * 4, BIG_ENDIAN); 459 460 if (len % 4) { 461 u8 tmp_buf[4]; 462 463 word2byte(crypto_read(CRYPTO_HASH_DOUT_0 + i * 4), 464 tmp_buf, BIG_ENDIAN); 465 memcpy(digest + i * 4, tmp_buf, len % 4); 466 } 467 468 /* clear hash status */ 469 crypto_write(CRYPTO_HASH_IS_VALID, CRYPTO_HASH_VALID); 470 crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 471 472 exit: 473 /* free lli list */ 474 hw_hash_clean_ctx(tmp_ctx); 475 476 return ret; 477 } 478 479 static int rk_trng(u8 *trng, u32 len) 480 { 481 u32 i, reg_ctrl = 0; 482 int ret = -EINVAL; 483 u32 buf[8]; 484 485 if (len > CRYPTO_TRNG_MAX) 486 return -EINVAL; 487 488 memset(buf, 0, sizeof(buf)); 489 490 /* enable osc_ring to get entropy, sample period is set as 50 */ 491 crypto_write(50, CRYPTO_RNG_SAMPLE_CNT); 492 493 reg_ctrl |= CRYPTO_RNG_256_bit_len; 494 reg_ctrl |= CRYPTO_RNG_SLOWER_SOC_RING_1; 495 reg_ctrl |= CRYPTO_RNG_ENABLE; 496 reg_ctrl |= CRYPTO_RNG_START; 497 reg_ctrl |= CRYPTO_WRITE_MASK_ALL; 498 499 crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_RNG_CTL); 500 RK_WHILE_TIME_OUT(crypto_read(CRYPTO_RNG_CTL) & CRYPTO_RNG_START, 501 RK_CRYPTO_TIME_OUT, ret); 502 503 if (ret == 0) { 504 for (i = 0; i < ARRAY_SIZE(buf); i++) 505 buf[i] = crypto_read(CRYPTO_RNG_DOUT_0 + i * 4); 506 memcpy(trng, buf, len); 507 } 508 509 /* close TRNG */ 510 crypto_write(0 | CRYPTO_WRITE_MASK_ALL, CRYPTO_RNG_CTL); 511 512 return ret; 513 } 514 515 static u32 rockchip_crypto_capability(struct udevice *dev) 516 { 517 return CRYPTO_MD5 | 518 CRYPTO_SHA1 | 519 CRYPTO_SHA256 | 520 #if !defined(CONFIG_ROCKCHIP_RK1808) 521 CRYPTO_SHA512 | 522 #endif 523 CRYPTO_RSA512 | 524 CRYPTO_RSA1024 | 525 CRYPTO_RSA2048 | 526 CRYPTO_RSA3072 | 527 CRYPTO_RSA4096 | 528 CRYPTO_TRNG; 529 } 530 531 static int rockchip_crypto_sha_init(struct udevice *dev, sha_context *ctx) 532 { 533 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 534 535 if (!ctx) 536 return -EINVAL; 537 538 memset(priv->hw_ctx, 0x00, sizeof(struct rk_hash_ctx)); 539 540 return rk_hash_init(priv->hw_ctx, ctx->algo, ctx->length); 541 } 542 543 static int rockchip_crypto_sha_update(struct udevice *dev, 544 u32 *input, u32 len) 545 { 546 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 547 548 if (!len) 549 return -EINVAL; 550 551 return rk_hash_update(priv->hw_ctx, (u8 *)input, len); 552 } 553 554 static int rockchip_crypto_sha_final(struct udevice *dev, 555 sha_context *ctx, u8 *output) 556 { 557 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 558 u32 nbits; 559 560 nbits = crypto_algo_nbits(ctx->algo); 561 562 return rk_hash_final(priv->hw_ctx, (u8 *)output, BITS2BYTE(nbits)); 563 } 564 565 static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 566 u8 *sign, u8 *output) 567 { 568 struct mpa_num *mpa_m = NULL, *mpa_e = NULL, *mpa_n = NULL; 569 struct mpa_num *mpa_c = NULL, *mpa_result = NULL; 570 u32 n_bits, n_words; 571 u32 *rsa_result; 572 int ret; 573 574 if (!ctx) 575 return -EINVAL; 576 577 if (ctx->algo != CRYPTO_RSA512 && 578 ctx->algo != CRYPTO_RSA1024 && 579 ctx->algo != CRYPTO_RSA2048 && 580 ctx->algo != CRYPTO_RSA3072 && 581 ctx->algo != CRYPTO_RSA4096) 582 return -EINVAL; 583 584 n_bits = crypto_algo_nbits(ctx->algo); 585 n_words = BITS2WORD(n_bits); 586 587 rsa_result = malloc(BITS2BYTE(n_bits)); 588 if (!rsa_result) 589 return -ENOMEM; 590 591 memset(rsa_result, 0x00, BITS2BYTE(n_bits)); 592 593 ret = rk_mpa_alloc(&mpa_m); 594 ret |= rk_mpa_alloc(&mpa_e); 595 ret |= rk_mpa_alloc(&mpa_n); 596 ret |= rk_mpa_alloc(&mpa_c); 597 ret |= rk_mpa_alloc(&mpa_result); 598 if (ret) 599 goto exit; 600 601 mpa_m->d = (void *)sign; 602 mpa_e->d = (void *)ctx->e; 603 mpa_n->d = (void *)ctx->n; 604 mpa_c->d = (void *)ctx->c; 605 mpa_result->d = (void *)rsa_result; 606 607 mpa_m->size = n_words; 608 mpa_e->size = n_words; 609 mpa_n->size = n_words; 610 mpa_c->size = n_words; 611 mpa_result->size = n_words; 612 613 ret = rk_exptmod_np(mpa_m, mpa_e, mpa_n, mpa_c, mpa_result); 614 if (!ret) 615 memcpy(output, rsa_result, BITS2BYTE(n_bits)); 616 617 exit: 618 free(rsa_result); 619 rk_mpa_free(&mpa_m); 620 rk_mpa_free(&mpa_e); 621 rk_mpa_free(&mpa_n); 622 rk_mpa_free(&mpa_c); 623 rk_mpa_free(&mpa_result); 624 625 return ret; 626 } 627 628 static int rockchip_crypto_get_trng(struct udevice *dev, u8 *output, u32 len) 629 { 630 int ret; 631 u32 i; 632 633 if (!dev || !output || !len) 634 return -EINVAL; 635 636 for (i = 0; i < len / CRYPTO_TRNG_MAX; i++) { 637 ret = rk_trng(output + i * CRYPTO_TRNG_MAX, CRYPTO_TRNG_MAX); 638 if (ret) 639 goto fail; 640 } 641 642 ret = rk_trng(output + i * CRYPTO_TRNG_MAX, len % CRYPTO_TRNG_MAX); 643 644 fail: 645 return ret; 646 } 647 648 static const struct dm_crypto_ops rockchip_crypto_ops = { 649 .capability = rockchip_crypto_capability, 650 .sha_init = rockchip_crypto_sha_init, 651 .sha_update = rockchip_crypto_sha_update, 652 .sha_final = rockchip_crypto_sha_final, 653 .rsa_verify = rockchip_crypto_rsa_verify, 654 .get_trng = rockchip_crypto_get_trng, 655 }; 656 657 /* 658 * Only use "clocks" to parse crypto clock id and use rockchip_get_clk(). 659 * Because we always add crypto node in U-Boot dts, when kernel dtb enabled : 660 * 661 * 1. There is cru phandle mismatch between U-Boot and kernel dtb; 662 * 2. CONFIG_OF_SPL_REMOVE_PROPS removes clock property; 663 */ 664 static int rockchip_crypto_ofdata_to_platdata(struct udevice *dev) 665 { 666 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 667 int len, ret = -EINVAL; 668 669 if (!dev_read_prop(dev, "clocks", &len)) { 670 printf("Can't find \"clocks\" property\n"); 671 return -EINVAL; 672 } 673 674 memset(priv, 0x00, sizeof(*priv)); 675 priv->clocks = malloc(len); 676 if (!priv->clocks) 677 return -ENOMEM; 678 679 priv->nclocks = len / sizeof(u32); 680 if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks, 681 priv->nclocks)) { 682 printf("Can't read \"clocks\" property\n"); 683 ret = -EINVAL; 684 goto exit; 685 } 686 687 if (!dev_read_prop(dev, "clock-frequency", &len)) { 688 printf("Can't find \"clock-frequency\" property\n"); 689 ret = -EINVAL; 690 goto exit; 691 } 692 693 priv->frequencies = malloc(len); 694 if (!priv->frequencies) { 695 ret = -ENOMEM; 696 goto exit; 697 } 698 699 priv->nclocks = len / sizeof(u32); 700 if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies, 701 priv->nclocks)) { 702 printf("Can't read \"clock-frequency\" property\n"); 703 ret = -EINVAL; 704 goto exit; 705 } 706 707 priv->reg = (fdt_addr_t)dev_read_addr_ptr(dev); 708 709 crypto_base = priv->reg; 710 711 return 0; 712 exit: 713 if (priv->clocks) 714 free(priv->clocks); 715 716 if (priv->frequencies) 717 free(priv->frequencies); 718 719 return ret; 720 } 721 722 static int rockchip_crypto_probe(struct udevice *dev) 723 { 724 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 725 int i, ret = 0; 726 u32* clocks; 727 728 priv->hw_ctx = memalign(LLI_ADDR_ALIGIN_SIZE, 729 sizeof(struct rk_hash_ctx)); 730 if (!priv->hw_ctx) 731 return -ENOMEM; 732 733 ret = rockchip_get_clk(&priv->clk.dev); 734 if (ret) { 735 printf("Failed to get clk device, ret=%d\n", ret); 736 return ret; 737 } 738 739 clocks = (u32 *)priv->clocks; 740 for (i = 0; i < priv->nclocks; i++) { 741 priv->clk.id = clocks[i * 2 + 1]; 742 ret = clk_set_rate(&priv->clk, priv->frequencies[i]); 743 if (ret < 0) { 744 printf("%s: Failed to set clk(%ld): ret=%d\n", 745 __func__, priv->clk.id, ret); 746 return ret; 747 } 748 } 749 750 hw_crypto_reset(); 751 752 return 0; 753 } 754 755 static const struct udevice_id rockchip_crypto_ids[] = { 756 { .compatible = "rockchip,px30-crypto" }, 757 { .compatible = "rockchip,rk1808-crypto" }, 758 { .compatible = "rockchip,rk3308-crypto" }, 759 { } 760 }; 761 762 U_BOOT_DRIVER(rockchip_crypto_v2) = { 763 .name = "rockchip_crypto_v2", 764 .id = UCLASS_CRYPTO, 765 .of_match = rockchip_crypto_ids, 766 .ops = &rockchip_crypto_ops, 767 .probe = rockchip_crypto_probe, 768 .ofdata_to_platdata = rockchip_crypto_ofdata_to_platdata, 769 .priv_auto_alloc_size = sizeof(struct rockchip_crypto_priv), 770 }; 771