1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * (C) Copyright ASPEED Technology Inc.
4 * Copyright 2021 IBM Corp.
5 */
6 #include <common.h>
7 #include <clk.h>
8
9 #include <log.h>
10 #include <asm/io.h>
11 #include <malloc.h>
12 #include <hash.h>
13
14 #include <dm/device.h>
15 #include <dm/fdtaddr.h>
16
17 #include <linux/bitops.h>
18 #include <linux/delay.h>
19 #include <linux/kernel.h>
20 #include <linux/iopoll.h>
21
22 #define ASPEED_HACE_STS 0x1C
23 #define HACE_RSA_ISR BIT(13)
24 #define HACE_CRYPTO_ISR BIT(12)
25 #define HACE_HASH_ISR BIT(9)
26 #define HACE_RSA_BUSY BIT(2)
27 #define HACE_CRYPTO_BUSY BIT(1)
28 #define HACE_HASH_BUSY BIT(0)
29 #define ASPEED_HACE_HASH_SRC 0x20
30 #define ASPEED_HACE_HASH_DIGEST_BUFF 0x24
31 #define ASPEED_HACE_HASH_KEY_BUFF 0x28
32 #define ASPEED_HACE_HASH_DATA_LEN 0x2C
33 #define HACE_SG_LAST BIT(31)
34 #define ASPEED_HACE_HASH_CMD 0x30
35 #define HACE_SHA_BE_EN BIT(3)
36 #define HACE_MD5_LE_EN BIT(2)
37 #define HACE_ALGO_MD5 0
38 #define HACE_ALGO_SHA1 BIT(5)
39 #define HACE_ALGO_SHA224 BIT(6)
40 #define HACE_ALGO_SHA256 (BIT(4) | BIT(6))
41 #define HACE_ALGO_SHA512 (BIT(5) | BIT(6))
42 #define HACE_ALGO_SHA384 (BIT(5) | BIT(6) | BIT(10))
43 #define HASH_CMD_ACC_MODE (0x2 << 7)
44 #define HACE_SG_EN BIT(18)
45
46 #define ASPEED_SHA1_DIGEST_SIZE 20
47 #define ASPEED_SHA256_DIGEST_SIZE 32
48 #define ASPEED_SHA384_DIGEST_SIZE 64
49 #define ASPEED_SHA512_DIGEST_SIZE 64
50
51 #define ASPEED_SHA_TYPE_SHA1 1
52 #define ASPEED_SHA_TYPE_SHA256 2
53 #define ASPEED_SHA_TYPE_SHA384 3
54 #define ASPEED_SHA_TYPE_SHA512 4
55
56 struct aspeed_sg {
57 u32 len;
58 u32 addr;
59 };
60
61 struct aspeed_hash_ctx {
62 struct aspeed_sg sg[2]; /* Must be 8 byte aligned */
63 u8 digest[64]; /* Must be 8 byte aligned */
64 u32 method;
65 u32 digest_size;
66 u32 block_size;
67 u64 digcnt[2]; /* total length */
68 u32 bufcnt;
69 u8 buffer[256];
70 };
71
72 struct aspeed_hace {
73 struct clk clk;
74 };
75
76 static const u32 sha1_iv[8] = {
77 0x01234567UL, 0x89abcdefUL, 0xfedcba98UL, 0x76543210UL,
78 0xf0e1d2c3UL, 0, 0, 0
79 };
80
81 static const u32 sha256_iv[8] = {
82 0x67e6096aUL, 0x85ae67bbUL, 0x72f36e3cUL, 0x3af54fa5UL,
83 0x7f520e51UL, 0x8c68059bUL, 0xabd9831fUL, 0x19cde05bUL
84 };
85
86 static const u32 sha384_iv[16] = {
87 0x5d9dbbcbUL, 0xd89e05c1UL, 0x2a299a62UL, 0x07d57c36UL,
88 0x5a015991UL, 0x17dd7030UL, 0xd8ec2f15UL, 0x39590ef7UL,
89 0x67263367UL, 0x310bc0ffUL, 0x874ab48eUL, 0x11155868UL,
90 0x0d2e0cdbUL, 0xa78ff964UL, 0x1d48b547UL, 0xa44ffabeUL
91 };
92
93 static const u32 sha512_iv[16] = {
94 0x67e6096aUL, 0x08c9bcf3UL, 0x85ae67bbUL, 0x3ba7ca84UL,
95 0x72f36e3cUL, 0x2bf894feUL, 0x3af54fa5UL, 0xf1361d5fUL,
96 0x7f520e51UL, 0xd182e6adUL, 0x8c68059bUL, 0x1f6c3e2bUL,
97 0xabd9831fUL, 0x6bbd41fbUL, 0x19cde05bUL, 0x79217e13UL
98 };
99
100 static phys_addr_t base;
101
aspeed_hace_wait_completion(u32 reg,u32 flag,int timeout_us)102 static int aspeed_hace_wait_completion(u32 reg, u32 flag, int timeout_us)
103 {
104 u32 val;
105
106 return readl_poll_timeout(reg, val, (val & flag) == flag, timeout_us);
107 }
108
aspeed_ahash_fill_padding(struct aspeed_hash_ctx * ctx,unsigned int remainder)109 static void aspeed_ahash_fill_padding(struct aspeed_hash_ctx *ctx, unsigned int remainder)
110 {
111 unsigned int index, padlen;
112 u64 bits[2];
113
114 if (ctx->block_size == 64) {
115 bits[0] = cpu_to_be64(ctx->digcnt[0] << 3);
116 index = (ctx->bufcnt + remainder) & 0x3f;
117 padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
118 *(ctx->buffer + ctx->bufcnt) = 0x80;
119 memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen - 1);
120 memcpy(ctx->buffer + ctx->bufcnt + padlen, bits, 8);
121 ctx->bufcnt += padlen + 8;
122 } else {
123 bits[1] = cpu_to_be64(ctx->digcnt[0] << 3);
124 bits[0] = cpu_to_be64(ctx->digcnt[1] << 3 | ctx->digcnt[0] >> 61);
125 index = (ctx->bufcnt + remainder) & 0x7f;
126 padlen = (index < 112) ? (112 - index) : ((128 + 112) - index);
127 *(ctx->buffer + ctx->bufcnt) = 0x80;
128 memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen - 1);
129 memcpy(ctx->buffer + ctx->bufcnt + padlen, bits, 16);
130 ctx->bufcnt += padlen + 16;
131 }
132 }
133
hash_trigger(struct aspeed_hash_ctx * ctx,int hash_len)134 static int hash_trigger(struct aspeed_hash_ctx *ctx, int hash_len)
135 {
136 if (readl(base + ASPEED_HACE_STS) & HACE_HASH_BUSY) {
137 debug("HACE error: engine busy\n");
138 return -EBUSY;
139 }
140 /* Clear pending completion status */
141 writel(HACE_HASH_ISR, base + ASPEED_HACE_STS);
142
143 writel((u32)ctx->sg, base + ASPEED_HACE_HASH_SRC);
144 writel((u32)ctx->digest, base + ASPEED_HACE_HASH_DIGEST_BUFF);
145 writel((u32)ctx->digest, base + ASPEED_HACE_HASH_KEY_BUFF);
146 writel(hash_len, base + ASPEED_HACE_HASH_DATA_LEN);
147 writel(ctx->method, base + ASPEED_HACE_HASH_CMD);
148
149 /* SHA512 hashing appears to have a througput of about 12MB/s */
150 return aspeed_hace_wait_completion(base + ASPEED_HACE_STS,
151 HACE_HASH_ISR,
152 1000 + (hash_len >> 3));
153 }
154
155 #if IS_ENABLED(CONFIG_SHA_PROG_HW_ACCEL)
hw_sha_init(struct hash_algo * algo,void ** ctxp)156 int hw_sha_init(struct hash_algo *algo, void **ctxp)
157 {
158 struct aspeed_hash_ctx *ctx;
159 u32 method;
160 u32 block_size;
161
162 ctx = memalign(8, sizeof(struct aspeed_hash_ctx));
163 memset(ctx, '\0', sizeof(struct aspeed_hash_ctx));
164
165 method = HASH_CMD_ACC_MODE | HACE_SHA_BE_EN | HACE_SG_EN;
166 if (!strcmp(algo->name, "sha1")) {
167 method |= HACE_ALGO_SHA1;
168 block_size = 64;
169 memcpy(ctx->digest, sha1_iv, 32);
170 } else if (!strcmp(algo->name, "sha256")) {
171 method |= HACE_ALGO_SHA256;
172 block_size = 64;
173 memcpy(ctx->digest, sha256_iv, 32);
174 } else if (!strcmp(algo->name, "sha384")) {
175 method |= HACE_ALGO_SHA384;
176 block_size = 128;
177 memcpy(ctx->digest, sha384_iv, 64);
178 } else if (!strcmp(algo->name, "sha512")) {
179 method |= HACE_ALGO_SHA512;
180 block_size = 128;
181 memcpy(ctx->digest, sha512_iv, 64);
182 } else {
183 return -ENOTSUPP;
184 }
185
186 if (!ctx) {
187 debug("HACE error: Cannot allocate memory for context\n");
188 return -ENOMEM;
189 }
190
191 ctx->method = method;
192 ctx->block_size = block_size;
193 ctx->digest_size = algo->digest_size;
194 ctx->bufcnt = 0;
195 ctx->digcnt[0] = 0;
196 ctx->digcnt[1] = 0;
197 *ctxp = ctx;
198
199 return 0;
200 }
201
hw_sha_update(struct hash_algo * algo,void * hash_ctx,const void * buf,unsigned int size,int is_last)202 int hw_sha_update(struct hash_algo *algo, void *hash_ctx, const void *buf,
203 unsigned int size, int is_last)
204 {
205 struct aspeed_hash_ctx *ctx = hash_ctx;
206 struct aspeed_sg *sg = ctx->sg;
207 int rc;
208 int remainder;
209 int total_len;
210 int i;
211
212 ctx->digcnt[0] += size;
213 if (ctx->digcnt[0] < size)
214 ctx->digcnt[1]++;
215
216 if (ctx->bufcnt + size < ctx->block_size) {
217 memcpy(ctx->buffer + ctx->bufcnt, buf, size);
218 ctx->bufcnt += size;
219 return 0;
220 }
221 remainder = (size + ctx->bufcnt) % ctx->block_size;
222 total_len = size + ctx->bufcnt - remainder;
223 i = 0;
224 if (ctx->bufcnt != 0) {
225 sg[0].addr = (u32)ctx->buffer;
226 sg[0].len = ctx->bufcnt;
227 if (total_len == ctx->bufcnt)
228 sg[0].len |= HACE_SG_LAST;
229 i++;
230 }
231
232 if (total_len != ctx->bufcnt) {
233 sg[i].addr = (u32)buf;
234 sg[i].len = (total_len - ctx->bufcnt) | HACE_SG_LAST;
235 }
236
237 rc = hash_trigger(ctx, total_len);
238 if (remainder != 0) {
239 memcpy(ctx->buffer, buf + (total_len - ctx->bufcnt), remainder);
240 ctx->bufcnt = remainder;
241 } else {
242 ctx->bufcnt = 0;
243 }
244
245 return rc;
246 }
247
hw_sha_finish(struct hash_algo * algo,void * hash_ctx,void * dest_buf,int size)248 int hw_sha_finish(struct hash_algo *algo, void *hash_ctx, void *dest_buf, int size)
249 {
250 struct aspeed_hash_ctx *ctx = hash_ctx;
251 struct aspeed_sg *sg = ctx->sg;
252 int rc;
253
254 if (size < ctx->digest_size) {
255 debug("HACE error: insufficient size on destination buffer\n");
256 free(ctx);
257 return -EINVAL;
258 }
259 aspeed_ahash_fill_padding(ctx, 0);
260
261 sg[0].addr = (u32)ctx->buffer;
262 sg[0].len = ctx->bufcnt | HACE_SG_LAST;
263
264 rc = hash_trigger(ctx, ctx->bufcnt);
265 memcpy(dest_buf, ctx->digest, ctx->digest_size);
266
267 free(ctx);
268
269 return rc;
270 }
271 #endif
272
sha_digest(const void * src,unsigned int length,void * digest,u32 sha_type)273 static int sha_digest(const void *src, unsigned int length, void *digest,
274 u32 sha_type)
275 {
276 struct aspeed_hash_ctx *ctx;
277 int ret;
278
279 if (!((u32)src & BIT(31))) {
280 debug("HACE src out of bounds: can only copy from SDRAM\n");
281 return -EINVAL;
282 }
283
284 if (readl(base + ASPEED_HACE_STS) & HACE_HASH_BUSY) {
285 debug("HACE error: engine busy\n");
286 return -EBUSY;
287 }
288
289 ctx = memalign(8, sizeof(struct aspeed_hash_ctx));
290 memset(ctx, '\0', sizeof(struct aspeed_hash_ctx));
291
292 if (!ctx) {
293 debug("HACE error: Cannot allocate memory for context\n");
294 return -ENOMEM;
295 }
296 ctx->method = HASH_CMD_ACC_MODE | HACE_SHA_BE_EN | HACE_SG_EN;
297
298 switch (sha_type) {
299 case ASPEED_SHA_TYPE_SHA1:
300 ctx->block_size = 64;
301 ctx->digest_size = 20;
302 ctx->method |= HACE_ALGO_SHA1;
303 memcpy(ctx->digest, sha1_iv, 32);
304 break;
305 case ASPEED_SHA_TYPE_SHA256:
306 ctx->block_size = 64;
307 ctx->digest_size = 32;
308 ctx->method |= HACE_ALGO_SHA256;
309 memcpy(ctx->digest, sha256_iv, 32);
310 break;
311 case ASPEED_SHA_TYPE_SHA384:
312 ctx->block_size = 128;
313 ctx->digest_size = 64;
314 ctx->method |= HACE_ALGO_SHA384;
315 memcpy(ctx->digest, sha384_iv, 64);
316 break;
317 case ASPEED_SHA_TYPE_SHA512:
318 ctx->block_size = 128;
319 ctx->digest_size = 64;
320 ctx->method |= HACE_ALGO_SHA512;
321 memcpy(ctx->digest, sha512_iv, 64);
322 break;
323 default:
324 return -ENOTSUPP;
325 }
326
327 ctx->digcnt[0] = length;
328 ctx->digcnt[1] = 0;
329
330 aspeed_ahash_fill_padding(ctx, length);
331
332 if (length != 0) {
333 ctx->sg[0].addr = (u32)src;
334 ctx->sg[0].len = length;
335 ctx->sg[1].addr = (u32)ctx->buffer;
336 ctx->sg[1].len = ctx->bufcnt | HACE_SG_LAST;
337 } else {
338 ctx->sg[0].addr = (u32)ctx->buffer;
339 ctx->sg[0].len = ctx->bufcnt | HACE_SG_LAST;
340 }
341
342 ret = hash_trigger(ctx, length + ctx->bufcnt);
343 memcpy(digest, ctx->digest, ctx->digest_size);
344 free(ctx);
345
346 return ret;
347 }
348
hw_sha1(const unsigned char * pbuf,unsigned int buf_len,unsigned char * pout,unsigned int chunk_size)349 void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
350 unsigned char *pout, unsigned int chunk_size)
351 {
352 int rc;
353
354 rc = sha_digest(pbuf, buf_len, pout, ASPEED_SHA_TYPE_SHA1);
355 if (rc)
356 debug("HACE failure: %d\n", rc);
357 }
358
hw_sha256(const unsigned char * pbuf,unsigned int buf_len,unsigned char * pout,unsigned int chunk_size)359 void hw_sha256(const unsigned char *pbuf, unsigned int buf_len,
360 unsigned char *pout, unsigned int chunk_size)
361 {
362 int rc;
363
364 rc = sha_digest(pbuf, buf_len, pout, ASPEED_SHA_TYPE_SHA256);
365 if (rc)
366 debug("HACE failure: %d\n", rc);
367 }
368
hw_sha384(const unsigned char * pbuf,unsigned int buf_len,unsigned char * pout,unsigned int chunk_size)369 void hw_sha384(const unsigned char *pbuf, unsigned int buf_len,
370 unsigned char *pout, unsigned int chunk_size)
371 {
372 int rc;
373
374 rc = sha_digest(pbuf, buf_len, pout, ASPEED_SHA_TYPE_SHA384);
375 if (rc)
376 debug("HACE failure: %d\n", rc);
377 }
378
hw_sha512(const unsigned char * pbuf,unsigned int buf_len,unsigned char * pout,unsigned int chunk_size)379 void hw_sha512(const unsigned char *pbuf, unsigned int buf_len,
380 unsigned char *pout, unsigned int chunk_size)
381 {
382 int rc;
383
384 rc = sha_digest(pbuf, buf_len, pout, ASPEED_SHA_TYPE_SHA512);
385 if (rc)
386 debug("HACE failure: %d\n", rc);
387 }
388
aspeed_hace_probe(struct udevice * dev)389 static int aspeed_hace_probe(struct udevice *dev)
390 {
391 struct aspeed_hace *hace = dev_get_priv(dev);
392 int ret;
393
394 ret = clk_get_by_index(dev, 0, &hace->clk);
395 if (ret < 0) {
396 debug("Can't get clock for %s: %d\n", dev->name, ret);
397 return ret;
398 }
399
400 ret = clk_enable(&hace->clk);
401 if (ret) {
402 debug("Failed to enable fsi clock (%d)\n", ret);
403 return ret;
404 }
405
406 /* As the crypto code does not pass us any driver state */
407 base = devfdt_get_addr(dev);
408
409 return ret;
410 }
411
aspeed_hace_remove(struct udevice * dev)412 static int aspeed_hace_remove(struct udevice *dev)
413 {
414 struct aspeed_hace *hace = dev_get_priv(dev);
415
416 clk_disable(&hace->clk);
417
418 return 0;
419 }
420
421 static const struct udevice_id aspeed_hace_ids[] = {
422 { .compatible = "aspeed,ast2600-hace" },
423 { }
424 };
425
426 U_BOOT_DRIVER(aspeed_hace) = {
427 .name = "aspeed_hace",
428 .id = UCLASS_MISC,
429 .of_match = aspeed_hace_ids,
430 .probe = aspeed_hace_probe,
431 .remove = aspeed_hace_remove,
432 .priv_auto_alloc_size = sizeof(struct aspeed_hace),
433 .flags = DM_FLAG_PRE_RELOC,
434 };
435