coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
crypto.c
Go to the documentation of this file.
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 
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 {
31  u8 _res0[0x80 - 0x24];
36  u32 aes_iv[4];
39  u8 _res1[0x100 - 0xe8];
45  u32 tdes_key[3][2];
46  u8 _res2[0x180 - 0x138];
52  u8 _res3[0x200 - 0x1c0];
55 } *crypto = (void *)CRYPTO_BASE;
56 check_member(rk3288_crypto, trng_dout[7], 0x220);
57 
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) {
62  printk(BIOS_INFO, "RK3288 doesn't support hash_alg %d!\n",
63  hash_alg);
64  return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
65  }
66 
67  write32(&crypto->ctrl, RK_SETBITS(1 << 6)); /* Assert HASH_FLUSH */
68  udelay(1); /* for 10+ cycles to */
69  write32(&crypto->ctrl, RK_CLRBITS(1 << 6)); /* clear out old hash */
70 
71  /* Enable DMA byte swapping for little-endian bus (Byteswap_??FIFO) */
72  write32(&crypto->conf, 1 << 5 | 1 << 4 | 1 << 3);
73 
74  write32(&crypto->intena, HRDMA_ERR | HRDMA_DONE); /* enable interrupt */
75 
76  write32(&crypto->hash_msg_len, data_size); /* program total size */
77  write32(&crypto->hash_ctrl, 1 << 3 | 0x2); /* swap DOUT, SHA256 */
78 
79  printk(BIOS_DEBUG, "Initialized RK3288 HW crypto for %u byte SHA256\n",
80  data_size);
81  return VB2_SUCCESS;
82 }
83 
85 {
86  uint32_t intsts;
87 
88  write32(&crypto->intsts, HRDMA_ERR | HRDMA_DONE); /* clear interrupts */
89 
90  /* NOTE: This assumes that the DMA is reading from uncached SRAM. */
92  write32(&crypto->hrdmal, size / sizeof(uint32_t));
93  write32(&crypto->ctrl, RK_SETBITS(1 << 3)); /* Set HASH_START */
94  do {
95  intsts = read32(&crypto->intsts);
96  if (intsts & HRDMA_ERR) {
97  printk(BIOS_ERR, "DMA error during HW crypto\n");
98  return VB2_ERROR_UNKNOWN;
99  }
100  } while (!(intsts & HRDMA_DONE)); /* wait for DMA to finish */
101 
102  return VB2_SUCCESS;
103 }
104 
106  uint32_t digest_size)
107 {
108  uint32_t *dest = (uint32_t *)digest;
109  uint32_t *src = crypto->hash_dout;
110  assert(digest_size == sizeof(crypto->hash_dout));
111 
112  while (!(read32(&crypto->hash_sts) & 0x1))
113  /* wait for crypto engine to set HASH_DONE bit */;
114 
115  while ((uint8_t *)dest < digest + digest_size)
116  *dest++ = read32(src++);
117 
118  return VB2_SUCCESS;
119 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define assert(statement)
Definition: assert.h:74
#define printk(level,...)
Definition: stdlib.h:16
vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, uint32_t data_size)
Definition: crypto.c:58
vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
Definition: crypto.c:105
vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
Definition: crypto.c:84
struct rk3288_crypto * crypto
check_member(rk3288_crypto, trng_dout[7], 0x220)
rk3288_crypto_interrupt_bits
Definition: crypto.c:12
@ HRDMA_ERR
Definition: crypto.c:15
@ BCDMA_DONE
Definition: crypto.c:18
@ PKA_DONE
Definition: crypto.c:13
@ BCDMA_ERR
Definition: crypto.c:17
@ HRDMA_DONE
Definition: crypto.c:16
@ HASH_DONE
Definition: crypto.c:14
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
static uint8_t * buf
Definition: uart.c:7
#define RK_CLRBITS(clr)
Definition: soc.h:10
#define RK_SETBITS(set)
Definition: soc.h:9
#define CRYPTO_BASE
Definition: addressmap.h:66
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
u32 aes_cnt[4]
Definition: crypto.c:38
u32 hrdmas
Definition: crypto.c:29
u32 tdes_dout[2]
Definition: crypto.c:43
u8 _res0[0x80 - 0x24]
Definition: crypto.c:31
u32 hrdmal
Definition: crypto.c:30
u32 conf
Definition: crypto.c:25
u32 aes_sts
Definition: crypto.c:33
u8 _res3[0x200 - 0x1c0]
Definition: crypto.c:52
u32 trng_ctrl
Definition: crypto.c:53
u32 intsts
Definition: crypto.c:22
u8 _res2[0x180 - 0x138]
Definition: crypto.c:46
u32 tdes_key[3][2]
Definition: crypto.c:45
u32 aes_dout[4]
Definition: crypto.c:35
u32 ctrl
Definition: crypto.c:24
u8 _res1[0x100 - 0xe8]
Definition: crypto.c:39
u32 aes_din[4]
Definition: crypto.c:34
u32 brdmas
Definition: crypto.c:26
u32 hash_dout[8]
Definition: crypto.c:50
u32 hash_sts
Definition: crypto.c:48
u32 tdes_iv[2]
Definition: crypto.c:44
u32 aes_key[8]
Definition: crypto.c:37
u32 aes_ctrl
Definition: crypto.c:32
u32 btdmal
Definition: crypto.c:28
u32 aes_iv[4]
Definition: crypto.c:36
u32 trng_dout[8]
Definition: crypto.c:54
u32 tdes_sts
Definition: crypto.c:41
u32 hash_seed[5]
Definition: crypto.c:51
u32 tdes_din[2]
Definition: crypto.c:42
u32 tdes_ctrl
Definition: crypto.c:40
u32 intena
Definition: crypto.c:23
u32 btdmas
Definition: crypto.c:27
u32 hash_ctrl
Definition: crypto.c:47
u32 hash_msg_len
Definition: crypto.c:49
void udelay(uint32_t us)
Definition: udelay.c:15