• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <assert.h>
5 #include <console/console.h>
6 #include <delay.h>
7 #include <soc/addressmap.h>
8 #include <soc/soc.h>
9 #include <types.h>
10 #include <vb2_api.h>
11 
12 enum rk3288_crypto_interrupt_bits {
13 	PKA_DONE	= 1 << 5,
14 	HASH_DONE	= 1 << 4,
15 	HRDMA_ERR	= 1 << 3,
16 	HRDMA_DONE	= 1 << 2,
17 	BCDMA_ERR	= 1 << 1,
18 	BCDMA_DONE	= 1 << 0,
19 };
20 
21 struct rk3288_crypto {
22 	u32 intsts;
23 	u32 intena;
24 	u32 ctrl;
25 	u32 conf;
26 	u32 brdmas;
27 	u32 btdmas;
28 	u32 btdmal;
29 	u32 hrdmas;
30 	u32 hrdmal;
31 	u8 _res0[0x80 - 0x24];
32 	u32 aes_ctrl;
33 	u32 aes_sts;
34 	u32 aes_din[4];
35 	u32 aes_dout[4];
36 	u32 aes_iv[4];
37 	u32 aes_key[8];
38 	u32 aes_cnt[4];
39 	u8 _res1[0x100 - 0xe8];
40 	u32 tdes_ctrl;
41 	u32 tdes_sts;
42 	u32 tdes_din[2];
43 	u32 tdes_dout[2];
44 	u32 tdes_iv[2];
45 	u32 tdes_key[3][2];
46 	u8 _res2[0x180 - 0x138];
47 	u32 hash_ctrl;
48 	u32 hash_sts;
49 	u32 hash_msg_len;
50 	u32 hash_dout[8];
51 	u32 hash_seed[5];
52 	u8 _res3[0x200 - 0x1c0];
53 	u32 trng_ctrl;
54 	u32 trng_dout[8];
55 } *crypto = (void *)CRYPTO_BASE;
56 check_member(rk3288_crypto, trng_dout[7], 0x220);
57 
vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,uint32_t data_size)58 vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
59 				       uint32_t data_size)
60 {
61 	if (hash_alg != VB2_HASH_SHA256 || !data_size)
62 		return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
63 
64 	write32(&crypto->ctrl, RK_SETBITS(1 << 6));	/* Assert HASH_FLUSH */
65 	udelay(1);					/* for 10+ cycles to */
66 	write32(&crypto->ctrl, RK_CLRBITS(1 << 6));	/* clear out old hash */
67 
68 	/* Enable DMA byte swapping for little-endian bus (Byteswap_??FIFO) */
69 	write32(&crypto->conf, 1 << 5 | 1 << 4 | 1 << 3);
70 
71 	write32(&crypto->intena, HRDMA_ERR | HRDMA_DONE); /* enable interrupt */
72 
73 	write32(&crypto->hash_msg_len, data_size);	/* program total size */
74 	write32(&crypto->hash_ctrl, 1 << 3 | 0x2);	/* swap DOUT, SHA256 */
75 
76 	printk(BIOS_DEBUG, "Initialized RK3288 HW crypto for %u byte SHA256\n",
77 	       data_size);
78 	return VB2_SUCCESS;
79 }
80 
vb2ex_hwcrypto_digest_extend(const uint8_t * buf,uint32_t size)81 vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
82 {
83 	uint32_t intsts;
84 
85 	write32(&crypto->intsts, HRDMA_ERR | HRDMA_DONE); /* clear interrupts */
86 
87 	/* NOTE: This assumes that the DMA is reading from uncached SRAM. */
88 	write32(&crypto->hrdmas, (uint32_t)buf);
89 	write32(&crypto->hrdmal, size / sizeof(uint32_t));
90 	write32(&crypto->ctrl, RK_SETBITS(1 << 3));	/* Set HASH_START */
91 	do {
92 		intsts = read32(&crypto->intsts);
93 		if (intsts & HRDMA_ERR) {
94 			printk(BIOS_ERR, "DMA error during HW crypto\n");
95 			return VB2_ERROR_UNKNOWN;
96 		}
97 	} while (!(intsts & HRDMA_DONE));	/* wait for DMA to finish */
98 
99 	return VB2_SUCCESS;
100 }
101 
vb2ex_hwcrypto_digest_finalize(uint8_t * digest,uint32_t digest_size)102 vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
103 					   uint32_t digest_size)
104 {
105 	uint32_t *dest = (uint32_t *)digest;
106 	uint32_t *src = crypto->hash_dout;
107 	assert(digest_size == sizeof(crypto->hash_dout));
108 
109 	while (!(read32(&crypto->hash_sts) & 0x1))
110 		/* wait for crypto engine to set HASH_DONE bit */;
111 
112 	while ((uint8_t *)dest < digest + digest_size)
113 		*dest++ = read32(src++);
114 
115 	return VB2_SUCCESS;
116 }
117