summaryrefslogtreecommitdiffstats
path: root/drivers/crypto/starfive/jh7110-cryp.h
blob: 6cdf6db5d90486ed08b6b975ef8fe24f79d8daf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __STARFIVE_STR_H__
#define __STARFIVE_STR_H__

#include <crypto/aes.h>
#include <crypto/hash.h>
#include <crypto/scatterwalk.h>
#include <crypto/sha2.h>
#include <crypto/sm3.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>

#define STARFIVE_ALG_CR_OFFSET			0x0
#define STARFIVE_ALG_FIFO_OFFSET		0x4
#define STARFIVE_IE_MASK_OFFSET			0x8
#define STARFIVE_IE_FLAG_OFFSET			0xc
#define STARFIVE_DMA_IN_LEN_OFFSET		0x10
#define STARFIVE_DMA_OUT_LEN_OFFSET		0x14

#define STARFIVE_IE_MASK_AES_DONE		0x1
#define STARFIVE_IE_MASK_HASH_DONE		0x4
#define STARFIVE_IE_MASK_PKA_DONE		0x8
#define STARFIVE_IE_FLAG_AES_DONE		0x1
#define STARFIVE_IE_FLAG_HASH_DONE		0x4
#define STARFIVE_IE_FLAG_PKA_DONE		0x8

#define STARFIVE_MSG_BUFFER_SIZE		SZ_16K
#define MAX_KEY_SIZE				SHA512_BLOCK_SIZE
#define STARFIVE_AES_IV_LEN			AES_BLOCK_SIZE
#define STARFIVE_AES_CTR_LEN			AES_BLOCK_SIZE

union starfive_aes_csr {
	u32 v;
	struct {
		u32 cmode			:1;
#define STARFIVE_AES_KEYMODE_128		0x0
#define STARFIVE_AES_KEYMODE_192		0x1
#define STARFIVE_AES_KEYMODE_256		0x2
		u32 keymode			:2;
#define STARFIVE_AES_BUSY			BIT(3)
		u32 busy			:1;
		u32 done			:1;
#define STARFIVE_AES_KEY_DONE			BIT(5)
		u32 krdy			:1;
		u32 aesrst			:1;
		u32 ie				:1;
#define STARFIVE_AES_CCM_START			BIT(8)
		u32 ccm_start			:1;
#define STARFIVE_AES_MODE_ECB			0x0
#define STARFIVE_AES_MODE_CBC			0x1
#define STARFIVE_AES_MODE_CTR			0x4
#define STARFIVE_AES_MODE_CCM			0x5
#define STARFIVE_AES_MODE_GCM			0x6
		u32 mode			:3;
#define STARFIVE_AES_GCM_START			BIT(12)
		u32 gcm_start			:1;
#define STARFIVE_AES_GCM_DONE			BIT(13)
		u32 gcm_done			:1;
		u32 delay_aes			:1;
		u32 vaes_start			:1;
		u32 rsvd_0			:8;
#define STARFIVE_AES_MODE_XFB_1			0x0
#define STARFIVE_AES_MODE_XFB_128		0x5
		u32 stmode			:3;
		u32 rsvd_1			:5;
	};
};

union starfive_hash_csr {
	u32 v;
	struct {
		u32 start			:1;
		u32 reset			:1;
		u32 ie				:1;
		u32 firstb			:1;
#define STARFIVE_HASH_SM3			0x0
#define STARFIVE_HASH_SHA224			0x3
#define STARFIVE_HASH_SHA256			0x4
#define STARFIVE_HASH_SHA384			0x5
#define STARFIVE_HASH_SHA512			0x6
#define STARFIVE_HASH_MODE_MASK			0x7
		u32 mode			:3;
		u32 rsvd_1			:1;
		u32 final			:1;
		u32 rsvd_2			:2;
#define STARFIVE_HASH_HMAC_FLAGS		0x800
		u32 hmac			:1;
		u32 rsvd_3			:1;
#define STARFIVE_HASH_KEY_DONE			BIT(13)
		u32 key_done			:1;
		u32 key_flag			:1;
		u32 hmac_done			:1;
#define STARFIVE_HASH_BUSY			BIT(16)
		u32 busy			:1;
		u32 hashdone			:1;
		u32 rsvd_4			:14;
	};
};

