blob: b569a6249cec1e56ac1146f65baad102c0bd2d7d [file] [log] [blame]
Julius Werner33df4952014-12-16 22:48:26 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Julius Werner33df4952014-12-16 22:48:26 -080014 */
15
16#include <arch/io.h>
17#include <assert.h>
18#include <delay.h>
19#include <soc/addressmap.h>
20#include <soc/soc.h>
21#include <types.h>
22#include <vb2_api.h>
23
24enum rk3288_crypto_interrupt_bits {
25 PKA_DONE = 1 << 5,
26 HASH_DONE = 1 << 4,
27 HRDMA_ERR = 1 << 3,
28 HRDMA_DONE = 1 << 2,
29 BCDMA_ERR = 1 << 1,
30 BCDMA_DONE = 1 << 0,
31};
32
33struct rk3288_crypto {
34 u32 intsts;
35 u32 intena;
36 u32 ctrl;
37 u32 conf;
38 u32 brdmas;
39 u32 btdmas;
40 u32 btdmal;
41 u32 hrdmas;
42 u32 hrdmal;
43 u8 _res0[0x80 - 0x24];
44 u32 aes_ctrl;
45 u32 aes_sts;
46 u32 aes_din[4];
47 u32 aes_dout[4];
48 u32 aes_iv[4];
49 u32 aes_key[8];
50 u32 aes_cnt[4];
51 u8 _res1[0x100 - 0xe8];
52 u32 tdes_ctrl;
53 u32 tdes_sts;
54 u32 tdes_din[2];
55 u32 tdes_dout[2];
56 u32 tdes_iv[2];
57 u32 tdes_key[3][2];
58 u8 _res2[0x180 - 0x138];
59 u32 hash_ctrl;
60 u32 hash_sts;
61 u32 hash_msg_len;
62 u32 hash_dout[8];
63 u32 hash_seed[5];
64 u8 _res3[0x200 - 0x1c0];
65 u32 trng_ctrl;
66 u32 trng_dout[8];
67} *crypto = (void *)CRYPTO_BASE;
68check_member(rk3288_crypto, trng_dout[7], 0x220);
69
70int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
71 uint32_t data_size)
72{
73 if (hash_alg != VB2_HASH_SHA256) {
74 printk(BIOS_INFO, "RK3288 doesn't support hash_alg %d!\n",
75 hash_alg);
76 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
77 }
78
Julius Werner2f37bd62015-02-19 14:51:15 -080079 write32(&crypto->ctrl, RK_SETBITS(1 << 6)); /* Assert HASH_FLUSH */
Julius Werner33df4952014-12-16 22:48:26 -080080 udelay(1); /* for 10+ cycles to */
Julius Werner2f37bd62015-02-19 14:51:15 -080081 write32(&crypto->ctrl, RK_CLRBITS(1 << 6)); /* clear out old hash */
Julius Werner33df4952014-12-16 22:48:26 -080082
83 /* Enable DMA byte swapping for little-endian bus (Byteswap_??FIFO) */
Julius Werner2f37bd62015-02-19 14:51:15 -080084 write32(&crypto->conf, 1 << 5 | 1 << 4 | 1 << 3);
Julius Werner33df4952014-12-16 22:48:26 -080085
Julius Werner2f37bd62015-02-19 14:51:15 -080086 write32(&crypto->intena, HRDMA_ERR | HRDMA_DONE); /* enable interrupt */
Julius Werner33df4952014-12-16 22:48:26 -080087
Julius Werner2f37bd62015-02-19 14:51:15 -080088 write32(&crypto->hash_msg_len, data_size); /* program total size */
89 write32(&crypto->hash_ctrl, 1 << 3 | 0x2); /* swap DOUT, SHA256 */
Julius Werner33df4952014-12-16 22:48:26 -080090
91 printk(BIOS_DEBUG, "Initialized RK3288 HW crypto for %u byte SHA256\n",
92 data_size);
93 return VB2_SUCCESS;
94}
95
96int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
97{
98 uint32_t intsts;
99
Julius Werner2f37bd62015-02-19 14:51:15 -0800100 write32(&crypto->intsts, HRDMA_ERR | HRDMA_DONE); /* clear interrupts */
Julius Werner33df4952014-12-16 22:48:26 -0800101
102 /* NOTE: This assumes that the DMA is reading from uncached SRAM. */
Julius Werner2f37bd62015-02-19 14:51:15 -0800103 write32(&crypto->hrdmas, (uint32_t)buf);
104 write32(&crypto->hrdmal, size / sizeof(uint32_t));
105 write32(&crypto->ctrl, RK_SETBITS(1 << 3)); /* Set HASH_START */
Julius Werner33df4952014-12-16 22:48:26 -0800106 do {
107 intsts = read32(&crypto->intsts);
108 if (intsts & HRDMA_ERR) {
109 printk(BIOS_ERR, "ERROR: DMA error during HW crypto\n");
110 return VB2_ERROR_UNKNOWN;
111 }
112 } while (!(intsts & HRDMA_DONE)); /* wait for DMA to finish */
113
114 return VB2_SUCCESS;
115}
116
117int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
118{
119 uint32_t *dest = (uint32_t *)digest;
120 uint32_t *src = crypto->hash_dout;
121 assert(digest_size == sizeof(crypto->hash_dout));
122
123 while (!(read32(&crypto->hash_sts) & 0x1))
124 /* wait for crypto engine to set HASH_DONE bit */;
125
126 while ((uint8_t *)dest < digest + digest_size)
127 *dest++ = read32(src++);
128
129 return VB2_SUCCESS;
130}