blob: a9ff2e19f9d509c9e16a3539bcf6045e540a69c9 [file] [log] [blame]
Horia Geantă618b5dc2018-10-10 14:26:48 +03001// SPDX-License-Identifier: GPL-2.0+
Kim Phillips8e8ec592011-03-13 16:54:26 +08002/*
3 * caam - Freescale FSL CAAM support for crypto API
4 *
5 * Copyright 2008-2011 Freescale Semiconductor, Inc.
Horia Geantă5ca7bad2018-08-06 15:43:59 +03006 * Copyright 2016-2018 NXP
Kim Phillips8e8ec592011-03-13 16:54:26 +08007 *
8 * Based on talitos crypto API driver.
9 *
10 * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
11 *
12 * --------------- ---------------
13 * | JobDesc #1 |-------------------->| ShareDesc |
14 * | *(packet 1) | | (PDB) |
15 * --------------- |------------->| (hashKey) |
16 * . | | (cipherKey) |
17 * . | |-------->| (operation) |
18 * --------------- | | ---------------
19 * | JobDesc #2 |------| |
20 * | *(packet 2) | |
21 * --------------- |
22 * . |
23 * . |
24 * --------------- |
25 * | JobDesc #3 |------------
26 * | *(packet 3) |
27 * ---------------
28 *
29 * The SharedDesc never changes for a connection unless rekeyed, but
30 * each packet will likely be in a different place. So all we need
31 * to know to process the packet is where the input is, where the
32 * output goes, and what context we want to process with. Context is
33 * in the SharedDesc, packet references in the JobDesc.
34 *
35 * So, a job desc looks like:
36 *
37 * ---------------------
38 * | Header |
39 * | ShareDesc Pointer |
40 * | SEQ_OUT_PTR |
41 * | (output buffer) |
Yuan Kang6ec47332012-06-22 19:48:43 -050042 * | (output length) |
Kim Phillips8e8ec592011-03-13 16:54:26 +080043 * | SEQ_IN_PTR |
44 * | (input buffer) |
Yuan Kang6ec47332012-06-22 19:48:43 -050045 * | (input length) |
Kim Phillips8e8ec592011-03-13 16:54:26 +080046 * ---------------------
47 */
48
49#include "compat.h"
50
51#include "regs.h"
52#include "intern.h"
53#include "desc_constr.h"
54#include "jr.h"
55#include "error.h"
Yuan Kanga299c832012-06-22 19:48:46 -050056#include "sg_sw_sec4.h"
Yuan Kang4c1ec1f2012-06-22 19:48:45 -050057#include "key_gen.h"
Horia Geantă8cea7b62016-11-22 15:44:09 +020058#include "caamalg_desc.h"
Kim Phillips8e8ec592011-03-13 16:54:26 +080059
60/*
61 * crypto alg
62 */
63#define CAAM_CRA_PRIORITY 3000
64/* max key is sum of AES_MAX_KEY_SIZE, max split key size */
65#define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + \
Catalin Vasiledaebc462014-10-31 12:45:37 +020066 CTR_RFC3686_NONCE_SIZE + \
Kim Phillips8e8ec592011-03-13 16:54:26 +080067 SHA512_DIGEST_SIZE * 2)
Kim Phillips8e8ec592011-03-13 16:54:26 +080068
Herbert Xuf2147b82015-06-16 13:54:23 +080069#define AEAD_DESC_JOB_IO_LEN (DESC_JOB_IO_LEN + CAAM_CMD_SZ * 2)
70#define GCM_DESC_JOB_IO_LEN (AEAD_DESC_JOB_IO_LEN + \
71 CAAM_CMD_SZ * 4)
Herbert Xu479bcc72015-07-30 17:53:17 +080072#define AUTHENC_DESC_JOB_IO_LEN (AEAD_DESC_JOB_IO_LEN + \
73 CAAM_CMD_SZ * 5)
Herbert Xuf2147b82015-06-16 13:54:23 +080074
Horia Geantăd6bbd4e2018-11-08 15:36:30 +020075#define CHACHAPOLY_DESC_JOB_IO_LEN (AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6)
76
Herbert Xu87e51b02015-06-18 14:25:55 +080077#define DESC_MAX_USED_BYTES (CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN)
78#define DESC_MAX_USED_LEN (DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
Kim Phillips4427b1b2011-05-14 22:08:17 -050079
Kim Phillips8e8ec592011-03-13 16:54:26 +080080#ifdef DEBUG
81/* for print_hex_dumps with line references */
Kim Phillips8e8ec592011-03-13 16:54:26 +080082#define debug(format, arg...) printk(format, arg)
83#else
84#define debug(format, arg...)
85#endif
Catalin Vasile5ecf8ef2016-09-22 11:57:58 +030086
Herbert Xu479bcc72015-07-30 17:53:17 +080087struct caam_alg_entry {
88 int class1_alg_type;
89 int class2_alg_type;
Herbert Xu479bcc72015-07-30 17:53:17 +080090 bool rfc3686;
91 bool geniv;
92};
93
94struct caam_aead_alg {
95 struct aead_alg aead;
96 struct caam_alg_entry caam;
97 bool registered;
98};
99
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300100struct caam_skcipher_alg {
101 struct skcipher_alg skcipher;
102 struct caam_alg_entry caam;
103 bool registered;
104};
105
Yuan Kangacdca312011-07-15 11:21:42 +0800106/*
Kim Phillips8e8ec592011-03-13 16:54:26 +0800107 * per-session context
108 */
109struct caam_ctx {
Yuan Kang1acebad2011-07-15 11:21:42 +0800110 u32 sh_desc_enc[DESC_MAX_USED_LEN];
111 u32 sh_desc_dec[DESC_MAX_USED_LEN];
Horia Geantăbbf22342017-02-10 14:07:22 +0200112 u8 key[CAAM_MAX_KEY_SIZE];
Yuan Kang1acebad2011-07-15 11:21:42 +0800113 dma_addr_t sh_desc_enc_dma;
114 dma_addr_t sh_desc_dec_dma;
Yuan Kang885e9e22011-07-15 11:21:41 +0800115 dma_addr_t key_dma;
Horia Geantă7e0880b2017-12-19 12:16:07 +0200116 enum dma_data_direction dir;
Horia Geantăbbf22342017-02-10 14:07:22 +0200117 struct device *jrdev;
Horia Geantădb576562016-11-22 15:44:04 +0200118 struct alginfo adata;
119 struct alginfo cdata;
Kim Phillips8e8ec592011-03-13 16:54:26 +0800120 unsigned int authsize;
121};
122
Horia Geantaae4a8252014-03-14 17:46:52 +0200123static int aead_null_set_sh_desc(struct crypto_aead *aead)
124{
Horia Geantaae4a8252014-03-14 17:46:52 +0200125 struct caam_ctx *ctx = crypto_aead_ctx(aead);
126 struct device *jrdev = ctx->jrdev;
Horia Geantă7e0880b2017-12-19 12:16:07 +0200127 struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
Horia Geantaae4a8252014-03-14 17:46:52 +0200128 u32 *desc;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200129 int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
130 ctx->adata.keylen_pad;
Horia Geantaae4a8252014-03-14 17:46:52 +0200131
132 /*
133 * Job Descriptor and Shared Descriptors
134 * must all fit into the 64-word Descriptor h/w Buffer
135 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200136 if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200137 ctx->adata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100138 ctx->adata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200139 } else {
140 ctx->adata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100141 ctx->adata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200142 }
Horia Geantaae4a8252014-03-14 17:46:52 +0200143
Herbert Xu479bcc72015-07-30 17:53:17 +0800144 /* aead_encrypt shared descriptor */
Horia Geantaae4a8252014-03-14 17:46:52 +0200145 desc = ctx->sh_desc_enc;
Horia Geantă7e0880b2017-12-19 12:16:07 +0200146 cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
147 ctrlpriv->era);
Horia Geantăbbf22342017-02-10 14:07:22 +0200148 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200149 desc_bytes(desc), ctx->dir);
Horia Geantaae4a8252014-03-14 17:46:52 +0200150
151 /*
152 * Job Descriptor and Shared Descriptors
153 * must all fit into the 64-word Descriptor h/w Buffer
154 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200155 if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200156 ctx->adata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100157 ctx->adata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200158 } else {
159 ctx->adata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100160 ctx->adata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200161 }
Horia Geantaae4a8252014-03-14 17:46:52 +0200162
Herbert Xu479bcc72015-07-30 17:53:17 +0800163 /* aead_decrypt shared descriptor */
Horia Geantă8cea7b62016-11-22 15:44:09 +0200164 desc = ctx->sh_desc_dec;
Horia Geantă7e0880b2017-12-19 12:16:07 +0200165 cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
166 ctrlpriv->era);
Horia Geantăbbf22342017-02-10 14:07:22 +0200167 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200168 desc_bytes(desc), ctx->dir);
Horia Geantaae4a8252014-03-14 17:46:52 +0200169
170 return 0;
171}
172
Yuan Kang1acebad2011-07-15 11:21:42 +0800173static int aead_set_sh_desc(struct crypto_aead *aead)
174{
Herbert Xu479bcc72015-07-30 17:53:17 +0800175 struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
176 struct caam_aead_alg, aead);
Herbert Xuadd86d52015-05-11 17:47:50 +0800177 unsigned int ivsize = crypto_aead_ivsize(aead);
Yuan Kang1acebad2011-07-15 11:21:42 +0800178 struct caam_ctx *ctx = crypto_aead_ctx(aead);
179 struct device *jrdev = ctx->jrdev;
Horia Geantă7e0880b2017-12-19 12:16:07 +0200180 struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
Catalin Vasiledaebc462014-10-31 12:45:37 +0200181 u32 ctx1_iv_off = 0;
Horia Geantă8cea7b62016-11-22 15:44:09 +0200182 u32 *desc, *nonce = NULL;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200183 u32 inl_mask;
184 unsigned int data_len[2];
Horia Geantădb576562016-11-22 15:44:04 +0200185 const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
Catalin Vasiledaebc462014-10-31 12:45:37 +0200186 OP_ALG_AAI_CTR_MOD128);
Herbert Xu479bcc72015-07-30 17:53:17 +0800187 const bool is_rfc3686 = alg->caam.rfc3686;
Yuan Kang1acebad2011-07-15 11:21:42 +0800188
Horia Geantă2fdea252016-08-04 20:02:47 +0300189 if (!ctx->authsize)
190 return 0;
191
Horia Geantaae4a8252014-03-14 17:46:52 +0200192 /* NULL encryption / decryption */
Horia Geantădb576562016-11-22 15:44:04 +0200193 if (!ctx->cdata.keylen)
Horia Geantaae4a8252014-03-14 17:46:52 +0200194 return aead_null_set_sh_desc(aead);
195
Yuan Kang1acebad2011-07-15 11:21:42 +0800196 /*
Catalin Vasiledaebc462014-10-31 12:45:37 +0200197 * AES-CTR needs to load IV in CONTEXT1 reg
198 * at an offset of 128bits (16bytes)
199 * CONTEXT1[255:128] = IV
200 */
201 if (ctr_mode)
202 ctx1_iv_off = 16;
203
204 /*
205 * RFC3686 specific:
206 * CONTEXT1[255:128] = {NONCE, IV, COUNTER}
207 */
Horia Geantă8cea7b62016-11-22 15:44:09 +0200208 if (is_rfc3686) {
Catalin Vasiledaebc462014-10-31 12:45:37 +0200209 ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
Horia Geantă8cea7b62016-11-22 15:44:09 +0200210 nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
211 ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
212 }
Catalin Vasiledaebc462014-10-31 12:45:37 +0200213
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200214 data_len[0] = ctx->adata.keylen_pad;
215 data_len[1] = ctx->cdata.keylen;
216
Herbert Xu479bcc72015-07-30 17:53:17 +0800217 if (alg->caam.geniv)
218 goto skip_enc;
219
Catalin Vasiledaebc462014-10-31 12:45:37 +0200220 /*
Yuan Kang1acebad2011-07-15 11:21:42 +0800221 * Job Descriptor and Shared Descriptors
222 * must all fit into the 64-word Descriptor h/w Buffer
223 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200224 if (desc_inline_query(DESC_AEAD_ENC_LEN +
225 (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
226 AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
227 ARRAY_SIZE(data_len)) < 0)
228 return -EINVAL;
229
230 if (inl_mask & 1)
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100231 ctx->adata.key_virt = ctx->key;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200232 else
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100233 ctx->adata.key_dma = ctx->key_dma;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200234
235 if (inl_mask & 2)
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100236 ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200237 else
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100238 ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200239
240 ctx->adata.key_inline = !!(inl_mask & 1);
241 ctx->cdata.key_inline = !!(inl_mask & 2);
Yuan Kang1acebad2011-07-15 11:21:42 +0800242
Herbert Xu479bcc72015-07-30 17:53:17 +0800243 /* aead_encrypt shared descriptor */
Yuan Kang1acebad2011-07-15 11:21:42 +0800244 desc = ctx->sh_desc_enc;
Horia Geantăb1898172017-03-17 12:06:02 +0200245 cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
246 ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200247 false, ctrlpriv->era);
Horia Geantăbbf22342017-02-10 14:07:22 +0200248 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200249 desc_bytes(desc), ctx->dir);
Yuan Kang1acebad2011-07-15 11:21:42 +0800250
Herbert Xu479bcc72015-07-30 17:53:17 +0800251skip_enc:
Yuan Kang1acebad2011-07-15 11:21:42 +0800252 /*
253 * Job Descriptor and Shared Descriptors
254 * must all fit into the 64-word Descriptor h/w Buffer
255 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200256 if (desc_inline_query(DESC_AEAD_DEC_LEN +
257 (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
258 AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
259 ARRAY_SIZE(data_len)) < 0)
260 return -EINVAL;
261
262 if (inl_mask & 1)
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100263 ctx->adata.key_virt = ctx->key;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200264 else
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100265 ctx->adata.key_dma = ctx->key_dma;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200266
267 if (inl_mask & 2)
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100268 ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200269 else
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100270 ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200271
272 ctx->adata.key_inline = !!(inl_mask & 1);
273 ctx->cdata.key_inline = !!(inl_mask & 2);
Yuan Kang1acebad2011-07-15 11:21:42 +0800274
Herbert Xu479bcc72015-07-30 17:53:17 +0800275 /* aead_decrypt shared descriptor */
Yuan Kang1acebad2011-07-15 11:21:42 +0800276 desc = ctx->sh_desc_dec;
Horia Geantă8cea7b62016-11-22 15:44:09 +0200277 cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
278 ctx->authsize, alg->caam.geniv, is_rfc3686,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200279 nonce, ctx1_iv_off, false, ctrlpriv->era);
Horia Geantăbbf22342017-02-10 14:07:22 +0200280 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200281 desc_bytes(desc), ctx->dir);
Yuan Kang1acebad2011-07-15 11:21:42 +0800282
Herbert Xu479bcc72015-07-30 17:53:17 +0800283 if (!alg->caam.geniv)
284 goto skip_givenc;
285
Yuan Kang1acebad2011-07-15 11:21:42 +0800286 /*
287 * Job Descriptor and Shared Descriptors
288 * must all fit into the 64-word Descriptor h/w Buffer
289 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200290 if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
291 (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
292 AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
293 ARRAY_SIZE(data_len)) < 0)
294 return -EINVAL;
295
296 if (inl_mask & 1)
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100297 ctx->adata.key_virt = ctx->key;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200298 else
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100299 ctx->adata.key_dma = ctx->key_dma;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200300
301 if (inl_mask & 2)
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100302 ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200303 else
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100304 ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200305
306 ctx->adata.key_inline = !!(inl_mask & 1);
307 ctx->cdata.key_inline = !!(inl_mask & 2);
Yuan Kang1acebad2011-07-15 11:21:42 +0800308
309 /* aead_givencrypt shared descriptor */
Horia Geantă1d2d87e2016-08-04 20:02:46 +0300310 desc = ctx->sh_desc_enc;
Horia Geantă8cea7b62016-11-22 15:44:09 +0200311 cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
312 ctx->authsize, is_rfc3686, nonce,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200313 ctx1_iv_off, false, ctrlpriv->era);
Horia Geantăbbf22342017-02-10 14:07:22 +0200314 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200315 desc_bytes(desc), ctx->dir);
Yuan Kang1acebad2011-07-15 11:21:42 +0800316
Herbert Xu479bcc72015-07-30 17:53:17 +0800317skip_givenc:
Yuan Kang1acebad2011-07-15 11:21:42 +0800318 return 0;
319}
320
Yuan Kang0e479302011-07-15 11:21:41 +0800321static int aead_setauthsize(struct crypto_aead *authenc,
Kim Phillips8e8ec592011-03-13 16:54:26 +0800322 unsigned int authsize)
323{
324 struct caam_ctx *ctx = crypto_aead_ctx(authenc);
325
326 ctx->authsize = authsize;
Yuan Kang1acebad2011-07-15 11:21:42 +0800327 aead_set_sh_desc(authenc);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800328
329 return 0;
330}
331
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300332static int gcm_set_sh_desc(struct crypto_aead *aead)
333{
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300334 struct caam_ctx *ctx = crypto_aead_ctx(aead);
335 struct device *jrdev = ctx->jrdev;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200336 unsigned int ivsize = crypto_aead_ivsize(aead);
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300337 u32 *desc;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200338 int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
339 ctx->cdata.keylen;
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300340
Horia Geantădb576562016-11-22 15:44:04 +0200341 if (!ctx->cdata.keylen || !ctx->authsize)
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300342 return 0;
343
344 /*
345 * AES GCM encrypt shared descriptor
346 * Job Descriptor and Shared Descriptor
347 * must fit into the 64-word Descriptor h/w Buffer
348 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200349 if (rem_bytes >= DESC_GCM_ENC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200350 ctx->cdata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100351 ctx->cdata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200352 } else {
353 ctx->cdata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100354 ctx->cdata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200355 }
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300356
357 desc = ctx->sh_desc_enc;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200358 cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
Horia Geantăbbf22342017-02-10 14:07:22 +0200359 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200360 desc_bytes(desc), ctx->dir);
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300361
362 /*
363 * Job Descriptor and Shared Descriptors
364 * must all fit into the 64-word Descriptor h/w Buffer
365 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200366 if (rem_bytes >= DESC_GCM_DEC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200367 ctx->cdata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100368 ctx->cdata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200369 } else {
370 ctx->cdata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100371 ctx->cdata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200372 }
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300373
374 desc = ctx->sh_desc_dec;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200375 cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
Horia Geantăbbf22342017-02-10 14:07:22 +0200376 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200377 desc_bytes(desc), ctx->dir);
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300378
379 return 0;
380}
381
382static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
383{
384 struct caam_ctx *ctx = crypto_aead_ctx(authenc);
385
386 ctx->authsize = authsize;
387 gcm_set_sh_desc(authenc);
388
389 return 0;
390}
391
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300392static int rfc4106_set_sh_desc(struct crypto_aead *aead)
393{
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300394 struct caam_ctx *ctx = crypto_aead_ctx(aead);
395 struct device *jrdev = ctx->jrdev;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200396 unsigned int ivsize = crypto_aead_ivsize(aead);
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300397 u32 *desc;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200398 int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
399 ctx->cdata.keylen;
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300400
Horia Geantădb576562016-11-22 15:44:04 +0200401 if (!ctx->cdata.keylen || !ctx->authsize)
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300402 return 0;
403
404 /*
405 * RFC4106 encrypt shared descriptor
406 * Job Descriptor and Shared Descriptor
407 * must fit into the 64-word Descriptor h/w Buffer
408 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200409 if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200410 ctx->cdata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100411 ctx->cdata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200412 } else {
413 ctx->cdata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100414 ctx->cdata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200415 }
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300416
417 desc = ctx->sh_desc_enc;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200418 cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
419 false);
Horia Geantăbbf22342017-02-10 14:07:22 +0200420 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200421 desc_bytes(desc), ctx->dir);
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300422
423 /*
424 * Job Descriptor and Shared Descriptors
425 * must all fit into the 64-word Descriptor h/w Buffer
426 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200427 if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200428 ctx->cdata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100429 ctx->cdata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200430 } else {
431 ctx->cdata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100432 ctx->cdata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200433 }
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300434
435 desc = ctx->sh_desc_dec;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200436 cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
437 false);
Horia Geantăbbf22342017-02-10 14:07:22 +0200438 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200439 desc_bytes(desc), ctx->dir);
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300440
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300441 return 0;
442}
443
444static int rfc4106_setauthsize(struct crypto_aead *authenc,
445 unsigned int authsize)
446{
447 struct caam_ctx *ctx = crypto_aead_ctx(authenc);
448
449 ctx->authsize = authsize;
450 rfc4106_set_sh_desc(authenc);
451
452 return 0;
453}
454
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200455static int rfc4543_set_sh_desc(struct crypto_aead *aead)
456{
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200457 struct caam_ctx *ctx = crypto_aead_ctx(aead);
458 struct device *jrdev = ctx->jrdev;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200459 unsigned int ivsize = crypto_aead_ivsize(aead);
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200460 u32 *desc;
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200461 int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
462 ctx->cdata.keylen;
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200463
Horia Geantădb576562016-11-22 15:44:04 +0200464 if (!ctx->cdata.keylen || !ctx->authsize)
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200465 return 0;
466
467 /*
468 * RFC4543 encrypt shared descriptor
469 * Job Descriptor and Shared Descriptor
470 * must fit into the 64-word Descriptor h/w Buffer
471 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200472 if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200473 ctx->cdata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100474 ctx->cdata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200475 } else {
476 ctx->cdata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100477 ctx->cdata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200478 }
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200479
480 desc = ctx->sh_desc_enc;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200481 cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
482 false);
Horia Geantăbbf22342017-02-10 14:07:22 +0200483 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200484 desc_bytes(desc), ctx->dir);
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200485
486 /*
487 * Job Descriptor and Shared Descriptors
488 * must all fit into the 64-word Descriptor h/w Buffer
489 */
Horia Geantă4cbe79c2016-11-22 15:44:06 +0200490 if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
Horia Geantădb576562016-11-22 15:44:04 +0200491 ctx->cdata.key_inline = true;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100492 ctx->cdata.key_virt = ctx->key;
Horia Geantădb576562016-11-22 15:44:04 +0200493 } else {
494 ctx->cdata.key_inline = false;
Arnd Bergmann9c0bc512016-11-30 22:01:59 +0100495 ctx->cdata.key_dma = ctx->key_dma;
Horia Geantădb576562016-11-22 15:44:04 +0200496 }
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200497
498 desc = ctx->sh_desc_dec;
Horia Geantă87ec3a02018-01-29 10:38:36 +0200499 cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
500 false);
Horia Geantăbbf22342017-02-10 14:07:22 +0200501 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200502 desc_bytes(desc), ctx->dir);
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200503
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200504 return 0;
505}
506
507static int rfc4543_setauthsize(struct crypto_aead *authenc,
508 unsigned int authsize)
509{
510 struct caam_ctx *ctx = crypto_aead_ctx(authenc);
511
512 ctx->authsize = authsize;
513 rfc4543_set_sh_desc(authenc);
514
515 return 0;
516}
517
Horia Geantăd6bbd4e2018-11-08 15:36:30 +0200518static int chachapoly_set_sh_desc(struct crypto_aead *aead)
519{
520 struct caam_ctx *ctx = crypto_aead_ctx(aead);
521 struct device *jrdev = ctx->jrdev;
522 unsigned int ivsize = crypto_aead_ivsize(aead);
523 u32 *desc;
524
525 if (!ctx->cdata.keylen || !ctx->authsize)
526 return 0;
527
528 desc = ctx->sh_desc_enc;
529 cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
Horia Geantăc10a5332018-11-08 15:36:31 +0200530 ctx->authsize, true, false);
Horia Geantăd6bbd4e2018-11-08 15:36:30 +0200531 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
532 desc_bytes(desc), ctx->dir);
533
534 desc = ctx->sh_desc_dec;
535 cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
Horia Geantăc10a5332018-11-08 15:36:31 +0200536 ctx->authsize, false, false);
Horia Geantăd6bbd4e2018-11-08 15:36:30 +0200537 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
538 desc_bytes(desc), ctx->dir);
539
540 return 0;
541}
542
543static int chachapoly_setauthsize(struct crypto_aead *aead,
544 unsigned int authsize)
545{
546 struct caam_ctx *ctx = crypto_aead_ctx(aead);
547
548 if (authsize != POLY1305_DIGEST_SIZE)
549 return -EINVAL;
550
551 ctx->authsize = authsize;
552 return chachapoly_set_sh_desc(aead);
553}
554
555static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
556 unsigned int keylen)
557{
558 struct caam_ctx *ctx = crypto_aead_ctx(aead);
559 unsigned int ivsize = crypto_aead_ivsize(aead);
560 unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
561
Eric Biggers1ca1b912018-11-16 17:26:21 -0800562 if (keylen != CHACHA_KEY_SIZE + saltlen) {
Horia Geantăd6bbd4e2018-11-08 15:36:30 +0200563 crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
564 return -EINVAL;
565 }
566
567 ctx->cdata.key_virt = key;
568 ctx->cdata.keylen = keylen - saltlen;
569
570 return chachapoly_set_sh_desc(aead);
571}
572
Yuan Kang0e479302011-07-15 11:21:41 +0800573static int aead_setkey(struct crypto_aead *aead,
Kim Phillips8e8ec592011-03-13 16:54:26 +0800574 const u8 *key, unsigned int keylen)
575{
Kim Phillips8e8ec592011-03-13 16:54:26 +0800576 struct caam_ctx *ctx = crypto_aead_ctx(aead);
577 struct device *jrdev = ctx->jrdev;
Horia Geantă7e0880b2017-12-19 12:16:07 +0200578 struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
Horia Geanta4e6e0b22013-12-19 17:27:35 +0200579 struct crypto_authenc_keys keys;
Kim Phillips8e8ec592011-03-13 16:54:26 +0800580 int ret = 0;
581
Horia Geanta4e6e0b22013-12-19 17:27:35 +0200582 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips8e8ec592011-03-13 16:54:26 +0800583 goto badkey;
584
Kim Phillips8e8ec592011-03-13 16:54:26 +0800585#ifdef DEBUG
586 printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
Horia Geanta4e6e0b22013-12-19 17:27:35 +0200587 keys.authkeylen + keys.enckeylen, keys.enckeylen,
588 keys.authkeylen);
Alex Porosanu514df282013-08-14 18:56:45 +0300589 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
Kim Phillips8e8ec592011-03-13 16:54:26 +0800590 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
591#endif
Kim Phillips8e8ec592011-03-13 16:54:26 +0800592
Horia Geantă7e0880b2017-12-19 12:16:07 +0200593 /*
594 * If DKP is supported, use it in the shared descriptor to generate
595 * the split key.
596 */
597 if (ctrlpriv->era >= 6) {
598 ctx->adata.keylen = keys.authkeylen;
599 ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
600 OP_ALG_ALGSEL_MASK);
601
602 if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
603 goto badkey;
604
605 memcpy(ctx->key, keys.authkey, keys.authkeylen);
606 memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
607 keys.enckeylen);
608 dma_sync_single_for_device(jrdev, ctx->key_dma,
609 ctx->adata.keylen_pad +
610 keys.enckeylen, ctx->dir);
611 goto skip_split_key;
612 }
613
Horia Geantă6655cb82016-11-22 15:44:10 +0200614 ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
615 keys.authkeylen, CAAM_MAX_KEY_SIZE -
616 keys.enckeylen);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800617 if (ret) {
Kim Phillips8e8ec592011-03-13 16:54:26 +0800618 goto badkey;
619 }
620
621 /* postpend encryption key to auth split key */
Horia Geantădb576562016-11-22 15:44:04 +0200622 memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
Horia Geantăbbf22342017-02-10 14:07:22 +0200623 dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
Horia Geantă7e0880b2017-12-19 12:16:07 +0200624 keys.enckeylen, ctx->dir);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800625#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +0300626 print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
Kim Phillips8e8ec592011-03-13 16:54:26 +0800627 DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
Horia Geantădb576562016-11-22 15:44:04 +0200628 ctx->adata.keylen_pad + keys.enckeylen, 1);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800629#endif
Horia Geantă7e0880b2017-12-19 12:16:07 +0200630
631skip_split_key:
Horia Geantădb576562016-11-22 15:44:04 +0200632 ctx->cdata.keylen = keys.enckeylen;
Tudor-Dan Ambarus61dab972018-03-23 12:42:18 +0200633 memzero_explicit(&keys, sizeof(keys));
Horia Geantăbbf22342017-02-10 14:07:22 +0200634 return aead_set_sh_desc(aead);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800635badkey:
636 crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
Tudor-Dan Ambarus61dab972018-03-23 12:42:18 +0200637 memzero_explicit(&keys, sizeof(keys));
Kim Phillips8e8ec592011-03-13 16:54:26 +0800638 return -EINVAL;
639}
640
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300641static int gcm_setkey(struct crypto_aead *aead,
642 const u8 *key, unsigned int keylen)
643{
644 struct caam_ctx *ctx = crypto_aead_ctx(aead);
645 struct device *jrdev = ctx->jrdev;
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300646
647#ifdef DEBUG
648 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
649 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
650#endif
651
652 memcpy(ctx->key, key, keylen);
Horia Geantă7e0880b2017-12-19 12:16:07 +0200653 dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
Horia Geantădb576562016-11-22 15:44:04 +0200654 ctx->cdata.keylen = keylen;
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300655
Horia Geantăbbf22342017-02-10 14:07:22 +0200656 return gcm_set_sh_desc(aead);
Tudor Ambarus3ef8d942014-10-23 16:11:23 +0300657}
658
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300659static int rfc4106_setkey(struct crypto_aead *aead,
660 const u8 *key, unsigned int keylen)
661{
662 struct caam_ctx *ctx = crypto_aead_ctx(aead);
663 struct device *jrdev = ctx->jrdev;
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300664
665 if (keylen < 4)
666 return -EINVAL;
667
668#ifdef DEBUG
669 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
670 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
671#endif
672
673 memcpy(ctx->key, key, keylen);
674
675 /*
676 * The last four bytes of the key material are used as the salt value
677 * in the nonce. Update the AES key length.
678 */
Horia Geantădb576562016-11-22 15:44:04 +0200679 ctx->cdata.keylen = keylen - 4;
Horia Geantăbbf22342017-02-10 14:07:22 +0200680 dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200681 ctx->dir);
Horia Geantăbbf22342017-02-10 14:07:22 +0200682 return rfc4106_set_sh_desc(aead);
Tudor Ambarusbac68f22014-10-23 16:14:03 +0300683}
684
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200685static int rfc4543_setkey(struct crypto_aead *aead,
686 const u8 *key, unsigned int keylen)
687{
688 struct caam_ctx *ctx = crypto_aead_ctx(aead);
689 struct device *jrdev = ctx->jrdev;
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200690
691 if (keylen < 4)
692 return -EINVAL;
693
694#ifdef DEBUG
695 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
696 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
697#endif
698
699 memcpy(ctx->key, key, keylen);
700
701 /*
702 * The last four bytes of the key material are used as the salt value
703 * in the nonce. Update the AES key length.
704 */
Horia Geantădb576562016-11-22 15:44:04 +0200705 ctx->cdata.keylen = keylen - 4;
Horia Geantăbbf22342017-02-10 14:07:22 +0200706 dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200707 ctx->dir);
Horia Geantăbbf22342017-02-10 14:07:22 +0200708 return rfc4543_set_sh_desc(aead);
Tudor Ambarus5d0429a2014-10-30 18:55:07 +0200709}
710
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300711static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
712 unsigned int keylen)
Yuan Kangacdca312011-07-15 11:21:42 +0800713{
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300714 struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
715 struct caam_skcipher_alg *alg =
716 container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
717 skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +0800718 struct device *jrdev = ctx->jrdev;
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300719 unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +0800720 u32 *desc;
Catalin Vasile2b22f6c2014-10-31 12:45:35 +0200721 u32 ctx1_iv_off = 0;
Horia Geantădb576562016-11-22 15:44:04 +0200722 const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
Catalin Vasile2b22f6c2014-10-31 12:45:35 +0200723 OP_ALG_AAI_CTR_MOD128);
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300724 const bool is_rfc3686 = alg->caam.rfc3686;
Yuan Kangacdca312011-07-15 11:21:42 +0800725
726#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +0300727 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
Yuan Kangacdca312011-07-15 11:21:42 +0800728 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
729#endif
Catalin Vasile2b22f6c2014-10-31 12:45:35 +0200730 /*
731 * AES-CTR needs to load IV in CONTEXT1 reg
732 * at an offset of 128bits (16bytes)
733 * CONTEXT1[255:128] = IV
734 */
735 if (ctr_mode)
736 ctx1_iv_off = 16;
Yuan Kangacdca312011-07-15 11:21:42 +0800737
Catalin Vasilea5f57cf2014-10-31 12:45:36 +0200738 /*
739 * RFC3686 specific:
740 * | CONTEXT1[255:128] = {NONCE, IV, COUNTER}
741 * | *key = {KEY, NONCE}
742 */
743 if (is_rfc3686) {
744 ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
745 keylen -= CTR_RFC3686_NONCE_SIZE;
746 }
747
Horia Geantădb576562016-11-22 15:44:04 +0200748 ctx->cdata.keylen = keylen;
Horia Geantă662f70e2017-12-19 12:16:05 +0200749 ctx->cdata.key_virt = key;
Horia Geantădb576562016-11-22 15:44:04 +0200750 ctx->cdata.key_inline = true;
Yuan Kangacdca312011-07-15 11:21:42 +0800751
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300752 /* skcipher_encrypt shared descriptor */
Yuan Kangacdca312011-07-15 11:21:42 +0800753 desc = ctx->sh_desc_enc;
Horia Geantă9dbe3072018-08-06 15:44:00 +0300754 cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
755 ctx1_iv_off);
Horia Geantăbbf22342017-02-10 14:07:22 +0200756 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200757 desc_bytes(desc), ctx->dir);
Horia Geantă8cea7b62016-11-22 15:44:09 +0200758
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300759 /* skcipher_decrypt shared descriptor */
Yuan Kangacdca312011-07-15 11:21:42 +0800760 desc = ctx->sh_desc_dec;
Horia Geantă9dbe3072018-08-06 15:44:00 +0300761 cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
762 ctx1_iv_off);
Horia Geantăbbf22342017-02-10 14:07:22 +0200763 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200764 desc_bytes(desc), ctx->dir);
Yuan Kangacdca312011-07-15 11:21:42 +0800765
Horia Geantă8cea7b62016-11-22 15:44:09 +0200766 return 0;
Yuan Kangacdca312011-07-15 11:21:42 +0800767}
768
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300769static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
770 unsigned int keylen)
Catalin Vasilec6415a62015-10-02 13:13:18 +0300771{
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300772 struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
Catalin Vasilec6415a62015-10-02 13:13:18 +0300773 struct device *jrdev = ctx->jrdev;
Horia Geantă8cea7b62016-11-22 15:44:09 +0200774 u32 *desc;
Catalin Vasilec6415a62015-10-02 13:13:18 +0300775
776 if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) {
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300777 crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
Catalin Vasilec6415a62015-10-02 13:13:18 +0300778 dev_err(jrdev, "key size mismatch\n");
779 return -EINVAL;
780 }
781
Horia Geantădb576562016-11-22 15:44:04 +0200782 ctx->cdata.keylen = keylen;
Horia Geantă662f70e2017-12-19 12:16:05 +0200783 ctx->cdata.key_virt = key;
Horia Geantădb576562016-11-22 15:44:04 +0200784 ctx->cdata.key_inline = true;
Catalin Vasilec6415a62015-10-02 13:13:18 +0300785
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300786 /* xts_skcipher_encrypt shared descriptor */
Catalin Vasilec6415a62015-10-02 13:13:18 +0300787 desc = ctx->sh_desc_enc;
Horia Geantă9dbe3072018-08-06 15:44:00 +0300788 cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata);
Horia Geantăbbf22342017-02-10 14:07:22 +0200789 dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200790 desc_bytes(desc), ctx->dir);
Catalin Vasilec6415a62015-10-02 13:13:18 +0300791
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300792 /* xts_skcipher_decrypt shared descriptor */
Catalin Vasilec6415a62015-10-02 13:13:18 +0300793 desc = ctx->sh_desc_dec;
Horia Geantă9dbe3072018-08-06 15:44:00 +0300794 cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata);
Horia Geantăbbf22342017-02-10 14:07:22 +0200795 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
Horia Geantă7e0880b2017-12-19 12:16:07 +0200796 desc_bytes(desc), ctx->dir);
Catalin Vasilec6415a62015-10-02 13:13:18 +0300797
798 return 0;
799}
800
Kim Phillips8e8ec592011-03-13 16:54:26 +0800801/*
Yuan Kang1acebad2011-07-15 11:21:42 +0800802 * aead_edesc - s/w-extended aead descriptor
Horia Geantăfa0c92d2017-02-10 14:07:19 +0200803 * @src_nents: number of segments in input s/w scatterlist
804 * @dst_nents: number of segments in output s/w scatterlist
Yuan Kanga299c832012-06-22 19:48:46 -0500805 * @sec4_sg_bytes: length of dma mapped sec4_sg space
806 * @sec4_sg_dma: bus physical mapped address of h/w link table
Horia Geantă4ca7c7d2016-11-09 10:46:18 +0200807 * @sec4_sg: pointer to h/w link table
Kim Phillips8e8ec592011-03-13 16:54:26 +0800808 * @hw_desc: the h/w job descriptor followed by any referenced link tables
809 */
Yuan Kang0e479302011-07-15 11:21:41 +0800810struct aead_edesc {
Kim Phillips8e8ec592011-03-13 16:54:26 +0800811 int src_nents;
812 int dst_nents;
Yuan Kanga299c832012-06-22 19:48:46 -0500813 int sec4_sg_bytes;
814 dma_addr_t sec4_sg_dma;
815 struct sec4_sg_entry *sec4_sg;
Herbert Xuf2147b82015-06-16 13:54:23 +0800816 u32 hw_desc[];
Kim Phillips8e8ec592011-03-13 16:54:26 +0800817};
818
Yuan Kangacdca312011-07-15 11:21:42 +0800819/*
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300820 * skcipher_edesc - s/w-extended skcipher descriptor
Horia Geantăfa0c92d2017-02-10 14:07:19 +0200821 * @src_nents: number of segments in input s/w scatterlist
822 * @dst_nents: number of segments in output s/w scatterlist
Yuan Kangacdca312011-07-15 11:21:42 +0800823 * @iv_dma: dma address of iv for checking continuity and link table
Yuan Kanga299c832012-06-22 19:48:46 -0500824 * @sec4_sg_bytes: length of dma mapped sec4_sg space
825 * @sec4_sg_dma: bus physical mapped address of h/w link table
Horia Geantă4ca7c7d2016-11-09 10:46:18 +0200826 * @sec4_sg: pointer to h/w link table
Yuan Kangacdca312011-07-15 11:21:42 +0800827 * @hw_desc: the h/w job descriptor followed by any referenced link tables
Horia Geantă115957b2018-03-28 15:39:18 +0300828 * and IV
Yuan Kangacdca312011-07-15 11:21:42 +0800829 */
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300830struct skcipher_edesc {
Yuan Kangacdca312011-07-15 11:21:42 +0800831 int src_nents;
832 int dst_nents;
833 dma_addr_t iv_dma;
Yuan Kanga299c832012-06-22 19:48:46 -0500834 int sec4_sg_bytes;
835 dma_addr_t sec4_sg_dma;
836 struct sec4_sg_entry *sec4_sg;
Yuan Kangacdca312011-07-15 11:21:42 +0800837 u32 hw_desc[0];
838};
839
Yuan Kang1acebad2011-07-15 11:21:42 +0800840static void caam_unmap(struct device *dev, struct scatterlist *src,
Yuan Kang643b39b2012-06-22 19:48:49 -0500841 struct scatterlist *dst, int src_nents,
LABBE Corentin13fb8fd2015-09-23 13:55:27 +0200842 int dst_nents,
Horia Geantăcf5448b2018-08-06 15:43:57 +0300843 dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
Yuan Kanga299c832012-06-22 19:48:46 -0500844 int sec4_sg_bytes)
Kim Phillips8e8ec592011-03-13 16:54:26 +0800845{
Yuan Kang643b39b2012-06-22 19:48:49 -0500846 if (dst != src) {
Horia Geantăfa0c92d2017-02-10 14:07:19 +0200847 if (src_nents)
848 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
Horia Geantă763069b2019-01-22 16:47:01 +0200849 if (dst_nents)
850 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800851 } else {
Horia Geantăfa0c92d2017-02-10 14:07:19 +0200852 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
Kim Phillips8e8ec592011-03-13 16:54:26 +0800853 }
854
Yuan Kang1acebad2011-07-15 11:21:42 +0800855 if (iv_dma)
Horia Geantăcf5448b2018-08-06 15:43:57 +0300856 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
Yuan Kanga299c832012-06-22 19:48:46 -0500857 if (sec4_sg_bytes)
858 dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
Kim Phillips8e8ec592011-03-13 16:54:26 +0800859 DMA_TO_DEVICE);
860}
861
Yuan Kang1acebad2011-07-15 11:21:42 +0800862static void aead_unmap(struct device *dev,
863 struct aead_edesc *edesc,
864 struct aead_request *req)
865{
Herbert Xuf2147b82015-06-16 13:54:23 +0800866 caam_unmap(dev, req->src, req->dst,
Horia Geantăcf5448b2018-08-06 15:43:57 +0300867 edesc->src_nents, edesc->dst_nents, 0, 0,
Herbert Xuf2147b82015-06-16 13:54:23 +0800868 edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
869}
870
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300871static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
872 struct skcipher_request *req)
Yuan Kangacdca312011-07-15 11:21:42 +0800873{
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300874 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
875 int ivsize = crypto_skcipher_ivsize(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +0800876
877 caam_unmap(dev, req->src, req->dst,
LABBE Corentin13fb8fd2015-09-23 13:55:27 +0200878 edesc->src_nents, edesc->dst_nents,
Horia Geantăcf5448b2018-08-06 15:43:57 +0300879 edesc->iv_dma, ivsize,
Yuan Kang643b39b2012-06-22 19:48:49 -0500880 edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
Yuan Kangacdca312011-07-15 11:21:42 +0800881}
882
Yuan Kang0e479302011-07-15 11:21:41 +0800883static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
Kim Phillips8e8ec592011-03-13 16:54:26 +0800884 void *context)
885{
Yuan Kang0e479302011-07-15 11:21:41 +0800886 struct aead_request *req = context;
887 struct aead_edesc *edesc;
Herbert Xuf2147b82015-06-16 13:54:23 +0800888
889#ifdef DEBUG
890 dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
891#endif
892
893 edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
894
895 if (err)
896 caam_jr_strstatus(jrdev, err);
897
898 aead_unmap(jrdev, edesc, req);
899
900 kfree(edesc);
901
902 aead_request_complete(req, err);
903}
904
Yuan Kang0e479302011-07-15 11:21:41 +0800905static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
Kim Phillips8e8ec592011-03-13 16:54:26 +0800906 void *context)
907{
Yuan Kang0e479302011-07-15 11:21:41 +0800908 struct aead_request *req = context;
909 struct aead_edesc *edesc;
Herbert Xuf2147b82015-06-16 13:54:23 +0800910
911#ifdef DEBUG
912 dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
913#endif
914
915 edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
916
917 if (err)
918 caam_jr_strstatus(jrdev, err);
919
920 aead_unmap(jrdev, edesc, req);
921
922 /*
923 * verify hw auth check passed else return -EBADMSG
924 */
925 if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
926 err = -EBADMSG;
927
928 kfree(edesc);
929
930 aead_request_complete(req, err);
931}
932
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300933static void skcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
934 void *context)
Yuan Kangacdca312011-07-15 11:21:42 +0800935{
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300936 struct skcipher_request *req = context;
937 struct skcipher_edesc *edesc;
938 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
939 int ivsize = crypto_skcipher_ivsize(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +0800940
David Gstir854b06f2017-06-28 15:27:10 +0200941#ifdef DEBUG
Yuan Kangacdca312011-07-15 11:21:42 +0800942 dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
943#endif
944
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300945 edesc = container_of(desc, struct skcipher_edesc, hw_desc[0]);
Yuan Kangacdca312011-07-15 11:21:42 +0800946
Marek Vasutfa9659c2014-04-24 20:05:12 +0200947 if (err)
948 caam_jr_strstatus(jrdev, err);
Yuan Kangacdca312011-07-15 11:21:42 +0800949
950#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +0300951 print_hex_dump(KERN_ERR, "dstiv @"__stringify(__LINE__)": ",
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300952 DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
Yuan Kangacdca312011-07-15 11:21:42 +0800953 edesc->src_nents > 1 ? 100 : ivsize, 1);
Yuan Kangacdca312011-07-15 11:21:42 +0800954#endif
Horia Geantă972b8122017-07-10 08:40:28 +0300955 caam_dump_sg(KERN_ERR, "dst @" __stringify(__LINE__)": ",
956 DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300957 edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
Yuan Kangacdca312011-07-15 11:21:42 +0800958
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300959 skcipher_unmap(jrdev, edesc, req);
David Gstir854b06f2017-06-28 15:27:10 +0200960
961 /*
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300962 * The crypto API expects us to set the IV (req->iv) to the last
David Gstir854b06f2017-06-28 15:27:10 +0200963 * ciphertext block. This is used e.g. by the CTS mode.
964 */
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300965 scatterwalk_map_and_copy(req->iv, req->dst, req->cryptlen - ivsize,
David Gstir854b06f2017-06-28 15:27:10 +0200966 ivsize, 0);
967
Yuan Kangacdca312011-07-15 11:21:42 +0800968 kfree(edesc);
969
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300970 skcipher_request_complete(req, err);
Yuan Kangacdca312011-07-15 11:21:42 +0800971}
972
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300973static void skcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
974 void *context)
Yuan Kangacdca312011-07-15 11:21:42 +0800975{
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300976 struct skcipher_request *req = context;
977 struct skcipher_edesc *edesc;
Horia Geantă115957b2018-03-28 15:39:18 +0300978#ifdef DEBUG
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300979 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
980 int ivsize = crypto_skcipher_ivsize(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +0800981
982 dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
983#endif
984
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300985 edesc = container_of(desc, struct skcipher_edesc, hw_desc[0]);
Marek Vasutfa9659c2014-04-24 20:05:12 +0200986 if (err)
987 caam_jr_strstatus(jrdev, err);
Yuan Kangacdca312011-07-15 11:21:42 +0800988
989#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +0300990 print_hex_dump(KERN_ERR, "dstiv @"__stringify(__LINE__)": ",
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300991 DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
Yuan Kangacdca312011-07-15 11:21:42 +0800992#endif
Horia Geantă972b8122017-07-10 08:40:28 +0300993 caam_dump_sg(KERN_ERR, "dst @" __stringify(__LINE__)": ",
994 DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300995 edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
Yuan Kangacdca312011-07-15 11:21:42 +0800996
Horia Geantă5ca7bad2018-08-06 15:43:59 +0300997 skcipher_unmap(jrdev, edesc, req);
Yuan Kangacdca312011-07-15 11:21:42 +0800998 kfree(edesc);
999
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001000 skcipher_request_complete(req, err);
Yuan Kangacdca312011-07-15 11:21:42 +08001001}
1002
Kim Phillips8e8ec592011-03-13 16:54:26 +08001003/*
Yuan Kang1acebad2011-07-15 11:21:42 +08001004 * Fill in aead job descriptor
Kim Phillips8e8ec592011-03-13 16:54:26 +08001005 */
Herbert Xuf2147b82015-06-16 13:54:23 +08001006static void init_aead_job(struct aead_request *req,
1007 struct aead_edesc *edesc,
1008 bool all_contig, bool encrypt)
1009{
1010 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1011 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1012 int authsize = ctx->authsize;
1013 u32 *desc = edesc->hw_desc;
1014 u32 out_options, in_options;
1015 dma_addr_t dst_dma, src_dma;
1016 int len, sec4_sg_index = 0;
1017 dma_addr_t ptr;
1018 u32 *sh_desc;
1019
1020 sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1021 ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1022
1023 len = desc_len(sh_desc);
1024 init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1025
1026 if (all_contig) {
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001027 src_dma = edesc->src_nents ? sg_dma_address(req->src) : 0;
Herbert Xuf2147b82015-06-16 13:54:23 +08001028 in_options = 0;
1029 } else {
1030 src_dma = edesc->sec4_sg_dma;
1031 sec4_sg_index += edesc->src_nents;
1032 in_options = LDST_SGF;
1033 }
1034
1035 append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1036 in_options);
1037
1038 dst_dma = src_dma;
1039 out_options = in_options;
1040
1041 if (unlikely(req->src != req->dst)) {
Horia Geantă763069b2019-01-22 16:47:01 +02001042 if (!edesc->dst_nents) {
1043 dst_dma = 0;
1044 } else if (edesc->dst_nents == 1) {
Herbert Xuf2147b82015-06-16 13:54:23 +08001045 dst_dma = sg_dma_address(req->dst);
Pankaj Gupta42e95d12019-02-01 07:18:20 +00001046 out_options = 0;
Herbert Xuf2147b82015-06-16 13:54:23 +08001047 } else {
1048 dst_dma = edesc->sec4_sg_dma +
1049 sec4_sg_index *
1050 sizeof(struct sec4_sg_entry);
1051 out_options = LDST_SGF;
1052 }
1053 }
1054
1055 if (encrypt)
1056 append_seq_out_ptr(desc, dst_dma,
1057 req->assoclen + req->cryptlen + authsize,
1058 out_options);
1059 else
1060 append_seq_out_ptr(desc, dst_dma,
1061 req->assoclen + req->cryptlen - authsize,
1062 out_options);
Herbert Xuf2147b82015-06-16 13:54:23 +08001063}
1064
1065static void init_gcm_job(struct aead_request *req,
1066 struct aead_edesc *edesc,
1067 bool all_contig, bool encrypt)
1068{
1069 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1070 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1071 unsigned int ivsize = crypto_aead_ivsize(aead);
1072 u32 *desc = edesc->hw_desc;
Corentin LABBE7545e162017-08-22 10:08:09 +02001073 bool generic_gcm = (ivsize == GCM_AES_IV_SIZE);
Herbert Xuf2147b82015-06-16 13:54:23 +08001074 unsigned int last;
1075
1076 init_aead_job(req, edesc, all_contig, encrypt);
Horia Geantă7e0880b2017-12-19 12:16:07 +02001077 append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
Herbert Xuf2147b82015-06-16 13:54:23 +08001078
1079 /* BUG This should not be specific to generic GCM. */
1080 last = 0;
1081 if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1082 last = FIFOLD_TYPE_LAST1;
1083
1084 /* Read GCM IV */
1085 append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
Corentin LABBE7545e162017-08-22 10:08:09 +02001086 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | GCM_AES_IV_SIZE | last);
Herbert Xuf2147b82015-06-16 13:54:23 +08001087 /* Append Salt */
1088 if (!generic_gcm)
Horia Geantădb576562016-11-22 15:44:04 +02001089 append_data(desc, ctx->key + ctx->cdata.keylen, 4);
Herbert Xuf2147b82015-06-16 13:54:23 +08001090 /* Append IV */
1091 append_data(desc, req->iv, ivsize);
1092 /* End of blank commands */
1093}
1094
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02001095static void init_chachapoly_job(struct aead_request *req,
1096 struct aead_edesc *edesc, bool all_contig,
1097 bool encrypt)
1098{
1099 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1100 unsigned int ivsize = crypto_aead_ivsize(aead);
1101 unsigned int assoclen = req->assoclen;
1102 u32 *desc = edesc->hw_desc;
1103 u32 ctx_iv_off = 4;
1104
1105 init_aead_job(req, edesc, all_contig, encrypt);
1106
1107 if (ivsize != CHACHAPOLY_IV_SIZE) {
1108 /* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
1109 ctx_iv_off += 4;
1110
1111 /*
1112 * The associated data comes already with the IV but we need
1113 * to skip it when we authenticate or encrypt...
1114 */
1115 assoclen -= ivsize;
1116 }
1117
1118 append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
1119
1120 /*
1121 * For IPsec load the IV further in the same register.
1122 * For RFC7539 simply load the 12 bytes nonce in a single operation
1123 */
1124 append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
1125 LDST_SRCDST_BYTE_CONTEXT |
1126 ctx_iv_off << LDST_OFFSET_SHIFT);
1127}
1128
Herbert Xu479bcc72015-07-30 17:53:17 +08001129static void init_authenc_job(struct aead_request *req,
1130 struct aead_edesc *edesc,
1131 bool all_contig, bool encrypt)
Yuan Kang1acebad2011-07-15 11:21:42 +08001132{
1133 struct crypto_aead *aead = crypto_aead_reqtfm(req);
Herbert Xu479bcc72015-07-30 17:53:17 +08001134 struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1135 struct caam_aead_alg, aead);
1136 unsigned int ivsize = crypto_aead_ivsize(aead);
Yuan Kang1acebad2011-07-15 11:21:42 +08001137 struct caam_ctx *ctx = crypto_aead_ctx(aead);
Horia Geantă7e0880b2017-12-19 12:16:07 +02001138 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
Horia Geantădb576562016-11-22 15:44:04 +02001139 const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
Herbert Xu479bcc72015-07-30 17:53:17 +08001140 OP_ALG_AAI_CTR_MOD128);
1141 const bool is_rfc3686 = alg->caam.rfc3686;
Yuan Kang1acebad2011-07-15 11:21:42 +08001142 u32 *desc = edesc->hw_desc;
Herbert Xu479bcc72015-07-30 17:53:17 +08001143 u32 ivoffset = 0;
Kim Phillips8e8ec592011-03-13 16:54:26 +08001144
Herbert Xu479bcc72015-07-30 17:53:17 +08001145 /*
1146 * AES-CTR needs to load IV in CONTEXT1 reg
1147 * at an offset of 128bits (16bytes)
1148 * CONTEXT1[255:128] = IV
1149 */
1150 if (ctr_mode)
1151 ivoffset = 16;
Kim Phillips8e8ec592011-03-13 16:54:26 +08001152
Herbert Xu479bcc72015-07-30 17:53:17 +08001153 /*
1154 * RFC3686 specific:
1155 * CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1156 */
1157 if (is_rfc3686)
1158 ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
Tudor Ambarusbac68f22014-10-23 16:14:03 +03001159
Herbert Xu479bcc72015-07-30 17:53:17 +08001160 init_aead_job(req, edesc, all_contig, encrypt);
Yuan Kang1acebad2011-07-15 11:21:42 +08001161
Horia Geantă7e0880b2017-12-19 12:16:07 +02001162 /*
1163 * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
1164 * having DPOVRD as destination.
1165 */
1166 if (ctrlpriv->era < 3)
1167 append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1168 else
1169 append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
1170
Horia Geantă8b18e232016-08-29 14:52:14 +03001171 if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
Herbert Xu479bcc72015-07-30 17:53:17 +08001172 append_load_as_imm(desc, req->iv, ivsize,
1173 LDST_CLASS_1_CCB |
1174 LDST_SRCDST_BYTE_CONTEXT |
1175 (ivoffset << LDST_OFFSET_SHIFT));
Kim Phillips8e8ec592011-03-13 16:54:26 +08001176}
1177
1178/*
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001179 * Fill in skcipher job descriptor
Yuan Kangacdca312011-07-15 11:21:42 +08001180 */
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001181static void init_skcipher_job(struct skcipher_request *req,
1182 struct skcipher_edesc *edesc,
1183 const bool encrypt)
Yuan Kangacdca312011-07-15 11:21:42 +08001184{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001185 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1186 struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1187 int ivsize = crypto_skcipher_ivsize(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +08001188 u32 *desc = edesc->hw_desc;
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001189 u32 *sh_desc;
Horia Geantă115957b2018-03-28 15:39:18 +03001190 u32 out_options = 0;
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001191 dma_addr_t dst_dma, ptr;
Horia Geantă115957b2018-03-28 15:39:18 +03001192 int len;
Yuan Kangacdca312011-07-15 11:21:42 +08001193
1194#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +03001195 print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001196 DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
1197 pr_err("asked=%d, cryptlen%d\n",
1198 (int)edesc->src_nents > 1 ? 100 : req->cryptlen, req->cryptlen);
Yuan Kangacdca312011-07-15 11:21:42 +08001199#endif
Horia Geantă972b8122017-07-10 08:40:28 +03001200 caam_dump_sg(KERN_ERR, "src @" __stringify(__LINE__)": ",
1201 DUMP_PREFIX_ADDRESS, 16, 4, req->src,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001202 edesc->src_nents > 1 ? 100 : req->cryptlen, 1);
1203
1204 sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1205 ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
Yuan Kangacdca312011-07-15 11:21:42 +08001206
1207 len = desc_len(sh_desc);
1208 init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1209
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001210 append_seq_in_ptr(desc, edesc->sec4_sg_dma, req->cryptlen + ivsize,
Horia Geantă115957b2018-03-28 15:39:18 +03001211 LDST_SGF);
Yuan Kangacdca312011-07-15 11:21:42 +08001212
1213 if (likely(req->src == req->dst)) {
Horia Geantă115957b2018-03-28 15:39:18 +03001214 dst_dma = edesc->sec4_sg_dma + sizeof(struct sec4_sg_entry);
1215 out_options = LDST_SGF;
Yuan Kangacdca312011-07-15 11:21:42 +08001216 } else {
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001217 if (edesc->dst_nents == 1) {
Yuan Kangacdca312011-07-15 11:21:42 +08001218 dst_dma = sg_dma_address(req->dst);
1219 } else {
Horia Geantă115957b2018-03-28 15:39:18 +03001220 dst_dma = edesc->sec4_sg_dma + (edesc->src_nents + 1) *
1221 sizeof(struct sec4_sg_entry);
Yuan Kangacdca312011-07-15 11:21:42 +08001222 out_options = LDST_SGF;
1223 }
1224 }
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001225 append_seq_out_ptr(desc, dst_dma, req->cryptlen, out_options);
Yuan Kangacdca312011-07-15 11:21:42 +08001226}
1227
1228/*
Yuan Kang1acebad2011-07-15 11:21:42 +08001229 * allocate and map the aead extended descriptor
Kim Phillips8e8ec592011-03-13 16:54:26 +08001230 */
Herbert Xuf2147b82015-06-16 13:54:23 +08001231static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1232 int desc_bytes, bool *all_contig_ptr,
1233 bool encrypt)
1234{
1235 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1236 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1237 struct device *jrdev = ctx->jrdev;
Horia Geantă019d62d2017-06-19 11:44:46 +03001238 gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1239 GFP_KERNEL : GFP_ATOMIC;
Horia Geantă838e0a82017-02-10 14:07:20 +02001240 int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
Herbert Xuf2147b82015-06-16 13:54:23 +08001241 struct aead_edesc *edesc;
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001242 int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
Herbert Xuf2147b82015-06-16 13:54:23 +08001243 unsigned int authsize = ctx->authsize;
1244
1245 if (unlikely(req->dst != req->src)) {
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001246 src_nents = sg_nents_for_len(req->src, req->assoclen +
1247 req->cryptlen);
Horia Geantăfd144d82017-02-10 14:07:18 +02001248 if (unlikely(src_nents < 0)) {
1249 dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1250 req->assoclen + req->cryptlen);
1251 return ERR_PTR(src_nents);
1252 }
1253
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001254 dst_nents = sg_nents_for_len(req->dst, req->assoclen +
1255 req->cryptlen +
1256 (encrypt ? authsize :
1257 (-authsize)));
Horia Geantăfd144d82017-02-10 14:07:18 +02001258 if (unlikely(dst_nents < 0)) {
1259 dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1260 req->assoclen + req->cryptlen +
1261 (encrypt ? authsize : (-authsize)));
1262 return ERR_PTR(dst_nents);
1263 }
Herbert Xuf2147b82015-06-16 13:54:23 +08001264 } else {
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001265 src_nents = sg_nents_for_len(req->src, req->assoclen +
1266 req->cryptlen +
1267 (encrypt ? authsize : 0));
Horia Geantăfd144d82017-02-10 14:07:18 +02001268 if (unlikely(src_nents < 0)) {
1269 dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1270 req->assoclen + req->cryptlen +
1271 (encrypt ? authsize : 0));
1272 return ERR_PTR(src_nents);
1273 }
Herbert Xuf2147b82015-06-16 13:54:23 +08001274 }
1275
Horia Geantă838e0a82017-02-10 14:07:20 +02001276 if (likely(req->src == req->dst)) {
1277 mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1278 DMA_BIDIRECTIONAL);
1279 if (unlikely(!mapped_src_nents)) {
1280 dev_err(jrdev, "unable to map source\n");
1281 return ERR_PTR(-ENOMEM);
1282 }
1283 } else {
1284 /* Cover also the case of null (zero length) input data */
1285 if (src_nents) {
1286 mapped_src_nents = dma_map_sg(jrdev, req->src,
1287 src_nents, DMA_TO_DEVICE);
1288 if (unlikely(!mapped_src_nents)) {
1289 dev_err(jrdev, "unable to map source\n");
1290 return ERR_PTR(-ENOMEM);
1291 }
1292 } else {
1293 mapped_src_nents = 0;
1294 }
1295
Horia Geantă763069b2019-01-22 16:47:01 +02001296 /* Cover also the case of null (zero length) output data */
1297 if (dst_nents) {
1298 mapped_dst_nents = dma_map_sg(jrdev, req->dst,
1299 dst_nents,
1300 DMA_FROM_DEVICE);
1301 if (unlikely(!mapped_dst_nents)) {
1302 dev_err(jrdev, "unable to map destination\n");
1303 dma_unmap_sg(jrdev, req->src, src_nents,
1304 DMA_TO_DEVICE);
1305 return ERR_PTR(-ENOMEM);
1306 }
1307 } else {
1308 mapped_dst_nents = 0;
Horia Geantă838e0a82017-02-10 14:07:20 +02001309 }
1310 }
1311
1312 sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1313 sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
Herbert Xuf2147b82015-06-16 13:54:23 +08001314 sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1315
1316 /* allocate space for base edesc and hw desc commands, link tables */
Victoria Milhoandde20ae2015-08-05 11:28:39 -07001317 edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1318 GFP_DMA | flags);
Herbert Xuf2147b82015-06-16 13:54:23 +08001319 if (!edesc) {
Horia Geantă838e0a82017-02-10 14:07:20 +02001320 caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
Horia Geantăcf5448b2018-08-06 15:43:57 +03001321 0, 0, 0);
Herbert Xuf2147b82015-06-16 13:54:23 +08001322 return ERR_PTR(-ENOMEM);
1323 }
1324
Herbert Xuf2147b82015-06-16 13:54:23 +08001325 edesc->src_nents = src_nents;
Herbert Xuf2147b82015-06-16 13:54:23 +08001326 edesc->dst_nents = dst_nents;
Herbert Xuf2147b82015-06-16 13:54:23 +08001327 edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1328 desc_bytes;
Horia Geantă838e0a82017-02-10 14:07:20 +02001329 *all_contig_ptr = !(mapped_src_nents > 1);
Herbert Xuf2147b82015-06-16 13:54:23 +08001330
1331 sec4_sg_index = 0;
Horia Geantă838e0a82017-02-10 14:07:20 +02001332 if (mapped_src_nents > 1) {
1333 sg_to_sec4_sg_last(req->src, mapped_src_nents,
1334 edesc->sec4_sg + sec4_sg_index, 0);
1335 sec4_sg_index += mapped_src_nents;
Herbert Xuf2147b82015-06-16 13:54:23 +08001336 }
Horia Geantă838e0a82017-02-10 14:07:20 +02001337 if (mapped_dst_nents > 1) {
1338 sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
Herbert Xuf2147b82015-06-16 13:54:23 +08001339 edesc->sec4_sg + sec4_sg_index, 0);
1340 }
1341
1342 if (!sec4_sg_bytes)
1343 return edesc;
1344
1345 edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1346 sec4_sg_bytes, DMA_TO_DEVICE);
1347 if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1348 dev_err(jrdev, "unable to map S/G table\n");
1349 aead_unmap(jrdev, edesc, req);
1350 kfree(edesc);
1351 return ERR_PTR(-ENOMEM);
1352 }
1353
1354 edesc->sec4_sg_bytes = sec4_sg_bytes;
1355
1356 return edesc;
1357}
1358
1359static int gcm_encrypt(struct aead_request *req)
Kim Phillips8e8ec592011-03-13 16:54:26 +08001360{
Yuan Kang0e479302011-07-15 11:21:41 +08001361 struct aead_edesc *edesc;
Kim Phillips8e8ec592011-03-13 16:54:26 +08001362 struct crypto_aead *aead = crypto_aead_reqtfm(req);
Kim Phillips8e8ec592011-03-13 16:54:26 +08001363 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1364 struct device *jrdev = ctx->jrdev;
Yuan Kang1acebad2011-07-15 11:21:42 +08001365 bool all_contig;
Kim Phillips8e8ec592011-03-13 16:54:26 +08001366 u32 *desc;
Yuan Kang1acebad2011-07-15 11:21:42 +08001367 int ret = 0;
1368
Kim Phillips8e8ec592011-03-13 16:54:26 +08001369 /* allocate extended descriptor */
Herbert Xuf2147b82015-06-16 13:54:23 +08001370 edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
Kim Phillips8e8ec592011-03-13 16:54:26 +08001371 if (IS_ERR(edesc))
1372 return PTR_ERR(edesc);
1373
Yuan Kang1acebad2011-07-15 11:21:42 +08001374 /* Create and submit job descriptor */
Herbert Xuf2147b82015-06-16 13:54:23 +08001375 init_gcm_job(req, edesc, all_contig, true);
Yuan Kang1acebad2011-07-15 11:21:42 +08001376#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +03001377 print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
Yuan Kang1acebad2011-07-15 11:21:42 +08001378 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1379 desc_bytes(edesc->hw_desc), 1);
1380#endif
1381
Kim Phillips8e8ec592011-03-13 16:54:26 +08001382 desc = edesc->hw_desc;
Yuan Kang1acebad2011-07-15 11:21:42 +08001383 ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1384 if (!ret) {
1385 ret = -EINPROGRESS;
1386 } else {
1387 aead_unmap(jrdev, edesc, req);
1388 kfree(edesc);
1389 }
Kim Phillips8e8ec592011-03-13 16:54:26 +08001390
Yuan Kang1acebad2011-07-15 11:21:42 +08001391 return ret;
Kim Phillips8e8ec592011-03-13 16:54:26 +08001392}
1393
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02001394static int chachapoly_encrypt(struct aead_request *req)
1395{
1396 struct aead_edesc *edesc;
1397 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1398 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1399 struct device *jrdev = ctx->jrdev;
1400 bool all_contig;
1401 u32 *desc;
1402 int ret;
1403
1404 edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1405 true);
1406 if (IS_ERR(edesc))
1407 return PTR_ERR(edesc);
1408
1409 desc = edesc->hw_desc;
1410
1411 init_chachapoly_job(req, edesc, all_contig, true);
1412 print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1413 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1414 1);
1415
1416 ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1417 if (!ret) {
1418 ret = -EINPROGRESS;
1419 } else {
1420 aead_unmap(jrdev, edesc, req);
1421 kfree(edesc);
1422 }
1423
1424 return ret;
1425}
1426
1427static int chachapoly_decrypt(struct aead_request *req)
1428{
1429 struct aead_edesc *edesc;
1430 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1431 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1432 struct device *jrdev = ctx->jrdev;
1433 bool all_contig;
1434 u32 *desc;
1435 int ret;
1436
1437 edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1438 false);
1439 if (IS_ERR(edesc))
1440 return PTR_ERR(edesc);
1441
1442 desc = edesc->hw_desc;
1443
1444 init_chachapoly_job(req, edesc, all_contig, false);
1445 print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1446 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1447 1);
1448
1449 ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1450 if (!ret) {
1451 ret = -EINPROGRESS;
1452 } else {
1453 aead_unmap(jrdev, edesc, req);
1454 kfree(edesc);
1455 }
1456
1457 return ret;
1458}
1459
Herbert Xu46218752015-07-09 07:17:33 +08001460static int ipsec_gcm_encrypt(struct aead_request *req)
1461{
1462 if (req->assoclen < 8)
1463 return -EINVAL;
1464
1465 return gcm_encrypt(req);
1466}
1467
Herbert Xu479bcc72015-07-30 17:53:17 +08001468static int aead_encrypt(struct aead_request *req)
Kim Phillips8e8ec592011-03-13 16:54:26 +08001469{
Yuan Kang1acebad2011-07-15 11:21:42 +08001470 struct aead_edesc *edesc;
Yuan Kang0e479302011-07-15 11:21:41 +08001471 struct crypto_aead *aead = crypto_aead_reqtfm(req);
Yuan Kang0e479302011-07-15 11:21:41 +08001472 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1473 struct device *jrdev = ctx->jrdev;
Yuan Kang1acebad2011-07-15 11:21:42 +08001474 bool all_contig;
Yuan Kang0e479302011-07-15 11:21:41 +08001475 u32 *desc;
Yuan Kang1acebad2011-07-15 11:21:42 +08001476 int ret = 0;
Yuan Kang0e479302011-07-15 11:21:41 +08001477
1478 /* allocate extended descriptor */
Herbert Xu479bcc72015-07-30 17:53:17 +08001479 edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1480 &all_contig, true);
Yuan Kang0e479302011-07-15 11:21:41 +08001481 if (IS_ERR(edesc))
1482 return PTR_ERR(edesc);
1483
Herbert Xuf2147b82015-06-16 13:54:23 +08001484 /* Create and submit job descriptor */
Herbert Xu479bcc72015-07-30 17:53:17 +08001485 init_authenc_job(req, edesc, all_contig, true);
Yuan Kang1acebad2011-07-15 11:21:42 +08001486#ifdef DEBUG
Herbert Xuf2147b82015-06-16 13:54:23 +08001487 print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1488 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1489 desc_bytes(edesc->hw_desc), 1);
Yuan Kang1acebad2011-07-15 11:21:42 +08001490#endif
1491
Herbert Xuf2147b82015-06-16 13:54:23 +08001492 desc = edesc->hw_desc;
Herbert Xu479bcc72015-07-30 17:53:17 +08001493 ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
Herbert Xuf2147b82015-06-16 13:54:23 +08001494 if (!ret) {
1495 ret = -EINPROGRESS;
1496 } else {
Herbert Xu479bcc72015-07-30 17:53:17 +08001497 aead_unmap(jrdev, edesc, req);
Herbert Xuf2147b82015-06-16 13:54:23 +08001498 kfree(edesc);
1499 }
1500
1501 return ret;
1502}
1503
1504static int gcm_decrypt(struct aead_request *req)
1505{
1506 struct aead_edesc *edesc;
1507 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1508 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1509 struct device *jrdev = ctx->jrdev;
1510 bool all_contig;
1511 u32 *desc;
1512 int ret = 0;
1513
1514 /* allocate extended descriptor */
1515 edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
1516 if (IS_ERR(edesc))
1517 return PTR_ERR(edesc);
1518
Yuan Kang1acebad2011-07-15 11:21:42 +08001519 /* Create and submit job descriptor*/
Herbert Xuf2147b82015-06-16 13:54:23 +08001520 init_gcm_job(req, edesc, all_contig, false);
Yuan Kang1acebad2011-07-15 11:21:42 +08001521#ifdef DEBUG
Alex Porosanu514df282013-08-14 18:56:45 +03001522 print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
Yuan Kang1acebad2011-07-15 11:21:42 +08001523 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1524 desc_bytes(edesc->hw_desc), 1);
1525#endif
1526
Yuan Kang0e479302011-07-15 11:21:41 +08001527 desc = edesc->hw_desc;
Yuan Kang1acebad2011-07-15 11:21:42 +08001528 ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1529 if (!ret) {
1530 ret = -EINPROGRESS;
1531 } else {
1532 aead_unmap(jrdev, edesc, req);
1533 kfree(edesc);
1534 }
Yuan Kang0e479302011-07-15 11:21:41 +08001535
Yuan Kang1acebad2011-07-15 11:21:42 +08001536 return ret;
1537}
Yuan Kang0e479302011-07-15 11:21:41 +08001538
Herbert Xu46218752015-07-09 07:17:33 +08001539static int ipsec_gcm_decrypt(struct aead_request *req)
1540{
1541 if (req->assoclen < 8)
1542 return -EINVAL;
1543
1544 return gcm_decrypt(req);
1545}
1546
Herbert Xu479bcc72015-07-30 17:53:17 +08001547static int aead_decrypt(struct aead_request *req)
Herbert Xuf2147b82015-06-16 13:54:23 +08001548{
1549 struct aead_edesc *edesc;
1550 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1551 struct caam_ctx *ctx = crypto_aead_ctx(aead);
1552 struct device *jrdev = ctx->jrdev;
1553 bool all_contig;
1554 u32 *desc;
1555 int ret = 0;
1556
Horia Geantă972b8122017-07-10 08:40:28 +03001557 caam_dump_sg(KERN_ERR, "dec src@" __stringify(__LINE__)": ",
1558 DUMP_PREFIX_ADDRESS, 16, 4, req->src,
1559 req->assoclen + req->cryptlen, 1);
Catalin Vasile5ecf8ef2016-09-22 11:57:58 +03001560
Herbert Xuf2147b82015-06-16 13:54:23 +08001561 /* allocate extended descriptor */
Herbert Xu479bcc72015-07-30 17:53:17 +08001562 edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1563 &all_contig, false);
Herbert Xuf2147b82015-06-16 13:54:23 +08001564 if (IS_ERR(edesc))
1565 return PTR_ERR(edesc);
1566
Herbert Xuf2147b82015-06-16 13:54:23 +08001567 /* Create and submit job descriptor*/
Herbert Xu479bcc72015-07-30 17:53:17 +08001568 init_authenc_job(req, edesc, all_contig, false);
Herbert Xuf2147b82015-06-16 13:54:23 +08001569#ifdef DEBUG
1570 print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1571 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1572 desc_bytes(edesc->hw_desc), 1);
1573#endif
1574
1575 desc = edesc->hw_desc;
Herbert Xu479bcc72015-07-30 17:53:17 +08001576 ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
Herbert Xuf2147b82015-06-16 13:54:23 +08001577 if (!ret) {
1578 ret = -EINPROGRESS;
1579 } else {
Herbert Xu479bcc72015-07-30 17:53:17 +08001580 aead_unmap(jrdev, edesc, req);
Herbert Xuf2147b82015-06-16 13:54:23 +08001581 kfree(edesc);
1582 }
1583
1584 return ret;
1585}
1586
Yuan Kangacdca312011-07-15 11:21:42 +08001587/*
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001588 * allocate and map the skcipher extended descriptor for skcipher
Yuan Kangacdca312011-07-15 11:21:42 +08001589 */
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001590static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
1591 int desc_bytes)
Yuan Kangacdca312011-07-15 11:21:42 +08001592{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001593 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1594 struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +08001595 struct device *jrdev = ctx->jrdev;
Horia Geantă42cfcaf2017-06-19 11:44:45 +03001596 gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
Yuan Kangacdca312011-07-15 11:21:42 +08001597 GFP_KERNEL : GFP_ATOMIC;
Horia Geantă838e0a82017-02-10 14:07:20 +02001598 int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001599 struct skcipher_edesc *edesc;
Horia Geantă115957b2018-03-28 15:39:18 +03001600 dma_addr_t iv_dma;
1601 u8 *iv;
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001602 int ivsize = crypto_skcipher_ivsize(skcipher);
Horia Geantă838e0a82017-02-10 14:07:20 +02001603 int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
Yuan Kangacdca312011-07-15 11:21:42 +08001604
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001605 src_nents = sg_nents_for_len(req->src, req->cryptlen);
Horia Geantăfd144d82017-02-10 14:07:18 +02001606 if (unlikely(src_nents < 0)) {
1607 dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001608 req->cryptlen);
Horia Geantăfd144d82017-02-10 14:07:18 +02001609 return ERR_PTR(src_nents);
1610 }
Yuan Kangacdca312011-07-15 11:21:42 +08001611
Horia Geantăfd144d82017-02-10 14:07:18 +02001612 if (req->dst != req->src) {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001613 dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
Horia Geantăfd144d82017-02-10 14:07:18 +02001614 if (unlikely(dst_nents < 0)) {
1615 dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001616 req->cryptlen);
Horia Geantăfd144d82017-02-10 14:07:18 +02001617 return ERR_PTR(dst_nents);
1618 }
1619 }
Yuan Kangacdca312011-07-15 11:21:42 +08001620
1621 if (likely(req->src == req->dst)) {
Horia Geantă838e0a82017-02-10 14:07:20 +02001622 mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1623 DMA_BIDIRECTIONAL);
1624 if (unlikely(!mapped_src_nents)) {
Horia Geantăc73e36e2016-11-09 10:46:20 +02001625 dev_err(jrdev, "unable to map source\n");
1626 return ERR_PTR(-ENOMEM);
1627 }
Yuan Kangacdca312011-07-15 11:21:42 +08001628 } else {
Horia Geantă838e0a82017-02-10 14:07:20 +02001629 mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1630 DMA_TO_DEVICE);
1631 if (unlikely(!mapped_src_nents)) {
Horia Geantăc73e36e2016-11-09 10:46:20 +02001632 dev_err(jrdev, "unable to map source\n");
1633 return ERR_PTR(-ENOMEM);
1634 }
1635
Horia Geantă838e0a82017-02-10 14:07:20 +02001636 mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1637 DMA_FROM_DEVICE);
1638 if (unlikely(!mapped_dst_nents)) {
Horia Geantăc73e36e2016-11-09 10:46:20 +02001639 dev_err(jrdev, "unable to map destination\n");
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001640 dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
Horia Geantăc73e36e2016-11-09 10:46:20 +02001641 return ERR_PTR(-ENOMEM);
1642 }
Yuan Kangacdca312011-07-15 11:21:42 +08001643 }
1644
Horia Geantă115957b2018-03-28 15:39:18 +03001645 sec4_sg_ents = 1 + mapped_src_nents;
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001646 dst_sg_idx = sec4_sg_ents;
Horia Geantă838e0a82017-02-10 14:07:20 +02001647 sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
Horia Geantăfa0c92d2017-02-10 14:07:19 +02001648 sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
Yuan Kangacdca312011-07-15 11:21:42 +08001649
Horia Geantă115957b2018-03-28 15:39:18 +03001650 /*
1651 * allocate space for base edesc and hw desc commands, link tables, IV
1652 */
1653 edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
Victoria Milhoandde20ae2015-08-05 11:28:39 -07001654 GFP_DMA | flags);
Yuan Kangacdca312011-07-15 11:21:42 +08001655 if (!edesc) {
1656 dev_err(jrdev, "could not allocate extended descriptor\n");
Horia Geantă115957b2018-03-28 15:39:18 +03001657 caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
Horia Geantăcf5448b2018-08-06 15:43:57 +03001658 0, 0, 0);
Yuan Kangacdca312011-07-15 11:21:42 +08001659 return ERR_PTR(-ENOMEM);
1660 }
1661
1662 edesc->src_nents = src_nents;
1663 edesc->dst_nents = dst_nents;
Yuan Kanga299c832012-06-22 19:48:46 -05001664 edesc->sec4_sg_bytes = sec4_sg_bytes;
Horia Geantă13cc6f42018-09-14 18:34:28 +03001665 edesc->sec4_sg = (struct sec4_sg_entry *)((u8 *)edesc->hw_desc +
1666 desc_bytes);
Yuan Kangacdca312011-07-15 11:21:42 +08001667
Horia Geantă115957b2018-03-28 15:39:18 +03001668 /* Make sure IV is located in a DMAable area */
1669 iv = (u8 *)edesc->hw_desc + desc_bytes + sec4_sg_bytes;
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001670 memcpy(iv, req->iv, ivsize);
Horia Geantă115957b2018-03-28 15:39:18 +03001671
1672 iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_TO_DEVICE);
1673 if (dma_mapping_error(jrdev, iv_dma)) {
1674 dev_err(jrdev, "unable to map IV\n");
1675 caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
Horia Geantăcf5448b2018-08-06 15:43:57 +03001676 0, 0, 0);
Horia Geantă115957b2018-03-28 15:39:18 +03001677 kfree(edesc);
1678 return ERR_PTR(-ENOMEM);
Yuan Kangacdca312011-07-15 11:21:42 +08001679 }
1680
Horia Geantă115957b2018-03-28 15:39:18 +03001681 dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1682 sg_to_sec4_sg_last(req->src, mapped_src_nents, edesc->sec4_sg + 1, 0);
1683
Horia Geantă838e0a82017-02-10 14:07:20 +02001684 if (mapped_dst_nents > 1) {
1685 sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1686 edesc->sec4_sg + dst_sg_idx, 0);
Yuan Kangacdca312011-07-15 11:21:42 +08001687 }
1688
Yuan Kanga299c832012-06-22 19:48:46 -05001689 edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1690 sec4_sg_bytes, DMA_TO_DEVICE);
Horia Geantace572082014-07-11 15:34:49 +03001691 if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1692 dev_err(jrdev, "unable to map S/G table\n");
Horia Geantăc73e36e2016-11-09 10:46:20 +02001693 caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
Horia Geantăcf5448b2018-08-06 15:43:57 +03001694 iv_dma, ivsize, 0, 0);
Horia Geantăc73e36e2016-11-09 10:46:20 +02001695 kfree(edesc);
Horia Geantace572082014-07-11 15:34:49 +03001696 return ERR_PTR(-ENOMEM);
1697 }
1698
Yuan Kangacdca312011-07-15 11:21:42 +08001699 edesc->iv_dma = iv_dma;
1700
1701#ifdef DEBUG
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001702 print_hex_dump(KERN_ERR, "skcipher sec4_sg@" __stringify(__LINE__)": ",
Yuan Kanga299c832012-06-22 19:48:46 -05001703 DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1704 sec4_sg_bytes, 1);
Yuan Kangacdca312011-07-15 11:21:42 +08001705#endif
1706
Yuan Kangacdca312011-07-15 11:21:42 +08001707 return edesc;
1708}
1709
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001710static int skcipher_encrypt(struct skcipher_request *req)
Yuan Kangacdca312011-07-15 11:21:42 +08001711{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001712 struct skcipher_edesc *edesc;
1713 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1714 struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +08001715 struct device *jrdev = ctx->jrdev;
Yuan Kangacdca312011-07-15 11:21:42 +08001716 u32 *desc;
1717 int ret = 0;
1718
1719 /* allocate extended descriptor */
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001720 edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
Yuan Kangacdca312011-07-15 11:21:42 +08001721 if (IS_ERR(edesc))
1722 return PTR_ERR(edesc);
1723
1724 /* Create and submit job descriptor*/
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001725 init_skcipher_job(req, edesc, true);
Yuan Kangacdca312011-07-15 11:21:42 +08001726#ifdef DEBUG
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001727 print_hex_dump(KERN_ERR, "skcipher jobdesc@" __stringify(__LINE__)": ",
Yuan Kangacdca312011-07-15 11:21:42 +08001728 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1729 desc_bytes(edesc->hw_desc), 1);
1730#endif
1731 desc = edesc->hw_desc;
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001732 ret = caam_jr_enqueue(jrdev, desc, skcipher_encrypt_done, req);
Yuan Kangacdca312011-07-15 11:21:42 +08001733
1734 if (!ret) {
1735 ret = -EINPROGRESS;
1736 } else {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001737 skcipher_unmap(jrdev, edesc, req);
Yuan Kangacdca312011-07-15 11:21:42 +08001738 kfree(edesc);
1739 }
1740
1741 return ret;
1742}
1743
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001744static int skcipher_decrypt(struct skcipher_request *req)
Yuan Kangacdca312011-07-15 11:21:42 +08001745{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001746 struct skcipher_edesc *edesc;
1747 struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1748 struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1749 int ivsize = crypto_skcipher_ivsize(skcipher);
Yuan Kangacdca312011-07-15 11:21:42 +08001750 struct device *jrdev = ctx->jrdev;
Yuan Kangacdca312011-07-15 11:21:42 +08001751 u32 *desc;
1752 int ret = 0;
1753
1754 /* allocate extended descriptor */
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001755 edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
Yuan Kangacdca312011-07-15 11:21:42 +08001756 if (IS_ERR(edesc))
1757 return PTR_ERR(edesc);
1758
Horia Geantă115957b2018-03-28 15:39:18 +03001759 /*
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001760 * The crypto API expects us to set the IV (req->iv) to the last
Horia Geantă115957b2018-03-28 15:39:18 +03001761 * ciphertext block.
1762 */
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001763 scatterwalk_map_and_copy(req->iv, req->src, req->cryptlen - ivsize,
Horia Geantă115957b2018-03-28 15:39:18 +03001764 ivsize, 0);
1765
Yuan Kangacdca312011-07-15 11:21:42 +08001766 /* Create and submit job descriptor*/
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001767 init_skcipher_job(req, edesc, false);
Yuan Kangacdca312011-07-15 11:21:42 +08001768 desc = edesc->hw_desc;
1769#ifdef DEBUG
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001770 print_hex_dump(KERN_ERR, "skcipher jobdesc@" __stringify(__LINE__)": ",
Yuan Kangacdca312011-07-15 11:21:42 +08001771 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1772 desc_bytes(edesc->hw_desc), 1);
1773#endif
1774
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001775 ret = caam_jr_enqueue(jrdev, desc, skcipher_decrypt_done, req);
Yuan Kangacdca312011-07-15 11:21:42 +08001776 if (!ret) {
1777 ret = -EINPROGRESS;
1778 } else {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001779 skcipher_unmap(jrdev, edesc, req);
Yuan Kangacdca312011-07-15 11:21:42 +08001780 kfree(edesc);
1781 }
1782
1783 return ret;
1784}
1785
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001786static struct caam_skcipher_alg driver_algs[] = {
Yuan Kangacdca312011-07-15 11:21:42 +08001787 {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001788 .skcipher = {
1789 .base = {
1790 .cra_name = "cbc(aes)",
1791 .cra_driver_name = "cbc-aes-caam",
1792 .cra_blocksize = AES_BLOCK_SIZE,
1793 },
1794 .setkey = skcipher_setkey,
1795 .encrypt = skcipher_encrypt,
1796 .decrypt = skcipher_decrypt,
Yuan Kangacdca312011-07-15 11:21:42 +08001797 .min_keysize = AES_MIN_KEY_SIZE,
1798 .max_keysize = AES_MAX_KEY_SIZE,
1799 .ivsize = AES_BLOCK_SIZE,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001800 },
1801 .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
Yuan Kangacdca312011-07-15 11:21:42 +08001802 },
1803 {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001804 .skcipher = {
1805 .base = {
1806 .cra_name = "cbc(des3_ede)",
1807 .cra_driver_name = "cbc-3des-caam",
1808 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1809 },
1810 .setkey = skcipher_setkey,
1811 .encrypt = skcipher_encrypt,
1812 .decrypt = skcipher_decrypt,
Yuan Kangacdca312011-07-15 11:21:42 +08001813 .min_keysize = DES3_EDE_KEY_SIZE,
1814 .max_keysize = DES3_EDE_KEY_SIZE,
1815 .ivsize = DES3_EDE_BLOCK_SIZE,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001816 },
1817 .caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
Yuan Kangacdca312011-07-15 11:21:42 +08001818 },
1819 {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001820 .skcipher = {
1821 .base = {
1822 .cra_name = "cbc(des)",
1823 .cra_driver_name = "cbc-des-caam",
1824 .cra_blocksize = DES_BLOCK_SIZE,
1825 },
1826 .setkey = skcipher_setkey,
1827 .encrypt = skcipher_encrypt,
1828 .decrypt = skcipher_decrypt,
Yuan Kangacdca312011-07-15 11:21:42 +08001829 .min_keysize = DES_KEY_SIZE,
1830 .max_keysize = DES_KEY_SIZE,
1831 .ivsize = DES_BLOCK_SIZE,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001832 },
1833 .caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
Catalin Vasile2b22f6c2014-10-31 12:45:35 +02001834 },
1835 {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001836 .skcipher = {
1837 .base = {
1838 .cra_name = "ctr(aes)",
1839 .cra_driver_name = "ctr-aes-caam",
1840 .cra_blocksize = 1,
1841 },
1842 .setkey = skcipher_setkey,
1843 .encrypt = skcipher_encrypt,
1844 .decrypt = skcipher_decrypt,
Catalin Vasile2b22f6c2014-10-31 12:45:35 +02001845 .min_keysize = AES_MIN_KEY_SIZE,
1846 .max_keysize = AES_MAX_KEY_SIZE,
1847 .ivsize = AES_BLOCK_SIZE,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001848 .chunksize = AES_BLOCK_SIZE,
1849 },
1850 .caam.class1_alg_type = OP_ALG_ALGSEL_AES |
1851 OP_ALG_AAI_CTR_MOD128,
Catalin Vasilea5f57cf2014-10-31 12:45:36 +02001852 },
1853 {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001854 .skcipher = {
1855 .base = {
1856 .cra_name = "rfc3686(ctr(aes))",
1857 .cra_driver_name = "rfc3686-ctr-aes-caam",
1858 .cra_blocksize = 1,
1859 },
1860 .setkey = skcipher_setkey,
1861 .encrypt = skcipher_encrypt,
1862 .decrypt = skcipher_decrypt,
Catalin Vasilea5f57cf2014-10-31 12:45:36 +02001863 .min_keysize = AES_MIN_KEY_SIZE +
1864 CTR_RFC3686_NONCE_SIZE,
1865 .max_keysize = AES_MAX_KEY_SIZE +
1866 CTR_RFC3686_NONCE_SIZE,
1867 .ivsize = CTR_RFC3686_IV_SIZE,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001868 .chunksize = AES_BLOCK_SIZE,
1869 },
1870 .caam = {
1871 .class1_alg_type = OP_ALG_ALGSEL_AES |
1872 OP_ALG_AAI_CTR_MOD128,
1873 .rfc3686 = true,
1874 },
Catalin Vasilec6415a62015-10-02 13:13:18 +03001875 },
1876 {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001877 .skcipher = {
1878 .base = {
1879 .cra_name = "xts(aes)",
1880 .cra_driver_name = "xts-aes-caam",
1881 .cra_blocksize = AES_BLOCK_SIZE,
1882 },
1883 .setkey = xts_skcipher_setkey,
1884 .encrypt = skcipher_encrypt,
1885 .decrypt = skcipher_decrypt,
Catalin Vasilec6415a62015-10-02 13:13:18 +03001886 .min_keysize = 2 * AES_MIN_KEY_SIZE,
1887 .max_keysize = 2 * AES_MAX_KEY_SIZE,
1888 .ivsize = AES_BLOCK_SIZE,
Horia Geantă5ca7bad2018-08-06 15:43:59 +03001889 },
1890 .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
Catalin Vasilec6415a62015-10-02 13:13:18 +03001891 },
Kim Phillips8e8ec592011-03-13 16:54:26 +08001892};
1893
Herbert Xuf2147b82015-06-16 13:54:23 +08001894static struct caam_aead_alg driver_aeads[] = {
1895 {
1896 .aead = {
1897 .base = {
1898 .cra_name = "rfc4106(gcm(aes))",
1899 .cra_driver_name = "rfc4106-gcm-aes-caam",
1900 .cra_blocksize = 1,
1901 },
1902 .setkey = rfc4106_setkey,
1903 .setauthsize = rfc4106_setauthsize,
Herbert Xu46218752015-07-09 07:17:33 +08001904 .encrypt = ipsec_gcm_encrypt,
1905 .decrypt = ipsec_gcm_decrypt,
Corentin LABBE7545e162017-08-22 10:08:09 +02001906 .ivsize = GCM_RFC4106_IV_SIZE,
Herbert Xuf2147b82015-06-16 13:54:23 +08001907 .maxauthsize = AES_BLOCK_SIZE,
1908 },
1909 .caam = {
1910 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
1911 },
1912 },
1913 {
1914 .aead = {
1915 .base = {
1916 .cra_name = "rfc4543(gcm(aes))",
1917 .cra_driver_name = "rfc4543-gcm-aes-caam",
1918 .cra_blocksize = 1,
1919 },
1920 .setkey = rfc4543_setkey,
1921 .setauthsize = rfc4543_setauthsize,
Herbert Xu46218752015-07-09 07:17:33 +08001922 .encrypt = ipsec_gcm_encrypt,
1923 .decrypt = ipsec_gcm_decrypt,
Corentin LABBE7545e162017-08-22 10:08:09 +02001924 .ivsize = GCM_RFC4543_IV_SIZE,
Herbert Xuf2147b82015-06-16 13:54:23 +08001925 .maxauthsize = AES_BLOCK_SIZE,
1926 },
1927 .caam = {
1928 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
1929 },
1930 },
1931 /* Galois Counter Mode */
1932 {
1933 .aead = {
1934 .base = {
1935 .cra_name = "gcm(aes)",
1936 .cra_driver_name = "gcm-aes-caam",
1937 .cra_blocksize = 1,
1938 },
1939 .setkey = gcm_setkey,
1940 .setauthsize = gcm_setauthsize,
1941 .encrypt = gcm_encrypt,
1942 .decrypt = gcm_decrypt,
Corentin LABBE7545e162017-08-22 10:08:09 +02001943 .ivsize = GCM_AES_IV_SIZE,
Herbert Xuf2147b82015-06-16 13:54:23 +08001944 .maxauthsize = AES_BLOCK_SIZE,
1945 },
1946 .caam = {
1947 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
1948 },
1949 },
Herbert Xu479bcc72015-07-30 17:53:17 +08001950 /* single-pass ipsec_esp descriptor */
1951 {
1952 .aead = {
1953 .base = {
1954 .cra_name = "authenc(hmac(md5),"
1955 "ecb(cipher_null))",
1956 .cra_driver_name = "authenc-hmac-md5-"
1957 "ecb-cipher_null-caam",
1958 .cra_blocksize = NULL_BLOCK_SIZE,
1959 },
1960 .setkey = aead_setkey,
1961 .setauthsize = aead_setauthsize,
1962 .encrypt = aead_encrypt,
1963 .decrypt = aead_decrypt,
1964 .ivsize = NULL_IV_SIZE,
1965 .maxauthsize = MD5_DIGEST_SIZE,
1966 },
1967 .caam = {
1968 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
1969 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08001970 },
1971 },
1972 {
1973 .aead = {
1974 .base = {
1975 .cra_name = "authenc(hmac(sha1),"
1976 "ecb(cipher_null))",
1977 .cra_driver_name = "authenc-hmac-sha1-"
1978 "ecb-cipher_null-caam",
1979 .cra_blocksize = NULL_BLOCK_SIZE,
1980 },
1981 .setkey = aead_setkey,
1982 .setauthsize = aead_setauthsize,
1983 .encrypt = aead_encrypt,
1984 .decrypt = aead_decrypt,
1985 .ivsize = NULL_IV_SIZE,
1986 .maxauthsize = SHA1_DIGEST_SIZE,
1987 },
1988 .caam = {
1989 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
1990 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08001991 },
1992 },
1993 {
1994 .aead = {
1995 .base = {
1996 .cra_name = "authenc(hmac(sha224),"
1997 "ecb(cipher_null))",
1998 .cra_driver_name = "authenc-hmac-sha224-"
1999 "ecb-cipher_null-caam",
2000 .cra_blocksize = NULL_BLOCK_SIZE,
2001 },
2002 .setkey = aead_setkey,
2003 .setauthsize = aead_setauthsize,
2004 .encrypt = aead_encrypt,
2005 .decrypt = aead_decrypt,
2006 .ivsize = NULL_IV_SIZE,
2007 .maxauthsize = SHA224_DIGEST_SIZE,
2008 },
2009 .caam = {
2010 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2011 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002012 },
2013 },
2014 {
2015 .aead = {
2016 .base = {
2017 .cra_name = "authenc(hmac(sha256),"
2018 "ecb(cipher_null))",
2019 .cra_driver_name = "authenc-hmac-sha256-"
2020 "ecb-cipher_null-caam",
2021 .cra_blocksize = NULL_BLOCK_SIZE,
2022 },
2023 .setkey = aead_setkey,
2024 .setauthsize = aead_setauthsize,
2025 .encrypt = aead_encrypt,
2026 .decrypt = aead_decrypt,
2027 .ivsize = NULL_IV_SIZE,
2028 .maxauthsize = SHA256_DIGEST_SIZE,
2029 },
2030 .caam = {
2031 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2032 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002033 },
2034 },
2035 {
2036 .aead = {
2037 .base = {
2038 .cra_name = "authenc(hmac(sha384),"
2039 "ecb(cipher_null))",
2040 .cra_driver_name = "authenc-hmac-sha384-"
2041 "ecb-cipher_null-caam",
2042 .cra_blocksize = NULL_BLOCK_SIZE,
2043 },
2044 .setkey = aead_setkey,
2045 .setauthsize = aead_setauthsize,
2046 .encrypt = aead_encrypt,
2047 .decrypt = aead_decrypt,
2048 .ivsize = NULL_IV_SIZE,
2049 .maxauthsize = SHA384_DIGEST_SIZE,
2050 },
2051 .caam = {
2052 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2053 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002054 },
2055 },
2056 {
2057 .aead = {
2058 .base = {
2059 .cra_name = "authenc(hmac(sha512),"
2060 "ecb(cipher_null))",
2061 .cra_driver_name = "authenc-hmac-sha512-"
2062 "ecb-cipher_null-caam",
2063 .cra_blocksize = NULL_BLOCK_SIZE,
2064 },
2065 .setkey = aead_setkey,
2066 .setauthsize = aead_setauthsize,
2067 .encrypt = aead_encrypt,
2068 .decrypt = aead_decrypt,
2069 .ivsize = NULL_IV_SIZE,
2070 .maxauthsize = SHA512_DIGEST_SIZE,
2071 },
2072 .caam = {
2073 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2074 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002075 },
2076 },
2077 {
2078 .aead = {
2079 .base = {
2080 .cra_name = "authenc(hmac(md5),cbc(aes))",
2081 .cra_driver_name = "authenc-hmac-md5-"
2082 "cbc-aes-caam",
2083 .cra_blocksize = AES_BLOCK_SIZE,
2084 },
2085 .setkey = aead_setkey,
2086 .setauthsize = aead_setauthsize,
2087 .encrypt = aead_encrypt,
2088 .decrypt = aead_decrypt,
2089 .ivsize = AES_BLOCK_SIZE,
2090 .maxauthsize = MD5_DIGEST_SIZE,
2091 },
2092 .caam = {
2093 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2094 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2095 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002096 },
2097 },
2098 {
2099 .aead = {
2100 .base = {
2101 .cra_name = "echainiv(authenc(hmac(md5),"
2102 "cbc(aes)))",
2103 .cra_driver_name = "echainiv-authenc-hmac-md5-"
2104 "cbc-aes-caam",
2105 .cra_blocksize = AES_BLOCK_SIZE,
2106 },
2107 .setkey = aead_setkey,
2108 .setauthsize = aead_setauthsize,
2109 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002110 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002111 .ivsize = AES_BLOCK_SIZE,
2112 .maxauthsize = MD5_DIGEST_SIZE,
2113 },
2114 .caam = {
2115 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2116 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2117 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002118 .geniv = true,
2119 },
2120 },
2121 {
2122 .aead = {
2123 .base = {
2124 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2125 .cra_driver_name = "authenc-hmac-sha1-"
2126 "cbc-aes-caam",
2127 .cra_blocksize = AES_BLOCK_SIZE,
2128 },
2129 .setkey = aead_setkey,
2130 .setauthsize = aead_setauthsize,
2131 .encrypt = aead_encrypt,
2132 .decrypt = aead_decrypt,
2133 .ivsize = AES_BLOCK_SIZE,
2134 .maxauthsize = SHA1_DIGEST_SIZE,
2135 },
2136 .caam = {
2137 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2138 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2139 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002140 },
2141 },
2142 {
2143 .aead = {
2144 .base = {
2145 .cra_name = "echainiv(authenc(hmac(sha1),"
2146 "cbc(aes)))",
2147 .cra_driver_name = "echainiv-authenc-"
2148 "hmac-sha1-cbc-aes-caam",
2149 .cra_blocksize = AES_BLOCK_SIZE,
2150 },
2151 .setkey = aead_setkey,
2152 .setauthsize = aead_setauthsize,
2153 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002154 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002155 .ivsize = AES_BLOCK_SIZE,
2156 .maxauthsize = SHA1_DIGEST_SIZE,
2157 },
2158 .caam = {
2159 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2160 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2161 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002162 .geniv = true,
2163 },
2164 },
2165 {
2166 .aead = {
2167 .base = {
2168 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2169 .cra_driver_name = "authenc-hmac-sha224-"
2170 "cbc-aes-caam",
2171 .cra_blocksize = AES_BLOCK_SIZE,
2172 },
2173 .setkey = aead_setkey,
2174 .setauthsize = aead_setauthsize,
2175 .encrypt = aead_encrypt,
2176 .decrypt = aead_decrypt,
2177 .ivsize = AES_BLOCK_SIZE,
2178 .maxauthsize = SHA224_DIGEST_SIZE,
2179 },
2180 .caam = {
2181 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2182 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2183 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002184 },
2185 },
2186 {
2187 .aead = {
2188 .base = {
2189 .cra_name = "echainiv(authenc(hmac(sha224),"
2190 "cbc(aes)))",
2191 .cra_driver_name = "echainiv-authenc-"
2192 "hmac-sha224-cbc-aes-caam",
2193 .cra_blocksize = AES_BLOCK_SIZE,
2194 },
2195 .setkey = aead_setkey,
2196 .setauthsize = aead_setauthsize,
2197 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002198 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002199 .ivsize = AES_BLOCK_SIZE,
2200 .maxauthsize = SHA224_DIGEST_SIZE,
2201 },
2202 .caam = {
2203 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2204 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2205 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002206 .geniv = true,
2207 },
2208 },
2209 {
2210 .aead = {
2211 .base = {
2212 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2213 .cra_driver_name = "authenc-hmac-sha256-"
2214 "cbc-aes-caam",
2215 .cra_blocksize = AES_BLOCK_SIZE,
2216 },
2217 .setkey = aead_setkey,
2218 .setauthsize = aead_setauthsize,
2219 .encrypt = aead_encrypt,
2220 .decrypt = aead_decrypt,
2221 .ivsize = AES_BLOCK_SIZE,
2222 .maxauthsize = SHA256_DIGEST_SIZE,
2223 },
2224 .caam = {
2225 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2226 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2227 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002228 },
2229 },
2230 {
2231 .aead = {
2232 .base = {
2233 .cra_name = "echainiv(authenc(hmac(sha256),"
2234 "cbc(aes)))",
2235 .cra_driver_name = "echainiv-authenc-"
2236 "hmac-sha256-cbc-aes-caam",
2237 .cra_blocksize = AES_BLOCK_SIZE,
2238 },
2239 .setkey = aead_setkey,
2240 .setauthsize = aead_setauthsize,
2241 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002242 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002243 .ivsize = AES_BLOCK_SIZE,
2244 .maxauthsize = SHA256_DIGEST_SIZE,
2245 },
2246 .caam = {
2247 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2248 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2249 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002250 .geniv = true,
2251 },
2252 },
2253 {
2254 .aead = {
2255 .base = {
2256 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2257 .cra_driver_name = "authenc-hmac-sha384-"
2258 "cbc-aes-caam",
2259 .cra_blocksize = AES_BLOCK_SIZE,
2260 },
2261 .setkey = aead_setkey,
2262 .setauthsize = aead_setauthsize,
2263 .encrypt = aead_encrypt,
2264 .decrypt = aead_decrypt,
2265 .ivsize = AES_BLOCK_SIZE,
2266 .maxauthsize = SHA384_DIGEST_SIZE,
2267 },
2268 .caam = {
2269 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2270 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2271 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002272 },
2273 },
2274 {
2275 .aead = {
2276 .base = {
2277 .cra_name = "echainiv(authenc(hmac(sha384),"
2278 "cbc(aes)))",
2279 .cra_driver_name = "echainiv-authenc-"
2280 "hmac-sha384-cbc-aes-caam",
2281 .cra_blocksize = AES_BLOCK_SIZE,
2282 },
2283 .setkey = aead_setkey,
2284 .setauthsize = aead_setauthsize,
2285 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002286 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002287 .ivsize = AES_BLOCK_SIZE,
2288 .maxauthsize = SHA384_DIGEST_SIZE,
2289 },
2290 .caam = {
2291 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2292 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2293 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002294 .geniv = true,
2295 },
2296 },
2297 {
2298 .aead = {
2299 .base = {
2300 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2301 .cra_driver_name = "authenc-hmac-sha512-"
2302 "cbc-aes-caam",
2303 .cra_blocksize = AES_BLOCK_SIZE,
2304 },
2305 .setkey = aead_setkey,
2306 .setauthsize = aead_setauthsize,
2307 .encrypt = aead_encrypt,
2308 .decrypt = aead_decrypt,
2309 .ivsize = AES_BLOCK_SIZE,
2310 .maxauthsize = SHA512_DIGEST_SIZE,
2311 },
2312 .caam = {
2313 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2314 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2315 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002316 },
2317 },
2318 {
2319 .aead = {
2320 .base = {
2321 .cra_name = "echainiv(authenc(hmac(sha512),"
2322 "cbc(aes)))",
2323 .cra_driver_name = "echainiv-authenc-"
2324 "hmac-sha512-cbc-aes-caam",
2325 .cra_blocksize = AES_BLOCK_SIZE,
2326 },
2327 .setkey = aead_setkey,
2328 .setauthsize = aead_setauthsize,
2329 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002330 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002331 .ivsize = AES_BLOCK_SIZE,
2332 .maxauthsize = SHA512_DIGEST_SIZE,
2333 },
2334 .caam = {
2335 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2336 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2337 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002338 .geniv = true,
2339 },
2340 },
2341 {
2342 .aead = {
2343 .base = {
2344 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2345 .cra_driver_name = "authenc-hmac-md5-"
2346 "cbc-des3_ede-caam",
2347 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2348 },
2349 .setkey = aead_setkey,
2350 .setauthsize = aead_setauthsize,
2351 .encrypt = aead_encrypt,
2352 .decrypt = aead_decrypt,
2353 .ivsize = DES3_EDE_BLOCK_SIZE,
2354 .maxauthsize = MD5_DIGEST_SIZE,
2355 },
2356 .caam = {
2357 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2358 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2359 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002360 }
2361 },
2362 {
2363 .aead = {
2364 .base = {
2365 .cra_name = "echainiv(authenc(hmac(md5),"
2366 "cbc(des3_ede)))",
2367 .cra_driver_name = "echainiv-authenc-hmac-md5-"
2368 "cbc-des3_ede-caam",
2369 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2370 },
2371 .setkey = aead_setkey,
2372 .setauthsize = aead_setauthsize,
2373 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002374 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002375 .ivsize = DES3_EDE_BLOCK_SIZE,
2376 .maxauthsize = MD5_DIGEST_SIZE,
2377 },
2378 .caam = {
2379 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2380 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2381 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002382 .geniv = true,
2383 }
2384 },
2385 {
2386 .aead = {
2387 .base = {
2388 .cra_name = "authenc(hmac(sha1),"
2389 "cbc(des3_ede))",
2390 .cra_driver_name = "authenc-hmac-sha1-"
2391 "cbc-des3_ede-caam",
2392 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2393 },
2394 .setkey = aead_setkey,
2395 .setauthsize = aead_setauthsize,
2396 .encrypt = aead_encrypt,
2397 .decrypt = aead_decrypt,
2398 .ivsize = DES3_EDE_BLOCK_SIZE,
2399 .maxauthsize = SHA1_DIGEST_SIZE,
2400 },
2401 .caam = {
2402 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2403 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2404 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002405 },
2406 },
2407 {
2408 .aead = {
2409 .base = {
2410 .cra_name = "echainiv(authenc(hmac(sha1),"
2411 "cbc(des3_ede)))",
2412 .cra_driver_name = "echainiv-authenc-"
2413 "hmac-sha1-"
2414 "cbc-des3_ede-caam",
2415 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2416 },
2417 .setkey = aead_setkey,
2418 .setauthsize = aead_setauthsize,
2419 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002420 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002421 .ivsize = DES3_EDE_BLOCK_SIZE,
2422 .maxauthsize = SHA1_DIGEST_SIZE,
2423 },
2424 .caam = {
2425 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2426 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2427 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002428 .geniv = true,
2429 },
2430 },
2431 {
2432 .aead = {
2433 .base = {
2434 .cra_name = "authenc(hmac(sha224),"
2435 "cbc(des3_ede))",
2436 .cra_driver_name = "authenc-hmac-sha224-"
2437 "cbc-des3_ede-caam",
2438 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2439 },
2440 .setkey = aead_setkey,
2441 .setauthsize = aead_setauthsize,
2442 .encrypt = aead_encrypt,
2443 .decrypt = aead_decrypt,
2444 .ivsize = DES3_EDE_BLOCK_SIZE,
2445 .maxauthsize = SHA224_DIGEST_SIZE,
2446 },
2447 .caam = {
2448 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2449 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2450 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002451 },
2452 },
2453 {
2454 .aead = {
2455 .base = {
2456 .cra_name = "echainiv(authenc(hmac(sha224),"
2457 "cbc(des3_ede)))",
2458 .cra_driver_name = "echainiv-authenc-"
2459 "hmac-sha224-"
2460 "cbc-des3_ede-caam",
2461 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2462 },
2463 .setkey = aead_setkey,
2464 .setauthsize = aead_setauthsize,
2465 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002466 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002467 .ivsize = DES3_EDE_BLOCK_SIZE,
2468 .maxauthsize = SHA224_DIGEST_SIZE,
2469 },
2470 .caam = {
2471 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2472 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2473 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002474 .geniv = true,
2475 },
2476 },
2477 {
2478 .aead = {
2479 .base = {
2480 .cra_name = "authenc(hmac(sha256),"
2481 "cbc(des3_ede))",
2482 .cra_driver_name = "authenc-hmac-sha256-"
2483 "cbc-des3_ede-caam",
2484 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2485 },
2486 .setkey = aead_setkey,
2487 .setauthsize = aead_setauthsize,
2488 .encrypt = aead_encrypt,
2489 .decrypt = aead_decrypt,
2490 .ivsize = DES3_EDE_BLOCK_SIZE,
2491 .maxauthsize = SHA256_DIGEST_SIZE,
2492 },
2493 .caam = {
2494 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2495 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2496 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002497 },
2498 },
2499 {
2500 .aead = {
2501 .base = {
2502 .cra_name = "echainiv(authenc(hmac(sha256),"
2503 "cbc(des3_ede)))",
2504 .cra_driver_name = "echainiv-authenc-"
2505 "hmac-sha256-"
2506 "cbc-des3_ede-caam",
2507 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2508 },
2509 .setkey = aead_setkey,
2510 .setauthsize = aead_setauthsize,
2511 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002512 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002513 .ivsize = DES3_EDE_BLOCK_SIZE,
2514 .maxauthsize = SHA256_DIGEST_SIZE,
2515 },
2516 .caam = {
2517 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2518 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2519 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002520 .geniv = true,
2521 },
2522 },
2523 {
2524 .aead = {
2525 .base = {
2526 .cra_name = "authenc(hmac(sha384),"
2527 "cbc(des3_ede))",
2528 .cra_driver_name = "authenc-hmac-sha384-"
2529 "cbc-des3_ede-caam",
2530 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2531 },
2532 .setkey = aead_setkey,
2533 .setauthsize = aead_setauthsize,
2534 .encrypt = aead_encrypt,
2535 .decrypt = aead_decrypt,
2536 .ivsize = DES3_EDE_BLOCK_SIZE,
2537 .maxauthsize = SHA384_DIGEST_SIZE,
2538 },
2539 .caam = {
2540 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2541 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2542 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002543 },
2544 },
2545 {
2546 .aead = {
2547 .base = {
2548 .cra_name = "echainiv(authenc(hmac(sha384),"
2549 "cbc(des3_ede)))",
2550 .cra_driver_name = "echainiv-authenc-"
2551 "hmac-sha384-"
2552 "cbc-des3_ede-caam",
2553 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2554 },
2555 .setkey = aead_setkey,
2556 .setauthsize = aead_setauthsize,
2557 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002558 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002559 .ivsize = DES3_EDE_BLOCK_SIZE,
2560 .maxauthsize = SHA384_DIGEST_SIZE,
2561 },
2562 .caam = {
2563 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2564 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2565 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002566 .geniv = true,
2567 },
2568 },
2569 {
2570 .aead = {
2571 .base = {
2572 .cra_name = "authenc(hmac(sha512),"
2573 "cbc(des3_ede))",
2574 .cra_driver_name = "authenc-hmac-sha512-"
2575 "cbc-des3_ede-caam",
2576 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2577 },
2578 .setkey = aead_setkey,
2579 .setauthsize = aead_setauthsize,
2580 .encrypt = aead_encrypt,
2581 .decrypt = aead_decrypt,
2582 .ivsize = DES3_EDE_BLOCK_SIZE,
2583 .maxauthsize = SHA512_DIGEST_SIZE,
2584 },
2585 .caam = {
2586 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2587 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2588 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002589 },
2590 },
2591 {
2592 .aead = {
2593 .base = {
2594 .cra_name = "echainiv(authenc(hmac(sha512),"
2595 "cbc(des3_ede)))",
2596 .cra_driver_name = "echainiv-authenc-"
2597 "hmac-sha512-"
2598 "cbc-des3_ede-caam",
2599 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2600 },
2601 .setkey = aead_setkey,
2602 .setauthsize = aead_setauthsize,
2603 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002604 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002605 .ivsize = DES3_EDE_BLOCK_SIZE,
2606 .maxauthsize = SHA512_DIGEST_SIZE,
2607 },
2608 .caam = {
2609 .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2610 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2611 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002612 .geniv = true,
2613 },
2614 },
2615 {
2616 .aead = {
2617 .base = {
2618 .cra_name = "authenc(hmac(md5),cbc(des))",
2619 .cra_driver_name = "authenc-hmac-md5-"
2620 "cbc-des-caam",
2621 .cra_blocksize = DES_BLOCK_SIZE,
2622 },
2623 .setkey = aead_setkey,
2624 .setauthsize = aead_setauthsize,
2625 .encrypt = aead_encrypt,
2626 .decrypt = aead_decrypt,
2627 .ivsize = DES_BLOCK_SIZE,
2628 .maxauthsize = MD5_DIGEST_SIZE,
2629 },
2630 .caam = {
2631 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2632 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2633 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002634 },
2635 },
2636 {
2637 .aead = {
2638 .base = {
2639 .cra_name = "echainiv(authenc(hmac(md5),"
2640 "cbc(des)))",
2641 .cra_driver_name = "echainiv-authenc-hmac-md5-"
2642 "cbc-des-caam",
2643 .cra_blocksize = DES_BLOCK_SIZE,
2644 },
2645 .setkey = aead_setkey,
2646 .setauthsize = aead_setauthsize,
2647 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002648 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002649 .ivsize = DES_BLOCK_SIZE,
2650 .maxauthsize = MD5_DIGEST_SIZE,
2651 },
2652 .caam = {
2653 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2654 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2655 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002656 .geniv = true,
2657 },
2658 },
2659 {
2660 .aead = {
2661 .base = {
2662 .cra_name = "authenc(hmac(sha1),cbc(des))",
2663 .cra_driver_name = "authenc-hmac-sha1-"
2664 "cbc-des-caam",
2665 .cra_blocksize = DES_BLOCK_SIZE,
2666 },
2667 .setkey = aead_setkey,
2668 .setauthsize = aead_setauthsize,
2669 .encrypt = aead_encrypt,
2670 .decrypt = aead_decrypt,
2671 .ivsize = DES_BLOCK_SIZE,
2672 .maxauthsize = SHA1_DIGEST_SIZE,
2673 },
2674 .caam = {
2675 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2676 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2677 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002678 },
2679 },
2680 {
2681 .aead = {
2682 .base = {
2683 .cra_name = "echainiv(authenc(hmac(sha1),"
2684 "cbc(des)))",
2685 .cra_driver_name = "echainiv-authenc-"
2686 "hmac-sha1-cbc-des-caam",
2687 .cra_blocksize = DES_BLOCK_SIZE,
2688 },
2689 .setkey = aead_setkey,
2690 .setauthsize = aead_setauthsize,
2691 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002692 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002693 .ivsize = DES_BLOCK_SIZE,
2694 .maxauthsize = SHA1_DIGEST_SIZE,
2695 },
2696 .caam = {
2697 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2698 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2699 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002700 .geniv = true,
2701 },
2702 },
2703 {
2704 .aead = {
2705 .base = {
2706 .cra_name = "authenc(hmac(sha224),cbc(des))",
2707 .cra_driver_name = "authenc-hmac-sha224-"
2708 "cbc-des-caam",
2709 .cra_blocksize = DES_BLOCK_SIZE,
2710 },
2711 .setkey = aead_setkey,
2712 .setauthsize = aead_setauthsize,
2713 .encrypt = aead_encrypt,
2714 .decrypt = aead_decrypt,
2715 .ivsize = DES_BLOCK_SIZE,
2716 .maxauthsize = SHA224_DIGEST_SIZE,
2717 },
2718 .caam = {
2719 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2720 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2721 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002722 },
2723 },
2724 {
2725 .aead = {
2726 .base = {
2727 .cra_name = "echainiv(authenc(hmac(sha224),"
2728 "cbc(des)))",
2729 .cra_driver_name = "echainiv-authenc-"
2730 "hmac-sha224-cbc-des-caam",
2731 .cra_blocksize = DES_BLOCK_SIZE,
2732 },
2733 .setkey = aead_setkey,
2734 .setauthsize = aead_setauthsize,
2735 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002736 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002737 .ivsize = DES_BLOCK_SIZE,
2738 .maxauthsize = SHA224_DIGEST_SIZE,
2739 },
2740 .caam = {
2741 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2742 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2743 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002744 .geniv = true,
2745 },
2746 },
2747 {
2748 .aead = {
2749 .base = {
2750 .cra_name = "authenc(hmac(sha256),cbc(des))",
2751 .cra_driver_name = "authenc-hmac-sha256-"
2752 "cbc-des-caam",
2753 .cra_blocksize = DES_BLOCK_SIZE,
2754 },
2755 .setkey = aead_setkey,
2756 .setauthsize = aead_setauthsize,
2757 .encrypt = aead_encrypt,
2758 .decrypt = aead_decrypt,
2759 .ivsize = DES_BLOCK_SIZE,
2760 .maxauthsize = SHA256_DIGEST_SIZE,
2761 },
2762 .caam = {
2763 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2764 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2765 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002766 },
2767 },
2768 {
2769 .aead = {
2770 .base = {
2771 .cra_name = "echainiv(authenc(hmac(sha256),"
2772 "cbc(des)))",
2773 .cra_driver_name = "echainiv-authenc-"
2774 "hmac-sha256-cbc-des-caam",
2775 .cra_blocksize = DES_BLOCK_SIZE,
2776 },
2777 .setkey = aead_setkey,
2778 .setauthsize = aead_setauthsize,
2779 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002780 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002781 .ivsize = DES_BLOCK_SIZE,
2782 .maxauthsize = SHA256_DIGEST_SIZE,
2783 },
2784 .caam = {
2785 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2786 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2787 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002788 .geniv = true,
2789 },
2790 },
2791 {
2792 .aead = {
2793 .base = {
2794 .cra_name = "authenc(hmac(sha384),cbc(des))",
2795 .cra_driver_name = "authenc-hmac-sha384-"
2796 "cbc-des-caam",
2797 .cra_blocksize = DES_BLOCK_SIZE,
2798 },
2799 .setkey = aead_setkey,
2800 .setauthsize = aead_setauthsize,
2801 .encrypt = aead_encrypt,
2802 .decrypt = aead_decrypt,
2803 .ivsize = DES_BLOCK_SIZE,
2804 .maxauthsize = SHA384_DIGEST_SIZE,
2805 },
2806 .caam = {
2807 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2808 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2809 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002810 },
2811 },
2812 {
2813 .aead = {
2814 .base = {
2815 .cra_name = "echainiv(authenc(hmac(sha384),"
2816 "cbc(des)))",
2817 .cra_driver_name = "echainiv-authenc-"
2818 "hmac-sha384-cbc-des-caam",
2819 .cra_blocksize = DES_BLOCK_SIZE,
2820 },
2821 .setkey = aead_setkey,
2822 .setauthsize = aead_setauthsize,
2823 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002824 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002825 .ivsize = DES_BLOCK_SIZE,
2826 .maxauthsize = SHA384_DIGEST_SIZE,
2827 },
2828 .caam = {
2829 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2830 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2831 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002832 .geniv = true,
2833 },
2834 },
2835 {
2836 .aead = {
2837 .base = {
2838 .cra_name = "authenc(hmac(sha512),cbc(des))",
2839 .cra_driver_name = "authenc-hmac-sha512-"
2840 "cbc-des-caam",
2841 .cra_blocksize = DES_BLOCK_SIZE,
2842 },
2843 .setkey = aead_setkey,
2844 .setauthsize = aead_setauthsize,
2845 .encrypt = aead_encrypt,
2846 .decrypt = aead_decrypt,
2847 .ivsize = DES_BLOCK_SIZE,
2848 .maxauthsize = SHA512_DIGEST_SIZE,
2849 },
2850 .caam = {
2851 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2852 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2853 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002854 },
2855 },
2856 {
2857 .aead = {
2858 .base = {
2859 .cra_name = "echainiv(authenc(hmac(sha512),"
2860 "cbc(des)))",
2861 .cra_driver_name = "echainiv-authenc-"
2862 "hmac-sha512-cbc-des-caam",
2863 .cra_blocksize = DES_BLOCK_SIZE,
2864 },
2865 .setkey = aead_setkey,
2866 .setauthsize = aead_setauthsize,
2867 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002868 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002869 .ivsize = DES_BLOCK_SIZE,
2870 .maxauthsize = SHA512_DIGEST_SIZE,
2871 },
2872 .caam = {
2873 .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2874 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2875 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002876 .geniv = true,
2877 },
2878 },
2879 {
2880 .aead = {
2881 .base = {
2882 .cra_name = "authenc(hmac(md5),"
2883 "rfc3686(ctr(aes)))",
2884 .cra_driver_name = "authenc-hmac-md5-"
2885 "rfc3686-ctr-aes-caam",
2886 .cra_blocksize = 1,
2887 },
2888 .setkey = aead_setkey,
2889 .setauthsize = aead_setauthsize,
2890 .encrypt = aead_encrypt,
2891 .decrypt = aead_decrypt,
2892 .ivsize = CTR_RFC3686_IV_SIZE,
2893 .maxauthsize = MD5_DIGEST_SIZE,
2894 },
2895 .caam = {
2896 .class1_alg_type = OP_ALG_ALGSEL_AES |
2897 OP_ALG_AAI_CTR_MOD128,
2898 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2899 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002900 .rfc3686 = true,
2901 },
2902 },
2903 {
2904 .aead = {
2905 .base = {
2906 .cra_name = "seqiv(authenc("
2907 "hmac(md5),rfc3686(ctr(aes))))",
2908 .cra_driver_name = "seqiv-authenc-hmac-md5-"
2909 "rfc3686-ctr-aes-caam",
2910 .cra_blocksize = 1,
2911 },
2912 .setkey = aead_setkey,
2913 .setauthsize = aead_setauthsize,
2914 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002915 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002916 .ivsize = CTR_RFC3686_IV_SIZE,
2917 .maxauthsize = MD5_DIGEST_SIZE,
2918 },
2919 .caam = {
2920 .class1_alg_type = OP_ALG_ALGSEL_AES |
2921 OP_ALG_AAI_CTR_MOD128,
2922 .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2923 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002924 .rfc3686 = true,
2925 .geniv = true,
2926 },
2927 },
2928 {
2929 .aead = {
2930 .base = {
2931 .cra_name = "authenc(hmac(sha1),"
2932 "rfc3686(ctr(aes)))",
2933 .cra_driver_name = "authenc-hmac-sha1-"
2934 "rfc3686-ctr-aes-caam",
2935 .cra_blocksize = 1,
2936 },
2937 .setkey = aead_setkey,
2938 .setauthsize = aead_setauthsize,
2939 .encrypt = aead_encrypt,
2940 .decrypt = aead_decrypt,
2941 .ivsize = CTR_RFC3686_IV_SIZE,
2942 .maxauthsize = SHA1_DIGEST_SIZE,
2943 },
2944 .caam = {
2945 .class1_alg_type = OP_ALG_ALGSEL_AES |
2946 OP_ALG_AAI_CTR_MOD128,
2947 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2948 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002949 .rfc3686 = true,
2950 },
2951 },
2952 {
2953 .aead = {
2954 .base = {
2955 .cra_name = "seqiv(authenc("
2956 "hmac(sha1),rfc3686(ctr(aes))))",
2957 .cra_driver_name = "seqiv-authenc-hmac-sha1-"
2958 "rfc3686-ctr-aes-caam",
2959 .cra_blocksize = 1,
2960 },
2961 .setkey = aead_setkey,
2962 .setauthsize = aead_setauthsize,
2963 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03002964 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08002965 .ivsize = CTR_RFC3686_IV_SIZE,
2966 .maxauthsize = SHA1_DIGEST_SIZE,
2967 },
2968 .caam = {
2969 .class1_alg_type = OP_ALG_ALGSEL_AES |
2970 OP_ALG_AAI_CTR_MOD128,
2971 .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2972 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002973 .rfc3686 = true,
2974 .geniv = true,
2975 },
2976 },
2977 {
2978 .aead = {
2979 .base = {
2980 .cra_name = "authenc(hmac(sha224),"
2981 "rfc3686(ctr(aes)))",
2982 .cra_driver_name = "authenc-hmac-sha224-"
2983 "rfc3686-ctr-aes-caam",
2984 .cra_blocksize = 1,
2985 },
2986 .setkey = aead_setkey,
2987 .setauthsize = aead_setauthsize,
2988 .encrypt = aead_encrypt,
2989 .decrypt = aead_decrypt,
2990 .ivsize = CTR_RFC3686_IV_SIZE,
2991 .maxauthsize = SHA224_DIGEST_SIZE,
2992 },
2993 .caam = {
2994 .class1_alg_type = OP_ALG_ALGSEL_AES |
2995 OP_ALG_AAI_CTR_MOD128,
2996 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2997 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08002998 .rfc3686 = true,
2999 },
3000 },
3001 {
3002 .aead = {
3003 .base = {
3004 .cra_name = "seqiv(authenc("
3005 "hmac(sha224),rfc3686(ctr(aes))))",
3006 .cra_driver_name = "seqiv-authenc-hmac-sha224-"
3007 "rfc3686-ctr-aes-caam",
3008 .cra_blocksize = 1,
3009 },
3010 .setkey = aead_setkey,
3011 .setauthsize = aead_setauthsize,
3012 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03003013 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08003014 .ivsize = CTR_RFC3686_IV_SIZE,
3015 .maxauthsize = SHA224_DIGEST_SIZE,
3016 },
3017 .caam = {
3018 .class1_alg_type = OP_ALG_ALGSEL_AES |
3019 OP_ALG_AAI_CTR_MOD128,
3020 .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3021 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003022 .rfc3686 = true,
3023 .geniv = true,
3024 },
3025 },
3026 {
3027 .aead = {
3028 .base = {
3029 .cra_name = "authenc(hmac(sha256),"
3030 "rfc3686(ctr(aes)))",
3031 .cra_driver_name = "authenc-hmac-sha256-"
3032 "rfc3686-ctr-aes-caam",
3033 .cra_blocksize = 1,
3034 },
3035 .setkey = aead_setkey,
3036 .setauthsize = aead_setauthsize,
3037 .encrypt = aead_encrypt,
3038 .decrypt = aead_decrypt,
3039 .ivsize = CTR_RFC3686_IV_SIZE,
3040 .maxauthsize = SHA256_DIGEST_SIZE,
3041 },
3042 .caam = {
3043 .class1_alg_type = OP_ALG_ALGSEL_AES |
3044 OP_ALG_AAI_CTR_MOD128,
3045 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3046 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003047 .rfc3686 = true,
3048 },
3049 },
3050 {
3051 .aead = {
3052 .base = {
3053 .cra_name = "seqiv(authenc(hmac(sha256),"
3054 "rfc3686(ctr(aes))))",
3055 .cra_driver_name = "seqiv-authenc-hmac-sha256-"
3056 "rfc3686-ctr-aes-caam",
3057 .cra_blocksize = 1,
3058 },
3059 .setkey = aead_setkey,
3060 .setauthsize = aead_setauthsize,
3061 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03003062 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08003063 .ivsize = CTR_RFC3686_IV_SIZE,
3064 .maxauthsize = SHA256_DIGEST_SIZE,
3065 },
3066 .caam = {
3067 .class1_alg_type = OP_ALG_ALGSEL_AES |
3068 OP_ALG_AAI_CTR_MOD128,
3069 .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3070 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003071 .rfc3686 = true,
3072 .geniv = true,
3073 },
3074 },
3075 {
3076 .aead = {
3077 .base = {
3078 .cra_name = "authenc(hmac(sha384),"
3079 "rfc3686(ctr(aes)))",
3080 .cra_driver_name = "authenc-hmac-sha384-"
3081 "rfc3686-ctr-aes-caam",
3082 .cra_blocksize = 1,
3083 },
3084 .setkey = aead_setkey,
3085 .setauthsize = aead_setauthsize,
3086 .encrypt = aead_encrypt,
3087 .decrypt = aead_decrypt,
3088 .ivsize = CTR_RFC3686_IV_SIZE,
3089 .maxauthsize = SHA384_DIGEST_SIZE,
3090 },
3091 .caam = {
3092 .class1_alg_type = OP_ALG_ALGSEL_AES |
3093 OP_ALG_AAI_CTR_MOD128,
3094 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3095 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003096 .rfc3686 = true,
3097 },
3098 },
3099 {
3100 .aead = {
3101 .base = {
3102 .cra_name = "seqiv(authenc(hmac(sha384),"
3103 "rfc3686(ctr(aes))))",
3104 .cra_driver_name = "seqiv-authenc-hmac-sha384-"
3105 "rfc3686-ctr-aes-caam",
3106 .cra_blocksize = 1,
3107 },
3108 .setkey = aead_setkey,
3109 .setauthsize = aead_setauthsize,
3110 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03003111 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08003112 .ivsize = CTR_RFC3686_IV_SIZE,
3113 .maxauthsize = SHA384_DIGEST_SIZE,
3114 },
3115 .caam = {
3116 .class1_alg_type = OP_ALG_ALGSEL_AES |
3117 OP_ALG_AAI_CTR_MOD128,
3118 .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3119 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003120 .rfc3686 = true,
3121 .geniv = true,
3122 },
3123 },
3124 {
3125 .aead = {
3126 .base = {
3127 .cra_name = "authenc(hmac(sha512),"
3128 "rfc3686(ctr(aes)))",
3129 .cra_driver_name = "authenc-hmac-sha512-"
3130 "rfc3686-ctr-aes-caam",
3131 .cra_blocksize = 1,
3132 },
3133 .setkey = aead_setkey,
3134 .setauthsize = aead_setauthsize,
3135 .encrypt = aead_encrypt,
3136 .decrypt = aead_decrypt,
3137 .ivsize = CTR_RFC3686_IV_SIZE,
3138 .maxauthsize = SHA512_DIGEST_SIZE,
3139 },
3140 .caam = {
3141 .class1_alg_type = OP_ALG_ALGSEL_AES |
3142 OP_ALG_AAI_CTR_MOD128,
3143 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3144 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003145 .rfc3686 = true,
3146 },
3147 },
3148 {
3149 .aead = {
3150 .base = {
3151 .cra_name = "seqiv(authenc(hmac(sha512),"
3152 "rfc3686(ctr(aes))))",
3153 .cra_driver_name = "seqiv-authenc-hmac-sha512-"
3154 "rfc3686-ctr-aes-caam",
3155 .cra_blocksize = 1,
3156 },
3157 .setkey = aead_setkey,
3158 .setauthsize = aead_setauthsize,
3159 .encrypt = aead_encrypt,
Horia Geantă8b18e232016-08-29 14:52:14 +03003160 .decrypt = aead_decrypt,
Herbert Xu479bcc72015-07-30 17:53:17 +08003161 .ivsize = CTR_RFC3686_IV_SIZE,
3162 .maxauthsize = SHA512_DIGEST_SIZE,
3163 },
3164 .caam = {
3165 .class1_alg_type = OP_ALG_ALGSEL_AES |
3166 OP_ALG_AAI_CTR_MOD128,
3167 .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3168 OP_ALG_AAI_HMAC_PRECOMP,
Herbert Xu479bcc72015-07-30 17:53:17 +08003169 .rfc3686 = true,
3170 .geniv = true,
3171 },
3172 },
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02003173 {
3174 .aead = {
3175 .base = {
3176 .cra_name = "rfc7539(chacha20,poly1305)",
3177 .cra_driver_name = "rfc7539-chacha20-poly1305-"
3178 "caam",
3179 .cra_blocksize = 1,
3180 },
3181 .setkey = chachapoly_setkey,
3182 .setauthsize = chachapoly_setauthsize,
3183 .encrypt = chachapoly_encrypt,
3184 .decrypt = chachapoly_decrypt,
3185 .ivsize = CHACHAPOLY_IV_SIZE,
3186 .maxauthsize = POLY1305_DIGEST_SIZE,
3187 },
3188 .caam = {
3189 .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3190 OP_ALG_AAI_AEAD,
3191 .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3192 OP_ALG_AAI_AEAD,
3193 },
3194 },
3195 {
3196 .aead = {
3197 .base = {
3198 .cra_name = "rfc7539esp(chacha20,poly1305)",
3199 .cra_driver_name = "rfc7539esp-chacha20-"
3200 "poly1305-caam",
3201 .cra_blocksize = 1,
3202 },
3203 .setkey = chachapoly_setkey,
3204 .setauthsize = chachapoly_setauthsize,
3205 .encrypt = chachapoly_encrypt,
3206 .decrypt = chachapoly_decrypt,
3207 .ivsize = 8,
3208 .maxauthsize = POLY1305_DIGEST_SIZE,
3209 },
3210 .caam = {
3211 .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3212 OP_ALG_AAI_AEAD,
3213 .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3214 OP_ALG_AAI_AEAD,
3215 },
3216 },
Herbert Xuf2147b82015-06-16 13:54:23 +08003217};
3218
Horia Geantă7e0880b2017-12-19 12:16:07 +02003219static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
3220 bool uses_dkp)
Herbert Xuf2147b82015-06-16 13:54:23 +08003221{
Horia Geantăbbf22342017-02-10 14:07:22 +02003222 dma_addr_t dma_addr;
Horia Geantă7e0880b2017-12-19 12:16:07 +02003223 struct caam_drv_private *priv;
Horia Geantăbbf22342017-02-10 14:07:22 +02003224
Herbert Xuf2147b82015-06-16 13:54:23 +08003225 ctx->jrdev = caam_jr_alloc();
3226 if (IS_ERR(ctx->jrdev)) {
3227 pr_err("Job Ring Device allocation for transform failed\n");
3228 return PTR_ERR(ctx->jrdev);
3229 }
3230
Horia Geantă7e0880b2017-12-19 12:16:07 +02003231 priv = dev_get_drvdata(ctx->jrdev->parent);
3232 if (priv->era >= 6 && uses_dkp)
3233 ctx->dir = DMA_BIDIRECTIONAL;
3234 else
3235 ctx->dir = DMA_TO_DEVICE;
3236
Horia Geantăbbf22342017-02-10 14:07:22 +02003237 dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3238 offsetof(struct caam_ctx,
3239 sh_desc_enc_dma),
Horia Geantă7e0880b2017-12-19 12:16:07 +02003240 ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
Horia Geantăbbf22342017-02-10 14:07:22 +02003241 if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3242 dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3243 caam_jr_free(ctx->jrdev);
3244 return -ENOMEM;
3245 }
3246
3247 ctx->sh_desc_enc_dma = dma_addr;
3248 ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3249 sh_desc_dec);
Horia Geantăbbf22342017-02-10 14:07:22 +02003250 ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key);
3251
Herbert Xuf2147b82015-06-16 13:54:23 +08003252 /* copy descriptor header template value */
Horia Geantădb576562016-11-22 15:44:04 +02003253 ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3254 ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
Herbert Xuf2147b82015-06-16 13:54:23 +08003255
3256 return 0;
3257}
3258
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003259static int caam_cra_init(struct crypto_skcipher *tfm)
Kim Phillips8e8ec592011-03-13 16:54:26 +08003260{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003261 struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
3262 struct caam_skcipher_alg *caam_alg =
3263 container_of(alg, typeof(*caam_alg), skcipher);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003264
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003265 return caam_init_common(crypto_skcipher_ctx(tfm), &caam_alg->caam,
3266 false);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003267}
3268
Herbert Xuf2147b82015-06-16 13:54:23 +08003269static int caam_aead_init(struct crypto_aead *tfm)
Kim Phillips8e8ec592011-03-13 16:54:26 +08003270{
Herbert Xuf2147b82015-06-16 13:54:23 +08003271 struct aead_alg *alg = crypto_aead_alg(tfm);
3272 struct caam_aead_alg *caam_alg =
3273 container_of(alg, struct caam_aead_alg, aead);
3274 struct caam_ctx *ctx = crypto_aead_ctx(tfm);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003275
Horia Geantă7e0880b2017-12-19 12:16:07 +02003276 return caam_init_common(ctx, &caam_alg->caam,
3277 alg->setkey == aead_setkey);
Herbert Xuf2147b82015-06-16 13:54:23 +08003278}
3279
3280static void caam_exit_common(struct caam_ctx *ctx)
3281{
Horia Geantăbbf22342017-02-10 14:07:22 +02003282 dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3283 offsetof(struct caam_ctx, sh_desc_enc_dma),
Horia Geantă7e0880b2017-12-19 12:16:07 +02003284 ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
Ruchika Guptacfc6f112013-10-25 12:01:03 +05303285 caam_jr_free(ctx->jrdev);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003286}
3287
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003288static void caam_cra_exit(struct crypto_skcipher *tfm)
Herbert Xuf2147b82015-06-16 13:54:23 +08003289{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003290 caam_exit_common(crypto_skcipher_ctx(tfm));
Herbert Xuf2147b82015-06-16 13:54:23 +08003291}
3292
3293static void caam_aead_exit(struct crypto_aead *tfm)
3294{
3295 caam_exit_common(crypto_aead_ctx(tfm));
3296}
3297
Kim Phillips8e8ec592011-03-13 16:54:26 +08003298static void __exit caam_algapi_exit(void)
3299{
Herbert Xuf2147b82015-06-16 13:54:23 +08003300 int i;
3301
3302 for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3303 struct caam_aead_alg *t_alg = driver_aeads + i;
3304
3305 if (t_alg->registered)
3306 crypto_unregister_aead(&t_alg->aead);
3307 }
Kim Phillips8e8ec592011-03-13 16:54:26 +08003308
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003309 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3310 struct caam_skcipher_alg *t_alg = driver_algs + i;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003311
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003312 if (t_alg->registered)
3313 crypto_unregister_skcipher(&t_alg->skcipher);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003314 }
Kim Phillips8e8ec592011-03-13 16:54:26 +08003315}
3316
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003317static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
Kim Phillips8e8ec592011-03-13 16:54:26 +08003318{
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003319 struct skcipher_alg *alg = &t_alg->skcipher;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003320
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003321 alg->base.cra_module = THIS_MODULE;
3322 alg->base.cra_priority = CAAM_CRA_PRIORITY;
3323 alg->base.cra_ctxsize = sizeof(struct caam_ctx);
3324 alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003325
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003326 alg->init = caam_cra_init;
3327 alg->exit = caam_cra_exit;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003328}
3329
Herbert Xuf2147b82015-06-16 13:54:23 +08003330static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3331{
3332 struct aead_alg *alg = &t_alg->aead;
3333
3334 alg->base.cra_module = THIS_MODULE;
3335 alg->base.cra_priority = CAAM_CRA_PRIORITY;
3336 alg->base.cra_ctxsize = sizeof(struct caam_ctx);
Herbert Xu5e4b8c12015-08-13 17:29:06 +08003337 alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
Herbert Xuf2147b82015-06-16 13:54:23 +08003338
3339 alg->init = caam_aead_init;
3340 alg->exit = caam_aead_exit;
3341}
3342
Kim Phillips8e8ec592011-03-13 16:54:26 +08003343static int __init caam_algapi_init(void)
3344{
Ruchika Gupta35af6402014-07-07 10:42:12 +05303345 struct device_node *dev_node;
3346 struct platform_device *pdev;
3347 struct device *ctrldev;
Victoria Milhoanbf834902015-08-05 11:28:48 -07003348 struct caam_drv_private *priv;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003349 int i = 0, err = 0;
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02003350 u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
Victoria Milhoanbf834902015-08-05 11:28:48 -07003351 unsigned int md_limit = SHA512_DIGEST_SIZE;
Herbert Xuf2147b82015-06-16 13:54:23 +08003352 bool registered = false;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003353
Ruchika Gupta35af6402014-07-07 10:42:12 +05303354 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
3355 if (!dev_node) {
3356 dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
3357 if (!dev_node)
3358 return -ENODEV;
3359 }
3360
3361 pdev = of_find_device_by_node(dev_node);
3362 if (!pdev) {
3363 of_node_put(dev_node);
3364 return -ENODEV;
3365 }
3366
3367 ctrldev = &pdev->dev;
3368 priv = dev_get_drvdata(ctrldev);
3369 of_node_put(dev_node);
3370
3371 /*
3372 * If priv is NULL, it's probably because the caam driver wasn't
3373 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
3374 */
3375 if (!priv)
3376 return -ENODEV;
3377
3378
Victoria Milhoanbf834902015-08-05 11:28:48 -07003379 /*
3380 * Register crypto algorithms the device supports.
3381 * First, detect presence and attributes of DES, AES, and MD blocks.
3382 */
Horia Geantăd239b102018-11-08 15:36:27 +02003383 if (priv->era < 10) {
3384 u32 cha_vid, cha_inst;
3385
3386 cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3387 aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
3388 md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3389
3390 cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3391 des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
3392 CHA_ID_LS_DES_SHIFT;
3393 aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
3394 md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02003395 ccha_inst = 0;
3396 ptha_inst = 0;
Horia Geantăd239b102018-11-08 15:36:27 +02003397 } else {
3398 u32 aesa, mdha;
3399
3400 aesa = rd_reg32(&priv->ctrl->vreg.aesa);
3401 mdha = rd_reg32(&priv->ctrl->vreg.mdha);
3402
3403 aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3404 md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3405
3406 des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
3407 aes_inst = aesa & CHA_VER_NUM_MASK;
3408 md_inst = mdha & CHA_VER_NUM_MASK;
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02003409 ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
3410 ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
Horia Geantăd239b102018-11-08 15:36:27 +02003411 }
Kim Phillips8e8ec592011-03-13 16:54:26 +08003412
Victoria Milhoanbf834902015-08-05 11:28:48 -07003413 /* If MD is present, limit digest size based on LP256 */
Horia Geantăd239b102018-11-08 15:36:27 +02003414 if (md_inst && md_vid == CHA_VER_VID_MD_LP256)
Victoria Milhoanbf834902015-08-05 11:28:48 -07003415 md_limit = SHA256_DIGEST_SIZE;
3416
3417 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003418 struct caam_skcipher_alg *t_alg = driver_algs + i;
3419 u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
Victoria Milhoanbf834902015-08-05 11:28:48 -07003420
3421 /* Skip DES algorithms if not supported by device */
3422 if (!des_inst &&
3423 ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3424 (alg_sel == OP_ALG_ALGSEL_DES)))
3425 continue;
3426
3427 /* Skip AES algorithms if not supported by device */
3428 if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3429 continue;
3430
Sven Ebenfeld83d2c9a2016-11-07 18:51:34 +01003431 /*
3432 * Check support for AES modes not available
3433 * on LP devices.
3434 */
Horia Geantăd239b102018-11-08 15:36:27 +02003435 if (aes_vid == CHA_VER_VID_AES_LP &&
3436 (t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK) ==
3437 OP_ALG_AAI_XTS)
3438 continue;
Sven Ebenfeld83d2c9a2016-11-07 18:51:34 +01003439
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003440 caam_skcipher_alg_init(t_alg);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003441
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003442 err = crypto_register_skcipher(&t_alg->skcipher);
Kim Phillips8e8ec592011-03-13 16:54:26 +08003443 if (err) {
Ruchika Guptacfc6f112013-10-25 12:01:03 +05303444 pr_warn("%s alg registration failed\n",
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003445 t_alg->skcipher.base.cra_driver_name);
Herbert Xuf2147b82015-06-16 13:54:23 +08003446 continue;
3447 }
3448
Horia Geantă5ca7bad2018-08-06 15:43:59 +03003449 t_alg->registered = true;
Herbert Xuf2147b82015-06-16 13:54:23 +08003450 registered = true;
Kim Phillips8e8ec592011-03-13 16:54:26 +08003451 }
Herbert Xuf2147b82015-06-16 13:54:23 +08003452
3453 for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3454 struct caam_aead_alg *t_alg = driver_aeads + i;
Victoria Milhoanbf834902015-08-05 11:28:48 -07003455 u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3456 OP_ALG_ALGSEL_MASK;
3457 u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3458 OP_ALG_ALGSEL_MASK;
3459 u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3460
3461 /* Skip DES algorithms if not supported by device */
3462 if (!des_inst &&
3463 ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3464 (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3465 continue;
3466
3467 /* Skip AES algorithms if not supported by device */
3468 if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3469 continue;
3470
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02003471 /* Skip CHACHA20 algorithms if not supported by device */
3472 if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
3473 continue;
3474
3475 /* Skip POLY1305 algorithms if not supported by device */
3476 if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
3477 continue;
3478
Victoria Milhoanbf834902015-08-05 11:28:48 -07003479 /*
3480 * Check support for AES algorithms not available
3481 * on LP devices.
3482 */
Horia Geantăd239b102018-11-08 15:36:27 +02003483 if (aes_vid == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
3484 continue;
Victoria Milhoanbf834902015-08-05 11:28:48 -07003485
3486 /*
3487 * Skip algorithms requiring message digests
3488 * if MD or MD size is not supported by device.
3489 */
Horia Geantă2dd3fde2018-12-21 14:47:46 +02003490 if (is_mdha(c2_alg_sel) &&
Horia Geantăd6bbd4e2018-11-08 15:36:30 +02003491 (!md_inst || t_alg->aead.maxauthsize > md_limit))
3492 continue;
Herbert Xuf2147b82015-06-16 13:54:23 +08003493
3494 caam_aead_alg_init(t_alg);
3495
3496 err = crypto_register_aead(&t_alg->aead);
3497 if (err) {
3498 pr_warn("%s alg registration failed\n",
3499 t_alg->aead.base.cra_driver_name);
3500 continue;
3501 }
3502
3503 t_alg->registered = true;
3504 registered = true;
3505 }
3506
3507 if (registered)
Ruchika Guptacfc6f112013-10-25 12:01:03 +05303508 pr_info("caam algorithms registered in /proc/crypto\n");
Kim Phillips8e8ec592011-03-13 16:54:26 +08003509
3510 return err;
3511}
3512
3513module_init(caam_algapi_init);
3514module_exit(caam_algapi_exit);
3515
3516MODULE_LICENSE("GPL");
3517MODULE_DESCRIPTION("FSL CAAM support for crypto API");
3518MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");