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