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