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