blob: d48ded987a647661623744d310371e4b4ce04e95 [file] [log] [blame]
Remi Pommarel199d6e32019-03-28 23:34:18 +01001/*
2 * Copyright (c) 2019, Remi Pommarel <repk@triplefau.lt>
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Remi Pommarel199d6e32019-03-28 23:34:18 +01007#include <arch_helpers.h>
Carlo Caione23a9ad22019-08-24 17:17:30 +01008#include <assert.h>
Remi Pommarel199d6e32019-03-28 23:34:18 +01009#include <crypto/sha_dma.h>
Carlo Caione23a9ad22019-08-24 17:17:30 +010010#include <lib/mmio.h>
Remi Pommarel199d6e32019-03-28 23:34:18 +010011
12#define AML_SHA_DMA_BASE 0xc883e000
13
14#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08)
15#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x18)
16
17#define ASD_MODE_SHA224 0x7
18#define ASD_MODE_SHA256 0x6
19
20/* SHA DMA descriptor */
21struct asd_desc {
22 uint32_t cfg;
23 uint32_t src;
24 uint32_t dst;
25};
26#define ASD_DESC_GET(x, msk, off) (((x) >> (off)) & (msk))
27#define ASD_DESC_SET(x, v, msk, off) \
28 ((x) = ((x) & ~((msk) << (off))) | (((v) & (msk)) << (off)))
29
30#define ASD_DESC_LEN_OFF 0
31#define ASD_DESC_LEN_MASK 0x1ffff
32#define ASD_DESC_LEN(d) \
33 (ASD_DESC_GET((d)->cfg, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF))
34#define ASD_DESC_LEN_SET(d, v) \
35 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF))
36
37#define ASD_DESC_IRQ_OFF 17
38#define ASD_DESC_IRQ_MASK 0x1
39#define ASD_DESC_IRQ(d) \
40 (ASD_DESC_GET((d)->cfg, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF))
41#define ASD_DESC_IRQ_SET(d, v) \
42 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF))
43
44#define ASD_DESC_EOD_OFF 18
45#define ASD_DESC_EOD_MASK 0x1
46#define ASD_DESC_EOD(d) \
47 (ASD_DESC_GET((d)->cfg, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF))
48#define ASD_DESC_EOD_SET(d, v) \
49 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF))
50
51#define ASD_DESC_LOOP_OFF 19
52#define ASD_DESC_LOOP_MASK 0x1
53#define ASD_DESC_LOOP(d) \
54 (ASD_DESC_GET((d)->cfg, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF))
55#define ASD_DESC_LOOP_SET(d, v) \
56 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF))
57
58#define ASD_DESC_MODE_OFF 20
59#define ASD_DESC_MODE_MASK 0xf
60#define ASD_DESC_MODE(d) \
61 (ASD_DESC_GET((d)->cfg, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF))
62#define ASD_DESC_MODE_SET(d, v) \
63 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF))
64
65#define ASD_DESC_BEGIN_OFF 24
66#define ASD_DESC_BEGIN_MASK 0x1
67#define ASD_DESC_BEGIN(d) \
68 (ASD_DESC_GET((d)->cfg, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF))
69#define ASD_DESC_BEGIN_SET(d, v) \
70 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF))
71
72#define ASD_DESC_END_OFF 25
73#define ASD_DESC_END_MASK 0x1
74#define ASD_DESC_END(d) \
75 (ASD_DESC_GET((d)->cfg, ASD_DESC_END_MASK, ASD_DESC_END_OFF))
76#define ASD_DESC_END_SET(d, v) \
77 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_END_MASK, ASD_DESC_END_OFF))
78
79#define ASD_DESC_OP_OFF 26
80#define ASD_DESC_OP_MASK 0x2
81#define ASD_DESC_OP(d) \
82 (ASD_DESC_GET((d)->cfg, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF))
83#define ASD_DESC_OP_SET(d, v) \
84 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF))
85
86#define ASD_DESC_ENCONLY_OFF 28
87#define ASD_DESC_ENCONLY_MASK 0x1
88#define ASD_DESC_ENCONLY(d) \
89 (ASD_DESC_GET((d)->cfg, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF))
90#define ASD_DESC_ENCONLY_SET(d, v) \
91 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF))
92
93#define ASD_DESC_BLOCK_OFF 29
94#define ASD_DESC_BLOCK_MASK 0x1
95#define ASD_DESC_BLOCK(d) \
96 (ASD_DESC_GET((d)->cfg, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF))
97#define ASD_DESC_BLOCK_SET(d, v) \
98 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF))
99
100#define ASD_DESC_ERR_OFF 30
101#define ASD_DESC_ERR_MASK 0x1
102#define ASD_DESC_ERR(d) \
103 (ASD_DESC_GET((d)->cfg, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF))
104#define ASD_DESC_ERR_SET(d, v) \
105 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF))
106
Justin Chadwell7429b392019-07-03 14:10:31 +0100107#define ASD_DESC_OWNER_OFF 31u
108#define ASD_DESC_OWNER_MASK 0x1u
Remi Pommarel199d6e32019-03-28 23:34:18 +0100109#define ASD_DESC_OWNER(d) \
110 (ASD_DESC_GET((d)->cfg, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF))
111#define ASD_DESC_OWNER_SET(d, v) \
112 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF))
113
114static void asd_compute_sha(struct asd_ctx *ctx, void *data, size_t len,
115 int finalize)
116{
117 /* Make it cache line size aligned ? */
118 struct asd_desc desc = {
119 .src = (uint32_t)(uintptr_t)data,
120 .dst = (uint32_t)(uintptr_t)ctx->digest,
121 };
122
123 /* Check data address is 32bit compatible */
124 assert((uintptr_t)data == (uintptr_t)desc.src);
125 assert((uintptr_t)ctx->digest == (uintptr_t)desc.dst);
126 assert((uintptr_t)&desc == (uintptr_t)&desc);
127
128 ASD_DESC_LEN_SET(&desc, len);
Justin Chadwell7429b392019-07-03 14:10:31 +0100129 ASD_DESC_OWNER_SET(&desc, 1u);
Remi Pommarel199d6e32019-03-28 23:34:18 +0100130 ASD_DESC_ENCONLY_SET(&desc, 1);
131 ASD_DESC_EOD_SET(&desc, 1);
132 if (ctx->started == 0) {
133 ASD_DESC_BEGIN_SET(&desc, 1);
134 ctx->started = 1;
135 }
136 if (finalize) {
137 ASD_DESC_END_SET(&desc, 1);
138 ctx->started = 0;
139 }
140 if (ctx->mode == ASM_SHA224)
141 ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA224);
142 else
143 ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA256);
144
145 flush_dcache_range((uintptr_t)&desc, sizeof(desc));
146 flush_dcache_range((uintptr_t)data, len);
147
148 mmio_write_32(AML_SHA_DMA_STATUS, 0xf);
149 mmio_write_32(AML_SHA_DMA_DESC, ((uintptr_t)&desc) | 2);
150 while (mmio_read_32(AML_SHA_DMA_STATUS) == 0)
151 continue;
152 flush_dcache_range((uintptr_t)ctx->digest, SHA256_HASHSZ);
153}
154
155void asd_sha_update(struct asd_ctx *ctx, void *data, size_t len)
156{
157 size_t nr;
158
159 if (ctx->blocksz) {
160 nr = MIN(len, SHA256_BLOCKSZ - ctx->blocksz);
161 memcpy(ctx->block + ctx->blocksz, data, nr);
162 ctx->blocksz += nr;
163 len -= nr;
164 data += nr;
165 }
166
167 if (ctx->blocksz == SHA256_BLOCKSZ) {
168 asd_compute_sha(ctx, ctx->block, SHA256_BLOCKSZ, 0);
169 ctx->blocksz = 0;
170 }
171
172 asd_compute_sha(ctx, data, len & ~(SHA256_BLOCKSZ - 1), 0);
173 data += len & ~(SHA256_BLOCKSZ - 1);
174
175 if (len & (SHA256_BLOCKSZ - 1)) {
176 nr = len & (SHA256_BLOCKSZ - 1);
177 memcpy(ctx->block + ctx->blocksz, data, nr);
178 ctx->blocksz += nr;
179 }
180}
181
182void asd_sha_finalize(struct asd_ctx *ctx)
183{
184 asd_compute_sha(ctx, ctx->block, ctx->blocksz, 1);
185}