1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright 2021 ASPEED Technology Inc.
4 */
5 #include <config.h>
6 #include <clk.h>
7 #include <dm.h>
8 #include <asm/types.h>
9 #include <asm/io.h>
10 #include <dm/device.h>
11 #include <dm/fdtaddr.h>
12 #include <linux/delay.h>
13 #include <u-boot/rsa-mod-exp.h>
14
15 /* ACRY register offsets */
16 #define ACRY_CTRL1 0x00
17 #define ACRY_CTRL1_RSA_DMA BIT(1)
18 #define ACRY_CTRL1_RSA_START BIT(0)
19 #define ACRY_CTRL2 0x44
20 #define ACRY_CTRL3 0x48
21 #define ACRY_CTRL3_SRAM_AHB_ACCESS BIT(8)
22 #define ACRY_CTRL3_ECC_RSA_MODE_MASK GENMASK(5, 4)
23 #define ACRY_CTRL3_ECC_RSA_MODE_SHIFT 4
24 #define ACRY_DMA_DRAM_SADDR 0x4c
25 #define ACRY_DMA_DMEM_TADDR 0x50
26 #define ACRY_DMA_DMEM_TADDR_LEN_MASK GENMASK(15, 0)
27 #define ACRY_DMA_DMEM_TADDR_LEN_SHIFT 0
28 #define ACRY_RSA_PARAM 0x58
29 #define ACRY_RSA_PARAM_EXP_MASK GENMASK(31, 16)
30 #define ACRY_RSA_PARAM_EXP_SHIFT 16
31 #define ACRY_RSA_PARAM_MOD_MASK GENMASK(15, 0)
32 #define ACRY_RSA_PARAM_MOD_SHIFT 0
33 #define ACRY_RSA_INT_EN 0x3f8
34 #define ACRY_RSA_INT_EN_RSA_READY BIT(2)
35 #define ACRY_RSA_INT_EN_RSA_CMPLT BIT(1)
36 #define ACRY_RSA_INT_STS 0x3fc
37 #define ACRY_RSA_INT_STS_RSA_READY BIT(2)
38 #define ACRY_RSA_INT_STS_RSA_CMPLT BIT(1)
39
40 /* misc. constant */
41 #define ACRY_ECC_MODE 2
42 #define ACRY_RSA_MODE 3
43 #define ACRY_CTX_BUFSZ 0x600
44
45 struct aspeed_acry {
46 phys_addr_t base;
47 phys_addr_t sram_base; /* internal sram */
48 struct clk clk;
49 };
50
aspeed_acry_mod_exp(struct udevice * dev,const uint8_t * sig,uint32_t sig_len,struct key_prop * prop,uint8_t * out)51 static int aspeed_acry_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
52 struct key_prop *prop, uint8_t *out)
53 {
54 int i, j;
55 u8 *ctx;
56 u8 *ptr;
57 u32 reg;
58 struct aspeed_acry *acry = dev_get_priv(dev);
59
60 ctx = memalign(16, ACRY_CTX_BUFSZ);
61 if (!ctx)
62 return -ENOMEM;
63
64 memset(ctx, 0, ACRY_CTX_BUFSZ);
65
66 ptr = (u8 *)prop->public_exponent;
67 for (i = prop->exp_len - 1, j = 0; i >= 0; --i) {
68 ctx[j] = ptr[i];
69 j++;
70 j = (j % 16) ? j : j + 32;
71 }
72
73 ptr = (u8 *)prop->modulus;
74 for (i = (prop->num_bits >> 3) - 1, j = 0; i >= 0; --i) {
75 ctx[j + 16] = ptr[i];
76 j++;
77 j = (j % 16) ? j : j + 32;
78 }
79
80 ptr = (u8 *)sig;
81 for (i = sig_len - 1, j = 0; i >= 0; --i) {
82 ctx[j + 32] = ptr[i];
83 j++;
84 j = (j % 16) ? j : j + 32;
85 }
86
87 writel((u32)ctx, acry->base + ACRY_DMA_DRAM_SADDR);
88
89 reg = (((prop->exp_len << 3) << ACRY_RSA_PARAM_EXP_SHIFT) & ACRY_RSA_PARAM_EXP_MASK) |
90 ((prop->num_bits << ACRY_RSA_PARAM_MOD_SHIFT) & ACRY_RSA_PARAM_MOD_MASK);
91 writel(reg, acry->base + ACRY_RSA_PARAM);
92
93 reg = (ACRY_CTX_BUFSZ << ACRY_DMA_DMEM_TADDR_LEN_SHIFT) & ACRY_DMA_DMEM_TADDR_LEN_MASK;
94 writel(reg, acry->base + ACRY_DMA_DMEM_TADDR);
95
96 reg = (ACRY_RSA_MODE << ACRY_CTRL3_ECC_RSA_MODE_SHIFT) & ACRY_CTRL3_ECC_RSA_MODE_MASK;
97 writel(reg, acry->base + ACRY_CTRL3);
98
99 writel(ACRY_CTRL1_RSA_DMA | ACRY_CTRL1_RSA_START, acry->base + ACRY_CTRL1);
100
101 /* polling RSA status */
102 while (1) {
103 reg = readl(acry->base + ACRY_RSA_INT_STS);
104 if ((reg & ACRY_RSA_INT_STS_RSA_READY) && (reg & ACRY_RSA_INT_STS_RSA_CMPLT)) {
105 writel(reg, acry->base + ACRY_RSA_INT_STS);
106 break;
107 }
108 udelay(20);
109 }
110
111 /* grant SRAM access permission to CPU */
112 writel(0x0, acry->base + ACRY_CTRL1);
113 writel(ACRY_CTRL3_SRAM_AHB_ACCESS, acry->base + ACRY_CTRL3);
114 udelay(20);
115
116 for (i = (prop->num_bits / 8) - 1, j = 0; i >= 0; --i) {
117 out[i] = readb(acry->sram_base + (j + 32));
118 j++;
119 j = (j % 16) ? j : j + 32;
120 }
121
122 /* return SRAM access permission to ACRY */
123 writel(0, acry->base + ACRY_CTRL3);
124
125 free(ctx);
126
127 return 0;
128 }
129
aspeed_acry_probe(struct udevice * dev)130 static int aspeed_acry_probe(struct udevice *dev)
131 {
132 struct aspeed_acry *acry = dev_get_priv(dev);
133 int ret;
134
135 ret = clk_get_by_index(dev, 0, &acry->clk);
136 if (ret < 0) {
137 debug("Can't get clock for %s: %d\n", dev->name, ret);
138 return ret;
139 }
140
141 ret = clk_enable(&acry->clk);
142 if (ret) {
143 debug("Failed to enable acry clock (%d)\n", ret);
144 return ret;
145 }
146
147 acry->base = devfdt_get_addr_index(dev, 0);
148 if (acry->base == FDT_ADDR_T_NONE) {
149 debug("Failed to get acry base\n");
150 return acry->base;
151 }
152
153 acry->sram_base = devfdt_get_addr_index(dev, 1);
154 if (acry->sram_base == FDT_ADDR_T_NONE) {
155 debug("Failed to get acry SRAM base\n");
156 return acry->sram_base;
157 }
158
159 return ret;
160 }
161
aspeed_acry_remove(struct udevice * dev)162 static int aspeed_acry_remove(struct udevice *dev)
163 {
164 struct aspeed_acry *acry = dev_get_priv(dev);
165
166 clk_disable(&acry->clk);
167
168 return 0;
169 }
170
171 static const struct mod_exp_ops aspeed_acry_ops = {
172 .mod_exp = aspeed_acry_mod_exp,
173 };
174
175 static const struct udevice_id aspeed_acry_ids[] = {
176 { .compatible = "aspeed,ast2600-acry" },
177 { }
178 };
179
180 U_BOOT_DRIVER(aspeed_acry) = {
181 .name = "aspeed_acry",
182 .id = UCLASS_MOD_EXP,
183 .of_match = aspeed_acry_ids,
184 .probe = aspeed_acry_probe,
185 .remove = aspeed_acry_remove,
186 .priv_auto = sizeof(struct aspeed_acry),
187 .ops = &aspeed_acry_ops,
188 .flags = DM_FLAG_PRE_RELOC,
189 };
190