union starfive_pka_cacr {
	u32 v;
	struct {
		u32 start			:1;
		u32 reset			:1;
		u32 ie				:1;
		u32 rsvd_0			:1;
		u32 fifo_mode			:1;
		u32 not_r2			:1;
		u32 ecc_sub			:1;
		u32 pre_expf			:1;
		u32 cmd				:4;
		u32 rsvd_1			:1;
		u32 ctrl_dummy			:1;
		u32 ctrl_false			:1;
		u32 cln_done			:1;
		u32 opsize			:6;
		u32 rsvd_2			:2;
		u32 exposize			:6;
		u32 rsvd_3			:1;
		u32 bigendian			:1;
	};
};

union starfive_pka_casr {
	u32 v;
	struct {
#define STARFIVE_PKA_DONE			BIT(0)
		u32 done			:1;
		u32 rsvd_0			:31;
	};
};

struct starfive_rsa_key {
	u8	*n;
	u8	*e;
	u8	*d;
	int	e_bitlen;
	int	d_bitlen;
	int	bitlen;
	size_t	key_sz;
};

union starfive_alg_cr {
	u32 v;
	struct {
		u32 start			:1;
		u32 aes_dma_en			:1;
		u32 rsvd_0			:1;
		u32 hash_dma_en			:1;
		u32 alg_done			:1;
		u32 rsvd_1			:3;
		u32 clear			:1;
		u32 rsvd_2			:23;
	};
};

struct starfive_cryp_ctx {
	struct starfive_cryp_dev		*cryp;
	struct starfive_cryp_request_ctx	*rctx;

	unsigned int				hash_mode;
	u8					key[MAX_KEY_SIZE];
	int					keylen;
	bool					is_hmac;
	struct starfive_rsa_key			rsa_key;
	struct crypto_akcipher			*akcipher_fbk;
	struct crypto_ahash			*ahash_fbk;
	struct crypto_aead			*aead_fbk;
};

struct starfive_cryp_dev {
	struct list_head			list;
	struct device				*dev;
	struct clk				*hclk;
	struct clk				*ahb;
	struct reset_control			*rst;

	void __iomem				*base;
	phys_addr_t				phys_base;

	u32					dma_maxburst;
	struct dma_chan				*tx;
	struct dma_chan				*rx;
	struct dma_slave_config			cfg_in;
	struct dma_slave_config			cfg_out;
	struct scatter_walk			in_walk;
	struct scatter_walk			out_walk;
	struct crypto_engine			*engine;
	struct tasklet_struct			aes_done;
	struct tasklet_struct			hash_done;
	size_t					assoclen;
	size_t					total_in;
	size_t					total_out;
	u32					tag_in[4];
	u32					tag_out[4];
	unsigned int				authsize;
	unsigned long				flags;
	int					err;
	bool					side_chan;
	union starfive_alg_cr			alg_cr;
	union {
		struct ahash_request		*hreq;
		struct aead_request		*areq;
		struct skcipher_request		*sreq;
	} req;
};

struct starfive_cryp_request_ctx {
	union {
		union starfive_hash_csr		hash;
		union starfive_pka_cacr		pka;
		union starfive_aes_csr		aes;
	} csr;

	struct scatterlist			*in_sg;
	struct scatterlist			*out_sg;
	struct ahash_request			ahash_fbk_req;
	size_t					total;
	size_t					nents;
	unsigned int				blksize;
	unsigned int				digsize;
	unsigned long				in_sg_len;
	unsigned char				*adata;
	u8 rsa_data[] __aligned(sizeof(u32));
};

struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);

int starfive_hash_register_algs(void);
void starfive_hash_unregister_algs(void);

int starfive_rsa_register_algs(void);
void starfive_rsa_unregister_algs(void);

int starfive_aes_register_algs(void);
void starfive_aes_unregister_algs(void);

void starfive_hash_done_task(unsigned long param);
void starfive_aes_done_task(unsigned long param);
#endif