1618b5dc4SHoria Geantă // SPDX-License-Identifier: GPL-2.0+
2b189817cSHoria Geantă /*
3b189817cSHoria Geantă * Freescale FSL CAAM support for crypto API over QI backend.
4b189817cSHoria Geantă * Based on caamalg.c
5b189817cSHoria Geantă *
6b189817cSHoria Geantă * Copyright 2013-2016 Freescale Semiconductor, Inc.
7a5e5c133SHoria Geantă * Copyright 2016-2019 NXP
8b189817cSHoria Geantă */
9b189817cSHoria Geantă
10b189817cSHoria Geantă #include "compat.h"
11d3b5a87cSHoria Geantă #include "ctrl.h"
12b189817cSHoria Geantă #include "regs.h"
13b189817cSHoria Geantă #include "intern.h"
14b189817cSHoria Geantă #include "desc_constr.h"
15b189817cSHoria Geantă #include "error.h"
16b189817cSHoria Geantă #include "sg_sw_qm.h"
17b189817cSHoria Geantă #include "key_gen.h"
18b189817cSHoria Geantă #include "qi.h"
19b189817cSHoria Geantă #include "jr.h"
20b189817cSHoria Geantă #include "caamalg_desc.h"
2162b9a669SAndrei Botila #include <crypto/xts.h>
2283e8aa91SAndrei Botila #include <asm/unaligned.h>
23*660ca947SHerbert Xu #include <linux/device.h>
24*660ca947SHerbert Xu #include <linux/err.h>
25199354d7SHerbert Xu #include <linux/dma-mapping.h>
26199354d7SHerbert Xu #include <linux/kernel.h>
27*660ca947SHerbert Xu #include <linux/string.h>
28b189817cSHoria Geantă
29b189817cSHoria Geantă /*
30b189817cSHoria Geantă * crypto alg
31b189817cSHoria Geantă */
32b189817cSHoria Geantă #define CAAM_CRA_PRIORITY 2000
33b189817cSHoria Geantă /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
34b189817cSHoria Geantă #define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + \
35b189817cSHoria Geantă SHA512_DIGEST_SIZE * 2)
36b189817cSHoria Geantă
37b189817cSHoria Geantă #define DESC_MAX_USED_BYTES (DESC_QI_AEAD_GIVENC_LEN + \
38b189817cSHoria Geantă CAAM_MAX_KEY_SIZE)
39b189817cSHoria Geantă #define DESC_MAX_USED_LEN (DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
40b189817cSHoria Geantă
41b189817cSHoria Geantă struct caam_alg_entry {
42b189817cSHoria Geantă int class1_alg_type;
43b189817cSHoria Geantă int class2_alg_type;
44b189817cSHoria Geantă bool rfc3686;
45b189817cSHoria Geantă bool geniv;
4624586b5fSHerbert Xu bool nodkp;
47b189817cSHoria Geantă };
48b189817cSHoria Geantă
49b189817cSHoria Geantă struct caam_aead_alg {
50b189817cSHoria Geantă struct aead_alg aead;
51b189817cSHoria Geantă struct caam_alg_entry caam;
52b189817cSHoria Geantă bool registered;
53b189817cSHoria Geantă };
54b189817cSHoria Geantă
559dbe3072SHoria Geantă struct caam_skcipher_alg {
569dbe3072SHoria Geantă struct skcipher_alg skcipher;
579dbe3072SHoria Geantă struct caam_alg_entry caam;
589dbe3072SHoria Geantă bool registered;
599dbe3072SHoria Geantă };
609dbe3072SHoria Geantă
61b189817cSHoria Geantă /*
62b189817cSHoria Geantă * per-session context
63b189817cSHoria Geantă */
64b189817cSHoria Geantă struct caam_ctx {
65b189817cSHoria Geantă struct device *jrdev;
66b189817cSHoria Geantă u32 sh_desc_enc[DESC_MAX_USED_LEN];
67b189817cSHoria Geantă u32 sh_desc_dec[DESC_MAX_USED_LEN];
68b189817cSHoria Geantă u8 key[CAAM_MAX_KEY_SIZE];
69b189817cSHoria Geantă dma_addr_t key_dma;
707e0880b9SHoria Geantă enum dma_data_direction dir;
71b189817cSHoria Geantă struct alginfo adata;
72b189817cSHoria Geantă struct alginfo cdata;
73b189817cSHoria Geantă unsigned int authsize;
74b189817cSHoria Geantă struct device *qidev;
75b189817cSHoria Geantă spinlock_t lock; /* Protects multiple init of driver context */
76b189817cSHoria Geantă struct caam_drv_ctx *drv_ctx[NUM_OP];
7762b9a669SAndrei Botila bool xts_key_fallback;
7883e8aa91SAndrei Botila struct crypto_skcipher *fallback;
7983e8aa91SAndrei Botila };
8083e8aa91SAndrei Botila
8183e8aa91SAndrei Botila struct caam_skcipher_req_ctx {
8283e8aa91SAndrei Botila struct skcipher_request fallback_req;
83b189817cSHoria Geantă };
84b189817cSHoria Geantă
aead_set_sh_desc(struct crypto_aead * aead)85b189817cSHoria Geantă static int aead_set_sh_desc(struct crypto_aead *aead)
86b189817cSHoria Geantă {
87b189817cSHoria Geantă struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
88b189817cSHoria Geantă typeof(*alg), aead);
894cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
90b189817cSHoria Geantă unsigned int ivsize = crypto_aead_ivsize(aead);
91b189817cSHoria Geantă u32 ctx1_iv_off = 0;
92b189817cSHoria Geantă u32 *nonce = NULL;
93b189817cSHoria Geantă unsigned int data_len[2];
94b189817cSHoria Geantă u32 inl_mask;
95b189817cSHoria Geantă const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
96b189817cSHoria Geantă OP_ALG_AAI_CTR_MOD128);
97b189817cSHoria Geantă const bool is_rfc3686 = alg->caam.rfc3686;
987e0880b9SHoria Geantă struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
99b189817cSHoria Geantă
100b189817cSHoria Geantă if (!ctx->cdata.keylen || !ctx->authsize)
101b189817cSHoria Geantă return 0;
102b189817cSHoria Geantă
103b189817cSHoria Geantă /*
104b189817cSHoria Geantă * AES-CTR needs to load IV in CONTEXT1 reg
105b189817cSHoria Geantă * at an offset of 128bits (16bytes)
106b189817cSHoria Geantă * CONTEXT1[255:128] = IV
107b189817cSHoria Geantă */
108b189817cSHoria Geantă if (ctr_mode)
109b189817cSHoria Geantă ctx1_iv_off = 16;
110b189817cSHoria Geantă
111b189817cSHoria Geantă /*
112b189817cSHoria Geantă * RFC3686 specific:
113b189817cSHoria Geantă * CONTEXT1[255:128] = {NONCE, IV, COUNTER}
114b189817cSHoria Geantă */
115b189817cSHoria Geantă if (is_rfc3686) {
116b189817cSHoria Geantă ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
117b189817cSHoria Geantă nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
118b189817cSHoria Geantă ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
119b189817cSHoria Geantă }
120b189817cSHoria Geantă
121e9b4913aSHoria Geantă /*
122e9b4913aSHoria Geantă * In case |user key| > |derived key|, using DKP<imm,imm> would result
123e9b4913aSHoria Geantă * in invalid opcodes (last bytes of user key) in the resulting
124e9b4913aSHoria Geantă * descriptor. Use DKP<ptr,imm> instead => both virtual and dma key
125e9b4913aSHoria Geantă * addresses are needed.
126e9b4913aSHoria Geantă */
127e9b4913aSHoria Geantă ctx->adata.key_virt = ctx->key;
128e9b4913aSHoria Geantă ctx->adata.key_dma = ctx->key_dma;
129e9b4913aSHoria Geantă
130e9b4913aSHoria Geantă ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
131e9b4913aSHoria Geantă ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
132e9b4913aSHoria Geantă
133b189817cSHoria Geantă data_len[0] = ctx->adata.keylen_pad;
134b189817cSHoria Geantă data_len[1] = ctx->cdata.keylen;
135b189817cSHoria Geantă
136b189817cSHoria Geantă if (alg->caam.geniv)
137b189817cSHoria Geantă goto skip_enc;
138b189817cSHoria Geantă
139b189817cSHoria Geantă /* aead_encrypt shared descriptor */
140b189817cSHoria Geantă if (desc_inline_query(DESC_QI_AEAD_ENC_LEN +
141b189817cSHoria Geantă (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
142b189817cSHoria Geantă DESC_JOB_IO_LEN, data_len, &inl_mask,
143b189817cSHoria Geantă ARRAY_SIZE(data_len)) < 0)
144b189817cSHoria Geantă return -EINVAL;
145b189817cSHoria Geantă
146b189817cSHoria Geantă ctx->adata.key_inline = !!(inl_mask & 1);
147b189817cSHoria Geantă ctx->cdata.key_inline = !!(inl_mask & 2);
148b189817cSHoria Geantă
149b189817cSHoria Geantă cnstr_shdsc_aead_encap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata,
150b189817cSHoria Geantă ivsize, ctx->authsize, is_rfc3686, nonce,
1517e0880b9SHoria Geantă ctx1_iv_off, true, ctrlpriv->era);
152b189817cSHoria Geantă
153b189817cSHoria Geantă skip_enc:
154b189817cSHoria Geantă /* aead_decrypt shared descriptor */
155b189817cSHoria Geantă if (desc_inline_query(DESC_QI_AEAD_DEC_LEN +
156b189817cSHoria Geantă (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
157b189817cSHoria Geantă DESC_JOB_IO_LEN, data_len, &inl_mask,
158b189817cSHoria Geantă ARRAY_SIZE(data_len)) < 0)
159b189817cSHoria Geantă return -EINVAL;
160b189817cSHoria Geantă
161b189817cSHoria Geantă ctx->adata.key_inline = !!(inl_mask & 1);
162b189817cSHoria Geantă ctx->cdata.key_inline = !!(inl_mask & 2);
163b189817cSHoria Geantă
164b189817cSHoria Geantă cnstr_shdsc_aead_decap(ctx->sh_desc_dec, &ctx->cdata, &ctx->adata,
165b189817cSHoria Geantă ivsize, ctx->authsize, alg->caam.geniv,
1667e0880b9SHoria Geantă is_rfc3686, nonce, ctx1_iv_off, true,
1677e0880b9SHoria Geantă ctrlpriv->era);
168b189817cSHoria Geantă
169b189817cSHoria Geantă if (!alg->caam.geniv)
170b189817cSHoria Geantă goto skip_givenc;
171b189817cSHoria Geantă
172b189817cSHoria Geantă /* aead_givencrypt shared descriptor */
173b189817cSHoria Geantă if (desc_inline_query(DESC_QI_AEAD_GIVENC_LEN +
174b189817cSHoria Geantă (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
175b189817cSHoria Geantă DESC_JOB_IO_LEN, data_len, &inl_mask,
176b189817cSHoria Geantă ARRAY_SIZE(data_len)) < 0)
177b189817cSHoria Geantă return -EINVAL;
178b189817cSHoria Geantă
179b189817cSHoria Geantă ctx->adata.key_inline = !!(inl_mask & 1);
180b189817cSHoria Geantă ctx->cdata.key_inline = !!(inl_mask & 2);
181b189817cSHoria Geantă
182b189817cSHoria Geantă cnstr_shdsc_aead_givencap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata,
183b189817cSHoria Geantă ivsize, ctx->authsize, is_rfc3686, nonce,
1847e0880b9SHoria Geantă ctx1_iv_off, true, ctrlpriv->era);
185b189817cSHoria Geantă
186b189817cSHoria Geantă skip_givenc:
187b189817cSHoria Geantă return 0;
188b189817cSHoria Geantă }
189b189817cSHoria Geantă
aead_setauthsize(struct crypto_aead * authenc,unsigned int authsize)190b189817cSHoria Geantă static int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
191b189817cSHoria Geantă {
1924cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
193b189817cSHoria Geantă
194b189817cSHoria Geantă ctx->authsize = authsize;
195b189817cSHoria Geantă aead_set_sh_desc(authenc);
196b189817cSHoria Geantă
197b189817cSHoria Geantă return 0;
198b189817cSHoria Geantă }
199b189817cSHoria Geantă
aead_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)200b189817cSHoria Geantă static int aead_setkey(struct crypto_aead *aead, const u8 *key,
201b189817cSHoria Geantă unsigned int keylen)
202b189817cSHoria Geantă {
2034cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
204b189817cSHoria Geantă struct device *jrdev = ctx->jrdev;
2057e0880b9SHoria Geantă struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
206b189817cSHoria Geantă struct crypto_authenc_keys keys;
207b189817cSHoria Geantă int ret = 0;
208b189817cSHoria Geantă
209b189817cSHoria Geantă if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
210b189817cSHoria Geantă goto badkey;
211b189817cSHoria Geantă
2126e005503SSascha Hauer dev_dbg(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
213b189817cSHoria Geantă keys.authkeylen + keys.enckeylen, keys.enckeylen,
214b189817cSHoria Geantă keys.authkeylen);
2156e005503SSascha Hauer print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
216b189817cSHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
217b189817cSHoria Geantă
2187e0880b9SHoria Geantă /*
2197e0880b9SHoria Geantă * If DKP is supported, use it in the shared descriptor to generate
2207e0880b9SHoria Geantă * the split key.
2217e0880b9SHoria Geantă */
2227e0880b9SHoria Geantă if (ctrlpriv->era >= 6) {
2237e0880b9SHoria Geantă ctx->adata.keylen = keys.authkeylen;
2247e0880b9SHoria Geantă ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
2257e0880b9SHoria Geantă OP_ALG_ALGSEL_MASK);
2267e0880b9SHoria Geantă
2277e0880b9SHoria Geantă if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
2287e0880b9SHoria Geantă goto badkey;
2297e0880b9SHoria Geantă
2307e0880b9SHoria Geantă memcpy(ctx->key, keys.authkey, keys.authkeylen);
2317e0880b9SHoria Geantă memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
2327e0880b9SHoria Geantă keys.enckeylen);
233a7cd942bSHoria Geantă dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
2347e0880b9SHoria Geantă ctx->adata.keylen_pad +
2357e0880b9SHoria Geantă keys.enckeylen, ctx->dir);
2367e0880b9SHoria Geantă goto skip_split_key;
2377e0880b9SHoria Geantă }
2387e0880b9SHoria Geantă
239b189817cSHoria Geantă ret = gen_split_key(jrdev, ctx->key, &ctx->adata, keys.authkey,
240b189817cSHoria Geantă keys.authkeylen, CAAM_MAX_KEY_SIZE -
241b189817cSHoria Geantă keys.enckeylen);
242b189817cSHoria Geantă if (ret)
243b189817cSHoria Geantă goto badkey;
244b189817cSHoria Geantă
245b189817cSHoria Geantă /* postpend encryption key to auth split key */
246b189817cSHoria Geantă memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
247a7cd942bSHoria Geantă dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
248a7cd942bSHoria Geantă ctx->adata.keylen_pad + keys.enckeylen,
249a7cd942bSHoria Geantă ctx->dir);
250671e5038SIuliana Prodan
251671e5038SIuliana Prodan print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ",
252b189817cSHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
253b189817cSHoria Geantă ctx->adata.keylen_pad + keys.enckeylen, 1);
254b189817cSHoria Geantă
2557e0880b9SHoria Geantă skip_split_key:
256b189817cSHoria Geantă ctx->cdata.keylen = keys.enckeylen;
257b189817cSHoria Geantă
258b189817cSHoria Geantă ret = aead_set_sh_desc(aead);
259b189817cSHoria Geantă if (ret)
260b189817cSHoria Geantă goto badkey;
261b189817cSHoria Geantă
262b189817cSHoria Geantă /* Now update the driver contexts with the new shared descriptor */
263b189817cSHoria Geantă if (ctx->drv_ctx[ENCRYPT]) {
264b189817cSHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
265b189817cSHoria Geantă ctx->sh_desc_enc);
266b189817cSHoria Geantă if (ret) {
267b189817cSHoria Geantă dev_err(jrdev, "driver enc context update failed\n");
268b189817cSHoria Geantă goto badkey;
269b189817cSHoria Geantă }
270b189817cSHoria Geantă }
271b189817cSHoria Geantă
272b189817cSHoria Geantă if (ctx->drv_ctx[DECRYPT]) {
273b189817cSHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
274b189817cSHoria Geantă ctx->sh_desc_dec);
275b189817cSHoria Geantă if (ret) {
276b189817cSHoria Geantă dev_err(jrdev, "driver dec context update failed\n");
277b189817cSHoria Geantă goto badkey;
278b189817cSHoria Geantă }
279b189817cSHoria Geantă }
280b189817cSHoria Geantă
281cc4ccaafSTudor-Dan Ambarus memzero_explicit(&keys, sizeof(keys));
282b189817cSHoria Geantă return ret;
283b189817cSHoria Geantă badkey:
284cc4ccaafSTudor-Dan Ambarus memzero_explicit(&keys, sizeof(keys));
285b189817cSHoria Geantă return -EINVAL;
286b189817cSHoria Geantă }
287b189817cSHoria Geantă
des3_aead_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)2881b52c409SHerbert Xu static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key,
2891b52c409SHerbert Xu unsigned int keylen)
2901b52c409SHerbert Xu {
2911b52c409SHerbert Xu struct crypto_authenc_keys keys;
2921b52c409SHerbert Xu int err;
2931b52c409SHerbert Xu
2941b52c409SHerbert Xu err = crypto_authenc_extractkeys(&keys, key, keylen);
2951b52c409SHerbert Xu if (unlikely(err))
2961b52c409SHerbert Xu return err;
2971b52c409SHerbert Xu
298a628c5a1SArd Biesheuvel err = verify_aead_des3_key(aead, keys.enckey, keys.enckeylen) ?:
299a628c5a1SArd Biesheuvel aead_setkey(aead, key, keylen);
300a628c5a1SArd Biesheuvel
301a628c5a1SArd Biesheuvel memzero_explicit(&keys, sizeof(keys));
302a628c5a1SArd Biesheuvel return err;
3031b52c409SHerbert Xu }
3041b52c409SHerbert Xu
gcm_set_sh_desc(struct crypto_aead * aead)305d3e41b50SHoria Geantă static int gcm_set_sh_desc(struct crypto_aead *aead)
306d3e41b50SHoria Geantă {
3074cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
308d3e41b50SHoria Geantă unsigned int ivsize = crypto_aead_ivsize(aead);
309d3e41b50SHoria Geantă int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
310d3e41b50SHoria Geantă ctx->cdata.keylen;
311d3e41b50SHoria Geantă
312d3e41b50SHoria Geantă if (!ctx->cdata.keylen || !ctx->authsize)
313d3e41b50SHoria Geantă return 0;
314d3e41b50SHoria Geantă
315d3e41b50SHoria Geantă /*
316d3e41b50SHoria Geantă * Job Descriptor and Shared Descriptor
317d3e41b50SHoria Geantă * must fit into the 64-word Descriptor h/w Buffer
318d3e41b50SHoria Geantă */
319d3e41b50SHoria Geantă if (rem_bytes >= DESC_QI_GCM_ENC_LEN) {
320d3e41b50SHoria Geantă ctx->cdata.key_inline = true;
321d3e41b50SHoria Geantă ctx->cdata.key_virt = ctx->key;
322d3e41b50SHoria Geantă } else {
323d3e41b50SHoria Geantă ctx->cdata.key_inline = false;
324d3e41b50SHoria Geantă ctx->cdata.key_dma = ctx->key_dma;
325d3e41b50SHoria Geantă }
326d3e41b50SHoria Geantă
327d3e41b50SHoria Geantă cnstr_shdsc_gcm_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
328d3e41b50SHoria Geantă ctx->authsize, true);
329d3e41b50SHoria Geantă
330d3e41b50SHoria Geantă /*
331d3e41b50SHoria Geantă * Job Descriptor and Shared Descriptor
332d3e41b50SHoria Geantă * must fit into the 64-word Descriptor h/w Buffer
333d3e41b50SHoria Geantă */
334d3e41b50SHoria Geantă if (rem_bytes >= DESC_QI_GCM_DEC_LEN) {
335d3e41b50SHoria Geantă ctx->cdata.key_inline = true;
336d3e41b50SHoria Geantă ctx->cdata.key_virt = ctx->key;
337d3e41b50SHoria Geantă } else {
338d3e41b50SHoria Geantă ctx->cdata.key_inline = false;
339d3e41b50SHoria Geantă ctx->cdata.key_dma = ctx->key_dma;
340d3e41b50SHoria Geantă }
341d3e41b50SHoria Geantă
342d3e41b50SHoria Geantă cnstr_shdsc_gcm_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
343d3e41b50SHoria Geantă ctx->authsize, true);
344d3e41b50SHoria Geantă
345d3e41b50SHoria Geantă return 0;
346d3e41b50SHoria Geantă }
347d3e41b50SHoria Geantă
gcm_setauthsize(struct crypto_aead * authenc,unsigned int authsize)348d3e41b50SHoria Geantă static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
349d3e41b50SHoria Geantă {
3504cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
35168a51394SIuliana Prodan int err;
35268a51394SIuliana Prodan
35368a51394SIuliana Prodan err = crypto_gcm_check_authsize(authsize);
35468a51394SIuliana Prodan if (err)
35568a51394SIuliana Prodan return err;
356d3e41b50SHoria Geantă
357d3e41b50SHoria Geantă ctx->authsize = authsize;
358d3e41b50SHoria Geantă gcm_set_sh_desc(authenc);
359d3e41b50SHoria Geantă
360d3e41b50SHoria Geantă return 0;
361d3e41b50SHoria Geantă }
362d3e41b50SHoria Geantă
gcm_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)363d3e41b50SHoria Geantă static int gcm_setkey(struct crypto_aead *aead,
364d3e41b50SHoria Geantă const u8 *key, unsigned int keylen)
365d3e41b50SHoria Geantă {
3664cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
367d3e41b50SHoria Geantă struct device *jrdev = ctx->jrdev;
368d3e41b50SHoria Geantă int ret;
369d3e41b50SHoria Geantă
370836d8f43SIuliana Prodan ret = aes_check_keylen(keylen);
371674f368aSEric Biggers if (ret)
372836d8f43SIuliana Prodan return ret;
373836d8f43SIuliana Prodan
3746e005503SSascha Hauer print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
375d3e41b50SHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
376d3e41b50SHoria Geantă
377d3e41b50SHoria Geantă memcpy(ctx->key, key, keylen);
378a7cd942bSHoria Geantă dma_sync_single_for_device(jrdev->parent, ctx->key_dma, keylen,
379a7cd942bSHoria Geantă ctx->dir);
380d3e41b50SHoria Geantă ctx->cdata.keylen = keylen;
381d3e41b50SHoria Geantă
382d3e41b50SHoria Geantă ret = gcm_set_sh_desc(aead);
383d3e41b50SHoria Geantă if (ret)
384d3e41b50SHoria Geantă return ret;
385d3e41b50SHoria Geantă
386d3e41b50SHoria Geantă /* Now update the driver contexts with the new shared descriptor */
387d3e41b50SHoria Geantă if (ctx->drv_ctx[ENCRYPT]) {
388d3e41b50SHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
389d3e41b50SHoria Geantă ctx->sh_desc_enc);
390d3e41b50SHoria Geantă if (ret) {
391d3e41b50SHoria Geantă dev_err(jrdev, "driver enc context update failed\n");
392d3e41b50SHoria Geantă return ret;
393d3e41b50SHoria Geantă }
394d3e41b50SHoria Geantă }
395d3e41b50SHoria Geantă
396d3e41b50SHoria Geantă if (ctx->drv_ctx[DECRYPT]) {
397d3e41b50SHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
398d3e41b50SHoria Geantă ctx->sh_desc_dec);
399d3e41b50SHoria Geantă if (ret) {
400d3e41b50SHoria Geantă dev_err(jrdev, "driver dec context update failed\n");
401d3e41b50SHoria Geantă return ret;
402d3e41b50SHoria Geantă }
403d3e41b50SHoria Geantă }
404d3e41b50SHoria Geantă
405d3e41b50SHoria Geantă return 0;
406d3e41b50SHoria Geantă }
407d3e41b50SHoria Geantă
rfc4106_set_sh_desc(struct crypto_aead * aead)408d3e41b50SHoria Geantă static int rfc4106_set_sh_desc(struct crypto_aead *aead)
409d3e41b50SHoria Geantă {
4104cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
411d3e41b50SHoria Geantă unsigned int ivsize = crypto_aead_ivsize(aead);
412d3e41b50SHoria Geantă int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
413d3e41b50SHoria Geantă ctx->cdata.keylen;
414d3e41b50SHoria Geantă
415d3e41b50SHoria Geantă if (!ctx->cdata.keylen || !ctx->authsize)
416d3e41b50SHoria Geantă return 0;
417d3e41b50SHoria Geantă
418d3e41b50SHoria Geantă ctx->cdata.key_virt = ctx->key;
419d3e41b50SHoria Geantă
420d3e41b50SHoria Geantă /*
421d3e41b50SHoria Geantă * Job Descriptor and Shared Descriptor
422d3e41b50SHoria Geantă * must fit into the 64-word Descriptor h/w Buffer
423d3e41b50SHoria Geantă */
424d3e41b50SHoria Geantă if (rem_bytes >= DESC_QI_RFC4106_ENC_LEN) {
425d3e41b50SHoria Geantă ctx->cdata.key_inline = true;
426d3e41b50SHoria Geantă } else {
427d3e41b50SHoria Geantă ctx->cdata.key_inline = false;
428d3e41b50SHoria Geantă ctx->cdata.key_dma = ctx->key_dma;
429d3e41b50SHoria Geantă }
430d3e41b50SHoria Geantă
431d3e41b50SHoria Geantă cnstr_shdsc_rfc4106_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
432d3e41b50SHoria Geantă ctx->authsize, true);
433d3e41b50SHoria Geantă
434d3e41b50SHoria Geantă /*
435d3e41b50SHoria Geantă * Job Descriptor and Shared Descriptor
436d3e41b50SHoria Geantă * must fit into the 64-word Descriptor h/w Buffer
437d3e41b50SHoria Geantă */
438d3e41b50SHoria Geantă if (rem_bytes >= DESC_QI_RFC4106_DEC_LEN) {
439d3e41b50SHoria Geantă ctx->cdata.key_inline = true;
440d3e41b50SHoria Geantă } else {
441d3e41b50SHoria Geantă ctx->cdata.key_inline = false;
442d3e41b50SHoria Geantă ctx->cdata.key_dma = ctx->key_dma;
443d3e41b50SHoria Geantă }
444d3e41b50SHoria Geantă
445d3e41b50SHoria Geantă cnstr_shdsc_rfc4106_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
446d3e41b50SHoria Geantă ctx->authsize, true);
447d3e41b50SHoria Geantă
448d3e41b50SHoria Geantă return 0;
449d3e41b50SHoria Geantă }
450d3e41b50SHoria Geantă
rfc4106_setauthsize(struct crypto_aead * authenc,unsigned int authsize)451d3e41b50SHoria Geantă static int rfc4106_setauthsize(struct crypto_aead *authenc,
452d3e41b50SHoria Geantă unsigned int authsize)
453d3e41b50SHoria Geantă {
4544cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
45568a51394SIuliana Prodan int err;
45668a51394SIuliana Prodan
45768a51394SIuliana Prodan err = crypto_rfc4106_check_authsize(authsize);
45868a51394SIuliana Prodan if (err)
45968a51394SIuliana Prodan return err;
460d3e41b50SHoria Geantă
461d3e41b50SHoria Geantă ctx->authsize = authsize;
462d3e41b50SHoria Geantă rfc4106_set_sh_desc(authenc);
463d3e41b50SHoria Geantă
464d3e41b50SHoria Geantă return 0;
465d3e41b50SHoria Geantă }
466d3e41b50SHoria Geantă
rfc4106_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)467d3e41b50SHoria Geantă static int rfc4106_setkey(struct crypto_aead *aead,
468d3e41b50SHoria Geantă const u8 *key, unsigned int keylen)
469d3e41b50SHoria Geantă {
4704cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
471d3e41b50SHoria Geantă struct device *jrdev = ctx->jrdev;
472d3e41b50SHoria Geantă int ret;
473d3e41b50SHoria Geantă
474836d8f43SIuliana Prodan ret = aes_check_keylen(keylen - 4);
475674f368aSEric Biggers if (ret)
476836d8f43SIuliana Prodan return ret;
477d3e41b50SHoria Geantă
4786e005503SSascha Hauer print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
479d3e41b50SHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
480d3e41b50SHoria Geantă
481d3e41b50SHoria Geantă memcpy(ctx->key, key, keylen);
482d3e41b50SHoria Geantă /*
483d3e41b50SHoria Geantă * The last four bytes of the key material are used as the salt value
484d3e41b50SHoria Geantă * in the nonce. Update the AES key length.
485d3e41b50SHoria Geantă */
486d3e41b50SHoria Geantă ctx->cdata.keylen = keylen - 4;
487a7cd942bSHoria Geantă dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
488a7cd942bSHoria Geantă ctx->cdata.keylen, ctx->dir);
489d3e41b50SHoria Geantă
490d3e41b50SHoria Geantă ret = rfc4106_set_sh_desc(aead);
491d3e41b50SHoria Geantă if (ret)
492d3e41b50SHoria Geantă return ret;
493d3e41b50SHoria Geantă
494d3e41b50SHoria Geantă /* Now update the driver contexts with the new shared descriptor */
495d3e41b50SHoria Geantă if (ctx->drv_ctx[ENCRYPT]) {
496d3e41b50SHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
497d3e41b50SHoria Geantă ctx->sh_desc_enc);
498d3e41b50SHoria Geantă if (ret) {
499d3e41b50SHoria Geantă dev_err(jrdev, "driver enc context update failed\n");
500d3e41b50SHoria Geantă return ret;
501d3e41b50SHoria Geantă }
502d3e41b50SHoria Geantă }
503d3e41b50SHoria Geantă
504d3e41b50SHoria Geantă if (ctx->drv_ctx[DECRYPT]) {
505d3e41b50SHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
506d3e41b50SHoria Geantă ctx->sh_desc_dec);
507d3e41b50SHoria Geantă if (ret) {
508d3e41b50SHoria Geantă dev_err(jrdev, "driver dec context update failed\n");
509d3e41b50SHoria Geantă return ret;
510d3e41b50SHoria Geantă }
511d3e41b50SHoria Geantă }
512d3e41b50SHoria Geantă
513d3e41b50SHoria Geantă return 0;
514d3e41b50SHoria Geantă }
515d3e41b50SHoria Geantă
rfc4543_set_sh_desc(struct crypto_aead * aead)516d3e41b50SHoria Geantă static int rfc4543_set_sh_desc(struct crypto_aead *aead)
517d3e41b50SHoria Geantă {
5184cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
519d3e41b50SHoria Geantă unsigned int ivsize = crypto_aead_ivsize(aead);
520d3e41b50SHoria Geantă int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
521d3e41b50SHoria Geantă ctx->cdata.keylen;
522d3e41b50SHoria Geantă
523d3e41b50SHoria Geantă if (!ctx->cdata.keylen || !ctx->authsize)
524d3e41b50SHoria Geantă return 0;
525d3e41b50SHoria Geantă
526d3e41b50SHoria Geantă ctx->cdata.key_virt = ctx->key;
527d3e41b50SHoria Geantă
528d3e41b50SHoria Geantă /*
529d3e41b50SHoria Geantă * Job Descriptor and Shared Descriptor
530d3e41b50SHoria Geantă * must fit into the 64-word Descriptor h/w Buffer
531d3e41b50SHoria Geantă */
532d3e41b50SHoria Geantă if (rem_bytes >= DESC_QI_RFC4543_ENC_LEN) {
533d3e41b50SHoria Geantă ctx->cdata.key_inline = true;
534d3e41b50SHoria Geantă } else {
535d3e41b50SHoria Geantă ctx->cdata.key_inline = false;
536d3e41b50SHoria Geantă ctx->cdata.key_dma = ctx->key_dma;
537d3e41b50SHoria Geantă }
538d3e41b50SHoria Geantă
539d3e41b50SHoria Geantă cnstr_shdsc_rfc4543_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
540d3e41b50SHoria Geantă ctx->authsize, true);
541d3e41b50SHoria Geantă
542d3e41b50SHoria Geantă /*
543d3e41b50SHoria Geantă * Job Descriptor and Shared Descriptor
544d3e41b50SHoria Geantă * must fit into the 64-word Descriptor h/w Buffer
545d3e41b50SHoria Geantă */
546d3e41b50SHoria Geantă if (rem_bytes >= DESC_QI_RFC4543_DEC_LEN) {
547d3e41b50SHoria Geantă ctx->cdata.key_inline = true;
548d3e41b50SHoria Geantă } else {
549d3e41b50SHoria Geantă ctx->cdata.key_inline = false;
550d3e41b50SHoria Geantă ctx->cdata.key_dma = ctx->key_dma;
551d3e41b50SHoria Geantă }
552d3e41b50SHoria Geantă
553d3e41b50SHoria Geantă cnstr_shdsc_rfc4543_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
554d3e41b50SHoria Geantă ctx->authsize, true);
555d3e41b50SHoria Geantă
556d3e41b50SHoria Geantă return 0;
557d3e41b50SHoria Geantă }
558d3e41b50SHoria Geantă
rfc4543_setauthsize(struct crypto_aead * authenc,unsigned int authsize)559d3e41b50SHoria Geantă static int rfc4543_setauthsize(struct crypto_aead *authenc,
560d3e41b50SHoria Geantă unsigned int authsize)
561d3e41b50SHoria Geantă {
5624cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
563d3e41b50SHoria Geantă
56468a51394SIuliana Prodan if (authsize != 16)
56568a51394SIuliana Prodan return -EINVAL;
56668a51394SIuliana Prodan
567d3e41b50SHoria Geantă ctx->authsize = authsize;
568d3e41b50SHoria Geantă rfc4543_set_sh_desc(authenc);
569d3e41b50SHoria Geantă
570d3e41b50SHoria Geantă return 0;
571d3e41b50SHoria Geantă }
572d3e41b50SHoria Geantă
rfc4543_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)573d3e41b50SHoria Geantă static int rfc4543_setkey(struct crypto_aead *aead,
574d3e41b50SHoria Geantă const u8 *key, unsigned int keylen)
575d3e41b50SHoria Geantă {
5764cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
577d3e41b50SHoria Geantă struct device *jrdev = ctx->jrdev;
578d3e41b50SHoria Geantă int ret;
579d3e41b50SHoria Geantă
580836d8f43SIuliana Prodan ret = aes_check_keylen(keylen - 4);
581674f368aSEric Biggers if (ret)
582836d8f43SIuliana Prodan return ret;
583d3e41b50SHoria Geantă
5846e005503SSascha Hauer print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
585d3e41b50SHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
586d3e41b50SHoria Geantă
587d3e41b50SHoria Geantă memcpy(ctx->key, key, keylen);
588d3e41b50SHoria Geantă /*
589d3e41b50SHoria Geantă * The last four bytes of the key material are used as the salt value
590d3e41b50SHoria Geantă * in the nonce. Update the AES key length.
591d3e41b50SHoria Geantă */
592d3e41b50SHoria Geantă ctx->cdata.keylen = keylen - 4;
593a7cd942bSHoria Geantă dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
594a7cd942bSHoria Geantă ctx->cdata.keylen, ctx->dir);
595d3e41b50SHoria Geantă
596d3e41b50SHoria Geantă ret = rfc4543_set_sh_desc(aead);
597d3e41b50SHoria Geantă if (ret)
598d3e41b50SHoria Geantă return ret;
599d3e41b50SHoria Geantă
600d3e41b50SHoria Geantă /* Now update the driver contexts with the new shared descriptor */
601d3e41b50SHoria Geantă if (ctx->drv_ctx[ENCRYPT]) {
602d3e41b50SHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
603d3e41b50SHoria Geantă ctx->sh_desc_enc);
604d3e41b50SHoria Geantă if (ret) {
605d3e41b50SHoria Geantă dev_err(jrdev, "driver enc context update failed\n");
606d3e41b50SHoria Geantă return ret;
607d3e41b50SHoria Geantă }
608d3e41b50SHoria Geantă }
609d3e41b50SHoria Geantă
610d3e41b50SHoria Geantă if (ctx->drv_ctx[DECRYPT]) {
611d3e41b50SHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
612d3e41b50SHoria Geantă ctx->sh_desc_dec);
613d3e41b50SHoria Geantă if (ret) {
614d3e41b50SHoria Geantă dev_err(jrdev, "driver dec context update failed\n");
615d3e41b50SHoria Geantă return ret;
616d3e41b50SHoria Geantă }
617d3e41b50SHoria Geantă }
618d3e41b50SHoria Geantă
619d3e41b50SHoria Geantă return 0;
620d3e41b50SHoria Geantă }
621d3e41b50SHoria Geantă
skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen,const u32 ctx1_iv_off)6229dbe3072SHoria Geantă static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
623836d8f43SIuliana Prodan unsigned int keylen, const u32 ctx1_iv_off)
624b189817cSHoria Geantă {
6254cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
6269dbe3072SHoria Geantă struct caam_skcipher_alg *alg =
6279dbe3072SHoria Geantă container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
6289dbe3072SHoria Geantă skcipher);
629b189817cSHoria Geantă struct device *jrdev = ctx->jrdev;
6309dbe3072SHoria Geantă unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
6319dbe3072SHoria Geantă const bool is_rfc3686 = alg->caam.rfc3686;
632b189817cSHoria Geantă int ret = 0;
633b189817cSHoria Geantă
6346e005503SSascha Hauer print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
635b189817cSHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6366e005503SSascha Hauer
637b189817cSHoria Geantă ctx->cdata.keylen = keylen;
638662f70edSHoria Geantă ctx->cdata.key_virt = key;
639b189817cSHoria Geantă ctx->cdata.key_inline = true;
640b189817cSHoria Geantă
6419dbe3072SHoria Geantă /* skcipher encrypt, decrypt shared descriptors */
6429dbe3072SHoria Geantă cnstr_shdsc_skcipher_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
643b189817cSHoria Geantă is_rfc3686, ctx1_iv_off);
6449dbe3072SHoria Geantă cnstr_shdsc_skcipher_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
645b189817cSHoria Geantă is_rfc3686, ctx1_iv_off);
646b189817cSHoria Geantă
647b189817cSHoria Geantă /* Now update the driver contexts with the new shared descriptor */
648b189817cSHoria Geantă if (ctx->drv_ctx[ENCRYPT]) {
649b189817cSHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
650b189817cSHoria Geantă ctx->sh_desc_enc);
651b189817cSHoria Geantă if (ret) {
652b189817cSHoria Geantă dev_err(jrdev, "driver enc context update failed\n");
653674f368aSEric Biggers return -EINVAL;
654b189817cSHoria Geantă }
655b189817cSHoria Geantă }
656b189817cSHoria Geantă
657b189817cSHoria Geantă if (ctx->drv_ctx[DECRYPT]) {
658b189817cSHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
659b189817cSHoria Geantă ctx->sh_desc_dec);
660b189817cSHoria Geantă if (ret) {
661b189817cSHoria Geantă dev_err(jrdev, "driver dec context update failed\n");
662674f368aSEric Biggers return -EINVAL;
663b189817cSHoria Geantă }
664b189817cSHoria Geantă }
665b189817cSHoria Geantă
666b189817cSHoria Geantă return ret;
667b189817cSHoria Geantă }
668b189817cSHoria Geantă
aes_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)669836d8f43SIuliana Prodan static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
670836d8f43SIuliana Prodan const u8 *key, unsigned int keylen)
671836d8f43SIuliana Prodan {
672836d8f43SIuliana Prodan int err;
673836d8f43SIuliana Prodan
674836d8f43SIuliana Prodan err = aes_check_keylen(keylen);
675674f368aSEric Biggers if (err)
676836d8f43SIuliana Prodan return err;
677836d8f43SIuliana Prodan
678836d8f43SIuliana Prodan return skcipher_setkey(skcipher, key, keylen, 0);
679836d8f43SIuliana Prodan }
680836d8f43SIuliana Prodan
rfc3686_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)681836d8f43SIuliana Prodan static int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher,
682836d8f43SIuliana Prodan const u8 *key, unsigned int keylen)
683836d8f43SIuliana Prodan {
684836d8f43SIuliana Prodan u32 ctx1_iv_off;
685836d8f43SIuliana Prodan int err;
686836d8f43SIuliana Prodan
687836d8f43SIuliana Prodan /*
688836d8f43SIuliana Prodan * RFC3686 specific:
689836d8f43SIuliana Prodan * | CONTEXT1[255:128] = {NONCE, IV, COUNTER}
690836d8f43SIuliana Prodan * | *key = {KEY, NONCE}
691836d8f43SIuliana Prodan */
692836d8f43SIuliana Prodan ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
693836d8f43SIuliana Prodan keylen -= CTR_RFC3686_NONCE_SIZE;
694836d8f43SIuliana Prodan
695836d8f43SIuliana Prodan err = aes_check_keylen(keylen);
696674f368aSEric Biggers if (err)
697836d8f43SIuliana Prodan return err;
698836d8f43SIuliana Prodan
699836d8f43SIuliana Prodan return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
700836d8f43SIuliana Prodan }
701836d8f43SIuliana Prodan
ctr_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)702836d8f43SIuliana Prodan static int ctr_skcipher_setkey(struct crypto_skcipher *skcipher,
703836d8f43SIuliana Prodan const u8 *key, unsigned int keylen)
704836d8f43SIuliana Prodan {
705836d8f43SIuliana Prodan u32 ctx1_iv_off;
706836d8f43SIuliana Prodan int err;
707836d8f43SIuliana Prodan
708836d8f43SIuliana Prodan /*
709836d8f43SIuliana Prodan * AES-CTR needs to load IV in CONTEXT1 reg
710836d8f43SIuliana Prodan * at an offset of 128bits (16bytes)
711836d8f43SIuliana Prodan * CONTEXT1[255:128] = IV
712836d8f43SIuliana Prodan */
713836d8f43SIuliana Prodan ctx1_iv_off = 16;
714836d8f43SIuliana Prodan
715836d8f43SIuliana Prodan err = aes_check_keylen(keylen);
716674f368aSEric Biggers if (err)
717836d8f43SIuliana Prodan return err;
718836d8f43SIuliana Prodan
719836d8f43SIuliana Prodan return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
720836d8f43SIuliana Prodan }
721836d8f43SIuliana Prodan
des3_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)7221b52c409SHerbert Xu static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
7231b52c409SHerbert Xu const u8 *key, unsigned int keylen)
7241b52c409SHerbert Xu {
725a628c5a1SArd Biesheuvel return verify_skcipher_des3_key(skcipher, key) ?:
726836d8f43SIuliana Prodan skcipher_setkey(skcipher, key, keylen, 0);
727836d8f43SIuliana Prodan }
728836d8f43SIuliana Prodan
des_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)729836d8f43SIuliana Prodan static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
730836d8f43SIuliana Prodan const u8 *key, unsigned int keylen)
731836d8f43SIuliana Prodan {
732a628c5a1SArd Biesheuvel return verify_skcipher_des_key(skcipher, key) ?:
733a628c5a1SArd Biesheuvel skcipher_setkey(skcipher, key, keylen, 0);
7341b52c409SHerbert Xu }
7351b52c409SHerbert Xu
xts_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)7369dbe3072SHoria Geantă static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
7379dbe3072SHoria Geantă unsigned int keylen)
738b189817cSHoria Geantă {
7394cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
740b189817cSHoria Geantă struct device *jrdev = ctx->jrdev;
7413a15679bSAndrei Botila struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
742b189817cSHoria Geantă int ret = 0;
74383e8aa91SAndrei Botila int err;
744b189817cSHoria Geantă
74562b9a669SAndrei Botila err = xts_verify_key(skcipher, key, keylen);
74662b9a669SAndrei Botila if (err) {
747da6a6685SHoria Geantă dev_dbg(jrdev, "key size mismatch\n");
74862b9a669SAndrei Botila return err;
749b189817cSHoria Geantă }
750b189817cSHoria Geantă
75162b9a669SAndrei Botila if (keylen != 2 * AES_KEYSIZE_128 && keylen != 2 * AES_KEYSIZE_256)
75262b9a669SAndrei Botila ctx->xts_key_fallback = true;
75362b9a669SAndrei Botila
7543a15679bSAndrei Botila if (ctrlpriv->era <= 8 || ctx->xts_key_fallback) {
75583e8aa91SAndrei Botila err = crypto_skcipher_setkey(ctx->fallback, key, keylen);
75683e8aa91SAndrei Botila if (err)
75783e8aa91SAndrei Botila return err;
7583a15679bSAndrei Botila }
75983e8aa91SAndrei Botila
760b189817cSHoria Geantă ctx->cdata.keylen = keylen;
761662f70edSHoria Geantă ctx->cdata.key_virt = key;
762b189817cSHoria Geantă ctx->cdata.key_inline = true;
763b189817cSHoria Geantă
7649dbe3072SHoria Geantă /* xts skcipher encrypt, decrypt shared descriptors */
7659dbe3072SHoria Geantă cnstr_shdsc_xts_skcipher_encap(ctx->sh_desc_enc, &ctx->cdata);
7669dbe3072SHoria Geantă cnstr_shdsc_xts_skcipher_decap(ctx->sh_desc_dec, &ctx->cdata);
767b189817cSHoria Geantă
768b189817cSHoria Geantă /* Now update the driver contexts with the new shared descriptor */
769b189817cSHoria Geantă if (ctx->drv_ctx[ENCRYPT]) {
770b189817cSHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
771b189817cSHoria Geantă ctx->sh_desc_enc);
772b189817cSHoria Geantă if (ret) {
773b189817cSHoria Geantă dev_err(jrdev, "driver enc context update failed\n");
774674f368aSEric Biggers return -EINVAL;
775b189817cSHoria Geantă }
776b189817cSHoria Geantă }
777b189817cSHoria Geantă
778b189817cSHoria Geantă if (ctx->drv_ctx[DECRYPT]) {
779b189817cSHoria Geantă ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
780b189817cSHoria Geantă ctx->sh_desc_dec);
781b189817cSHoria Geantă if (ret) {
782b189817cSHoria Geantă dev_err(jrdev, "driver dec context update failed\n");
783674f368aSEric Biggers return -EINVAL;
784b189817cSHoria Geantă }
785b189817cSHoria Geantă }
786b189817cSHoria Geantă
787b189817cSHoria Geantă return ret;
788b189817cSHoria Geantă }
789b189817cSHoria Geantă
790b189817cSHoria Geantă /*
791b189817cSHoria Geantă * aead_edesc - s/w-extended aead descriptor
792b189817cSHoria Geantă * @src_nents: number of segments in input scatterlist
793b189817cSHoria Geantă * @dst_nents: number of segments in output scatterlist
794b189817cSHoria Geantă * @iv_dma: dma address of iv for checking continuity and link table
795b189817cSHoria Geantă * @qm_sg_bytes: length of dma mapped h/w link table
796b189817cSHoria Geantă * @qm_sg_dma: bus physical mapped address of h/w link table
79736cda08fSHoria Geantă * @assoclen: associated data length, in CAAM endianness
798b189817cSHoria Geantă * @assoclen_dma: bus physical mapped address of req->assoclen
799b189817cSHoria Geantă * @drv_req: driver-specific request structure
8003a488aaeSHoria Geantă * @sgt: the h/w link table, followed by IV
801b189817cSHoria Geantă */
802b189817cSHoria Geantă struct aead_edesc {
803b189817cSHoria Geantă int src_nents;
804b189817cSHoria Geantă int dst_nents;
805b189817cSHoria Geantă dma_addr_t iv_dma;
806b189817cSHoria Geantă int qm_sg_bytes;
807b189817cSHoria Geantă dma_addr_t qm_sg_dma;
80836cda08fSHoria Geantă unsigned int assoclen;
809b189817cSHoria Geantă dma_addr_t assoclen_dma;
810b189817cSHoria Geantă struct caam_drv_req drv_req;
8115a8a0765SGustavo A. R. Silva struct qm_sg_entry sgt[];
812b189817cSHoria Geantă };
813b189817cSHoria Geantă
814b189817cSHoria Geantă /*
8159dbe3072SHoria Geantă * skcipher_edesc - s/w-extended skcipher descriptor
816b189817cSHoria Geantă * @src_nents: number of segments in input scatterlist
817b189817cSHoria Geantă * @dst_nents: number of segments in output scatterlist
818b189817cSHoria Geantă * @iv_dma: dma address of iv for checking continuity and link table
819b189817cSHoria Geantă * @qm_sg_bytes: length of dma mapped h/w link table
820b189817cSHoria Geantă * @qm_sg_dma: bus physical mapped address of h/w link table
821b189817cSHoria Geantă * @drv_req: driver-specific request structure
8223a488aaeSHoria Geantă * @sgt: the h/w link table, followed by IV
823b189817cSHoria Geantă */
8249dbe3072SHoria Geantă struct skcipher_edesc {
825b189817cSHoria Geantă int src_nents;
826b189817cSHoria Geantă int dst_nents;
827b189817cSHoria Geantă dma_addr_t iv_dma;
828b189817cSHoria Geantă int qm_sg_bytes;
829b189817cSHoria Geantă dma_addr_t qm_sg_dma;
830b189817cSHoria Geantă struct caam_drv_req drv_req;
8315a8a0765SGustavo A. R. Silva struct qm_sg_entry sgt[];
832b189817cSHoria Geantă };
833b189817cSHoria Geantă
get_drv_ctx(struct caam_ctx * ctx,enum optype type)834b189817cSHoria Geantă static struct caam_drv_ctx *get_drv_ctx(struct caam_ctx *ctx,
835b189817cSHoria Geantă enum optype type)
836b189817cSHoria Geantă {
837b189817cSHoria Geantă /*
838b189817cSHoria Geantă * This function is called on the fast path with values of 'type'
839b189817cSHoria Geantă * known at compile time. Invalid arguments are not expected and
840b189817cSHoria Geantă * thus no checks are made.
841b189817cSHoria Geantă */
842b189817cSHoria Geantă struct caam_drv_ctx *drv_ctx = ctx->drv_ctx[type];
843b189817cSHoria Geantă u32 *desc;
844b189817cSHoria Geantă
845b189817cSHoria Geantă if (unlikely(!drv_ctx)) {
846b189817cSHoria Geantă spin_lock(&ctx->lock);
847b189817cSHoria Geantă
848b189817cSHoria Geantă /* Read again to check if some other core init drv_ctx */
849b189817cSHoria Geantă drv_ctx = ctx->drv_ctx[type];
850b189817cSHoria Geantă if (!drv_ctx) {
851b189817cSHoria Geantă int cpu;
852b189817cSHoria Geantă
853b189817cSHoria Geantă if (type == ENCRYPT)
854b189817cSHoria Geantă desc = ctx->sh_desc_enc;
855aec48adcSHoria Geantă else /* (type == DECRYPT) */
856b189817cSHoria Geantă desc = ctx->sh_desc_dec;
857b189817cSHoria Geantă
858b189817cSHoria Geantă cpu = smp_processor_id();
859b189817cSHoria Geantă drv_ctx = caam_drv_ctx_init(ctx->qidev, &cpu, desc);
8600049a132SHoria Geantă if (!IS_ERR(drv_ctx))
861b189817cSHoria Geantă drv_ctx->op_type = type;
862b189817cSHoria Geantă
863b189817cSHoria Geantă ctx->drv_ctx[type] = drv_ctx;
864b189817cSHoria Geantă }
865b189817cSHoria Geantă
866b189817cSHoria Geantă spin_unlock(&ctx->lock);
867b189817cSHoria Geantă }
868b189817cSHoria Geantă
869b189817cSHoria Geantă return drv_ctx;
870b189817cSHoria Geantă }
871b189817cSHoria Geantă
caam_unmap(struct device * dev,struct scatterlist * src,struct scatterlist * dst,int src_nents,int dst_nents,dma_addr_t iv_dma,int ivsize,enum dma_data_direction iv_dir,dma_addr_t qm_sg_dma,int qm_sg_bytes)872b189817cSHoria Geantă static void caam_unmap(struct device *dev, struct scatterlist *src,
873b189817cSHoria Geantă struct scatterlist *dst, int src_nents,
874b189817cSHoria Geantă int dst_nents, dma_addr_t iv_dma, int ivsize,
875334d37c9SHoria Geantă enum dma_data_direction iv_dir, dma_addr_t qm_sg_dma,
876334d37c9SHoria Geantă int qm_sg_bytes)
877b189817cSHoria Geantă {
878b189817cSHoria Geantă if (dst != src) {
879b189817cSHoria Geantă if (src_nents)
880b189817cSHoria Geantă dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
881763069baSHoria Geantă if (dst_nents)
882b189817cSHoria Geantă dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
883b189817cSHoria Geantă } else {
884b189817cSHoria Geantă dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
885b189817cSHoria Geantă }
886b189817cSHoria Geantă
887b189817cSHoria Geantă if (iv_dma)
888334d37c9SHoria Geantă dma_unmap_single(dev, iv_dma, ivsize, iv_dir);
889b189817cSHoria Geantă if (qm_sg_bytes)
890b189817cSHoria Geantă dma_unmap_single(dev, qm_sg_dma, qm_sg_bytes, DMA_TO_DEVICE);
891b189817cSHoria Geantă }
892b189817cSHoria Geantă
aead_unmap(struct device * dev,struct aead_edesc * edesc,struct aead_request * req)893b189817cSHoria Geantă static void aead_unmap(struct device *dev,
894b189817cSHoria Geantă struct aead_edesc *edesc,
895b189817cSHoria Geantă struct aead_request *req)
896b189817cSHoria Geantă {
897b189817cSHoria Geantă struct crypto_aead *aead = crypto_aead_reqtfm(req);
898b189817cSHoria Geantă int ivsize = crypto_aead_ivsize(aead);
899b189817cSHoria Geantă
900b189817cSHoria Geantă caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents,
901334d37c9SHoria Geantă edesc->iv_dma, ivsize, DMA_TO_DEVICE, edesc->qm_sg_dma,
902334d37c9SHoria Geantă edesc->qm_sg_bytes);
903b189817cSHoria Geantă dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
904b189817cSHoria Geantă }
905b189817cSHoria Geantă
skcipher_unmap(struct device * dev,struct skcipher_edesc * edesc,struct skcipher_request * req)9069dbe3072SHoria Geantă static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
9079dbe3072SHoria Geantă struct skcipher_request *req)
908b189817cSHoria Geantă {
9099dbe3072SHoria Geantă struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
9109dbe3072SHoria Geantă int ivsize = crypto_skcipher_ivsize(skcipher);
911b189817cSHoria Geantă
912b189817cSHoria Geantă caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents,
913334d37c9SHoria Geantă edesc->iv_dma, ivsize, DMA_BIDIRECTIONAL, edesc->qm_sg_dma,
914334d37c9SHoria Geantă edesc->qm_sg_bytes);
915b189817cSHoria Geantă }
916b189817cSHoria Geantă
aead_done(struct caam_drv_req * drv_req,u32 status)917b189817cSHoria Geantă static void aead_done(struct caam_drv_req *drv_req, u32 status)
918b189817cSHoria Geantă {
919b189817cSHoria Geantă struct device *qidev;
920b189817cSHoria Geantă struct aead_edesc *edesc;
921b189817cSHoria Geantă struct aead_request *aead_req = drv_req->app_ctx;
922b189817cSHoria Geantă struct crypto_aead *aead = crypto_aead_reqtfm(aead_req);
9234cb4f7c1SHerbert Xu struct caam_ctx *caam_ctx = crypto_aead_ctx_dma(aead);
924b189817cSHoria Geantă int ecode = 0;
925b189817cSHoria Geantă
926b189817cSHoria Geantă qidev = caam_ctx->qidev;
927b189817cSHoria Geantă
9281984aaeeSHoria Geantă if (unlikely(status))
9291984aaeeSHoria Geantă ecode = caam_jr_strstatus(qidev, status);
930b189817cSHoria Geantă
931b189817cSHoria Geantă edesc = container_of(drv_req, typeof(*edesc), drv_req);
932b189817cSHoria Geantă aead_unmap(qidev, edesc, aead_req);
933b189817cSHoria Geantă
934b189817cSHoria Geantă aead_request_complete(aead_req, ecode);
935b189817cSHoria Geantă qi_cache_free(edesc);
936b189817cSHoria Geantă }
937b189817cSHoria Geantă
938b189817cSHoria Geantă /*
939b189817cSHoria Geantă * allocate and map the aead extended descriptor
940b189817cSHoria Geantă */
aead_edesc_alloc(struct aead_request * req,bool encrypt)941b189817cSHoria Geantă static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
942b189817cSHoria Geantă bool encrypt)
943b189817cSHoria Geantă {
944b189817cSHoria Geantă struct crypto_aead *aead = crypto_aead_reqtfm(req);
9454cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
946b189817cSHoria Geantă struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
947b189817cSHoria Geantă typeof(*alg), aead);
948b189817cSHoria Geantă struct device *qidev = ctx->qidev;
949019d62dbSHoria Geantă gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
950019d62dbSHoria Geantă GFP_KERNEL : GFP_ATOMIC;
951b189817cSHoria Geantă int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
952059d73eeSHoria Geantă int src_len, dst_len = 0;
953b189817cSHoria Geantă struct aead_edesc *edesc;
954b189817cSHoria Geantă dma_addr_t qm_sg_dma, iv_dma = 0;
955b189817cSHoria Geantă int ivsize = 0;
956b189817cSHoria Geantă unsigned int authsize = ctx->authsize;
957b189817cSHoria Geantă int qm_sg_index = 0, qm_sg_ents = 0, qm_sg_bytes;
958b189817cSHoria Geantă int in_len, out_len;
959b189817cSHoria Geantă struct qm_sg_entry *sg_table, *fd_sgt;
960b189817cSHoria Geantă struct caam_drv_ctx *drv_ctx;
961b189817cSHoria Geantă
962aec48adcSHoria Geantă drv_ctx = get_drv_ctx(ctx, encrypt ? ENCRYPT : DECRYPT);
9630049a132SHoria Geantă if (IS_ERR(drv_ctx))
964b189817cSHoria Geantă return (struct aead_edesc *)drv_ctx;
965b189817cSHoria Geantă
966b189817cSHoria Geantă /* allocate space for base edesc and hw desc commands, link tables */
967199354d7SHerbert Xu edesc = qi_cache_alloc(flags);
968b189817cSHoria Geantă if (unlikely(!edesc)) {
969b189817cSHoria Geantă dev_err(qidev, "could not allocate extended descriptor\n");
970b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
971b189817cSHoria Geantă }
972b189817cSHoria Geantă
973b189817cSHoria Geantă if (likely(req->src == req->dst)) {
974059d73eeSHoria Geantă src_len = req->assoclen + req->cryptlen +
975059d73eeSHoria Geantă (encrypt ? authsize : 0);
976059d73eeSHoria Geantă
977059d73eeSHoria Geantă src_nents = sg_nents_for_len(req->src, src_len);
978b189817cSHoria Geantă if (unlikely(src_nents < 0)) {
979b189817cSHoria Geantă dev_err(qidev, "Insufficient bytes (%d) in src S/G\n",
980059d73eeSHoria Geantă src_len);
981b189817cSHoria Geantă qi_cache_free(edesc);
982b189817cSHoria Geantă return ERR_PTR(src_nents);
983b189817cSHoria Geantă }
984b189817cSHoria Geantă
985b189817cSHoria Geantă mapped_src_nents = dma_map_sg(qidev, req->src, src_nents,
986b189817cSHoria Geantă DMA_BIDIRECTIONAL);
987b189817cSHoria Geantă if (unlikely(!mapped_src_nents)) {
988b189817cSHoria Geantă dev_err(qidev, "unable to map source\n");
989b189817cSHoria Geantă qi_cache_free(edesc);
990b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
991b189817cSHoria Geantă }
992b189817cSHoria Geantă } else {
993059d73eeSHoria Geantă src_len = req->assoclen + req->cryptlen;
994059d73eeSHoria Geantă dst_len = src_len + (encrypt ? authsize : (-authsize));
995059d73eeSHoria Geantă
996059d73eeSHoria Geantă src_nents = sg_nents_for_len(req->src, src_len);
997b189817cSHoria Geantă if (unlikely(src_nents < 0)) {
998b189817cSHoria Geantă dev_err(qidev, "Insufficient bytes (%d) in src S/G\n",
999059d73eeSHoria Geantă src_len);
1000b189817cSHoria Geantă qi_cache_free(edesc);
1001b189817cSHoria Geantă return ERR_PTR(src_nents);
1002b189817cSHoria Geantă }
1003b189817cSHoria Geantă
1004059d73eeSHoria Geantă dst_nents = sg_nents_for_len(req->dst, dst_len);
1005b189817cSHoria Geantă if (unlikely(dst_nents < 0)) {
1006b189817cSHoria Geantă dev_err(qidev, "Insufficient bytes (%d) in dst S/G\n",
1007059d73eeSHoria Geantă dst_len);
1008b189817cSHoria Geantă qi_cache_free(edesc);
1009b189817cSHoria Geantă return ERR_PTR(dst_nents);
1010b189817cSHoria Geantă }
1011b189817cSHoria Geantă
1012b189817cSHoria Geantă if (src_nents) {
1013b189817cSHoria Geantă mapped_src_nents = dma_map_sg(qidev, req->src,
1014b189817cSHoria Geantă src_nents, DMA_TO_DEVICE);
1015b189817cSHoria Geantă if (unlikely(!mapped_src_nents)) {
1016b189817cSHoria Geantă dev_err(qidev, "unable to map source\n");
1017b189817cSHoria Geantă qi_cache_free(edesc);
1018b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1019b189817cSHoria Geantă }
1020b189817cSHoria Geantă } else {
1021b189817cSHoria Geantă mapped_src_nents = 0;
1022b189817cSHoria Geantă }
1023b189817cSHoria Geantă
1024763069baSHoria Geantă if (dst_nents) {
1025763069baSHoria Geantă mapped_dst_nents = dma_map_sg(qidev, req->dst,
1026763069baSHoria Geantă dst_nents,
1027b189817cSHoria Geantă DMA_FROM_DEVICE);
1028b189817cSHoria Geantă if (unlikely(!mapped_dst_nents)) {
1029b189817cSHoria Geantă dev_err(qidev, "unable to map destination\n");
1030763069baSHoria Geantă dma_unmap_sg(qidev, req->src, src_nents,
1031763069baSHoria Geantă DMA_TO_DEVICE);
1032b189817cSHoria Geantă qi_cache_free(edesc);
1033b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1034b189817cSHoria Geantă }
1035763069baSHoria Geantă } else {
1036763069baSHoria Geantă mapped_dst_nents = 0;
1037763069baSHoria Geantă }
1038b189817cSHoria Geantă }
1039b189817cSHoria Geantă
10403a488aaeSHoria Geantă if ((alg->caam.rfc3686 && encrypt) || !alg->caam.geniv)
1041b189817cSHoria Geantă ivsize = crypto_aead_ivsize(aead);
1042b189817cSHoria Geantă
1043b189817cSHoria Geantă /*
1044b189817cSHoria Geantă * Create S/G table: req->assoclen, [IV,] req->src [, req->dst].
1045b189817cSHoria Geantă * Input is not contiguous.
1046a5e5c133SHoria Geantă * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1047a5e5c133SHoria Geantă * the end of the table by allocating more S/G entries. Logic:
1048a5e5c133SHoria Geantă * if (src != dst && output S/G)
1049a5e5c133SHoria Geantă * pad output S/G, if needed
1050a5e5c133SHoria Geantă * else if (src == dst && S/G)
1051a5e5c133SHoria Geantă * overlapping S/Gs; pad one of them
1052a5e5c133SHoria Geantă * else if (input S/G) ...
1053a5e5c133SHoria Geantă * pad input S/G, if needed
1054b189817cSHoria Geantă */
1055a5e5c133SHoria Geantă qm_sg_ents = 1 + !!ivsize + mapped_src_nents;
1056a5e5c133SHoria Geantă if (mapped_dst_nents > 1)
1057a5e5c133SHoria Geantă qm_sg_ents += pad_sg_nents(mapped_dst_nents);
1058a5e5c133SHoria Geantă else if ((req->src == req->dst) && (mapped_src_nents > 1))
1059a5e5c133SHoria Geantă qm_sg_ents = max(pad_sg_nents(qm_sg_ents),
1060a5e5c133SHoria Geantă 1 + !!ivsize + pad_sg_nents(mapped_src_nents));
1061a5e5c133SHoria Geantă else
1062a5e5c133SHoria Geantă qm_sg_ents = pad_sg_nents(qm_sg_ents);
1063a5e5c133SHoria Geantă
10643a488aaeSHoria Geantă sg_table = &edesc->sgt[0];
10653a488aaeSHoria Geantă qm_sg_bytes = qm_sg_ents * sizeof(*sg_table);
10663a488aaeSHoria Geantă if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize >
10673a488aaeSHoria Geantă CAAM_QI_MEMCACHE_SIZE)) {
10683a488aaeSHoria Geantă dev_err(qidev, "No space for %d S/G entries and/or %dB IV\n",
10693a488aaeSHoria Geantă qm_sg_ents, ivsize);
10703a488aaeSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0,
1071334d37c9SHoria Geantă 0, DMA_NONE, 0, 0);
1072eb9ba37dSHoria Geantă qi_cache_free(edesc);
1073eb9ba37dSHoria Geantă return ERR_PTR(-ENOMEM);
1074eb9ba37dSHoria Geantă }
10753a488aaeSHoria Geantă
10763a488aaeSHoria Geantă if (ivsize) {
10773a488aaeSHoria Geantă u8 *iv = (u8 *)(sg_table + qm_sg_ents);
10783a488aaeSHoria Geantă
10793a488aaeSHoria Geantă /* Make sure IV is located in a DMAable area */
10803a488aaeSHoria Geantă memcpy(iv, req->iv, ivsize);
10813a488aaeSHoria Geantă
10823a488aaeSHoria Geantă iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE);
10833a488aaeSHoria Geantă if (dma_mapping_error(qidev, iv_dma)) {
10843a488aaeSHoria Geantă dev_err(qidev, "unable to map IV\n");
10853a488aaeSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents,
1086334d37c9SHoria Geantă dst_nents, 0, 0, DMA_NONE, 0, 0);
10873a488aaeSHoria Geantă qi_cache_free(edesc);
10883a488aaeSHoria Geantă return ERR_PTR(-ENOMEM);
10893a488aaeSHoria Geantă }
10903a488aaeSHoria Geantă }
1091b189817cSHoria Geantă
1092b189817cSHoria Geantă edesc->src_nents = src_nents;
1093b189817cSHoria Geantă edesc->dst_nents = dst_nents;
1094b189817cSHoria Geantă edesc->iv_dma = iv_dma;
1095b189817cSHoria Geantă edesc->drv_req.app_ctx = req;
1096b189817cSHoria Geantă edesc->drv_req.cbk = aead_done;
1097b189817cSHoria Geantă edesc->drv_req.drv_ctx = drv_ctx;
1098b189817cSHoria Geantă
109936cda08fSHoria Geantă edesc->assoclen = cpu_to_caam32(req->assoclen);
110036cda08fSHoria Geantă edesc->assoclen_dma = dma_map_single(qidev, &edesc->assoclen, 4,
1101b189817cSHoria Geantă DMA_TO_DEVICE);
1102b189817cSHoria Geantă if (dma_mapping_error(qidev, edesc->assoclen_dma)) {
1103b189817cSHoria Geantă dev_err(qidev, "unable to map assoclen\n");
1104b189817cSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents,
1105334d37c9SHoria Geantă iv_dma, ivsize, DMA_TO_DEVICE, 0, 0);
1106b189817cSHoria Geantă qi_cache_free(edesc);
1107b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1108b189817cSHoria Geantă }
1109b189817cSHoria Geantă
1110b189817cSHoria Geantă dma_to_qm_sg_one(sg_table, edesc->assoclen_dma, 4, 0);
1111b189817cSHoria Geantă qm_sg_index++;
1112b189817cSHoria Geantă if (ivsize) {
1113b189817cSHoria Geantă dma_to_qm_sg_one(sg_table + qm_sg_index, iv_dma, ivsize, 0);
1114b189817cSHoria Geantă qm_sg_index++;
1115b189817cSHoria Geantă }
1116059d73eeSHoria Geantă sg_to_qm_sg_last(req->src, src_len, sg_table + qm_sg_index, 0);
1117b189817cSHoria Geantă qm_sg_index += mapped_src_nents;
1118b189817cSHoria Geantă
1119b189817cSHoria Geantă if (mapped_dst_nents > 1)
1120059d73eeSHoria Geantă sg_to_qm_sg_last(req->dst, dst_len, sg_table + qm_sg_index, 0);
1121b189817cSHoria Geantă
1122b189817cSHoria Geantă qm_sg_dma = dma_map_single(qidev, sg_table, qm_sg_bytes, DMA_TO_DEVICE);
1123b189817cSHoria Geantă if (dma_mapping_error(qidev, qm_sg_dma)) {
1124b189817cSHoria Geantă dev_err(qidev, "unable to map S/G table\n");
1125b189817cSHoria Geantă dma_unmap_single(qidev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
1126b189817cSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents,
1127334d37c9SHoria Geantă iv_dma, ivsize, DMA_TO_DEVICE, 0, 0);
1128b189817cSHoria Geantă qi_cache_free(edesc);
1129b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1130b189817cSHoria Geantă }
1131b189817cSHoria Geantă
1132b189817cSHoria Geantă edesc->qm_sg_dma = qm_sg_dma;
1133b189817cSHoria Geantă edesc->qm_sg_bytes = qm_sg_bytes;
1134b189817cSHoria Geantă
1135b189817cSHoria Geantă out_len = req->assoclen + req->cryptlen +
1136b189817cSHoria Geantă (encrypt ? ctx->authsize : (-ctx->authsize));
1137b189817cSHoria Geantă in_len = 4 + ivsize + req->assoclen + req->cryptlen;
1138b189817cSHoria Geantă
1139b189817cSHoria Geantă fd_sgt = &edesc->drv_req.fd_sgt[0];
1140b189817cSHoria Geantă dma_to_qm_sg_one_last_ext(&fd_sgt[1], qm_sg_dma, in_len, 0);
1141b189817cSHoria Geantă
1142b189817cSHoria Geantă if (req->dst == req->src) {
1143b189817cSHoria Geantă if (mapped_src_nents == 1)
1144b189817cSHoria Geantă dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(req->src),
1145b189817cSHoria Geantă out_len, 0);
1146b189817cSHoria Geantă else
1147b189817cSHoria Geantă dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma +
1148b189817cSHoria Geantă (1 + !!ivsize) * sizeof(*sg_table),
1149b189817cSHoria Geantă out_len, 0);
1150dcd9c76eSHoria Geantă } else if (mapped_dst_nents <= 1) {
1151b189817cSHoria Geantă dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(req->dst), out_len,
1152b189817cSHoria Geantă 0);
1153b189817cSHoria Geantă } else {
1154b189817cSHoria Geantă dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + sizeof(*sg_table) *
1155b189817cSHoria Geantă qm_sg_index, out_len, 0);
1156b189817cSHoria Geantă }
1157b189817cSHoria Geantă
1158b189817cSHoria Geantă return edesc;
1159b189817cSHoria Geantă }
1160b189817cSHoria Geantă
aead_crypt(struct aead_request * req,bool encrypt)1161b189817cSHoria Geantă static inline int aead_crypt(struct aead_request *req, bool encrypt)
1162b189817cSHoria Geantă {
1163b189817cSHoria Geantă struct aead_edesc *edesc;
1164b189817cSHoria Geantă struct crypto_aead *aead = crypto_aead_reqtfm(req);
11654cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
1166b189817cSHoria Geantă int ret;
1167b189817cSHoria Geantă
1168b189817cSHoria Geantă if (unlikely(caam_congested))
1169b189817cSHoria Geantă return -EAGAIN;
1170b189817cSHoria Geantă
1171b189817cSHoria Geantă /* allocate extended descriptor */
1172b189817cSHoria Geantă edesc = aead_edesc_alloc(req, encrypt);
11730049a132SHoria Geantă if (IS_ERR(edesc))
1174b189817cSHoria Geantă return PTR_ERR(edesc);
1175b189817cSHoria Geantă
1176b189817cSHoria Geantă /* Create and submit job descriptor */
1177b189817cSHoria Geantă ret = caam_qi_enqueue(ctx->qidev, &edesc->drv_req);
1178b189817cSHoria Geantă if (!ret) {
1179b189817cSHoria Geantă ret = -EINPROGRESS;
1180b189817cSHoria Geantă } else {
1181b189817cSHoria Geantă aead_unmap(ctx->qidev, edesc, req);
1182b189817cSHoria Geantă qi_cache_free(edesc);
1183b189817cSHoria Geantă }
1184b189817cSHoria Geantă
1185b189817cSHoria Geantă return ret;
1186b189817cSHoria Geantă }
1187b189817cSHoria Geantă
aead_encrypt(struct aead_request * req)1188b189817cSHoria Geantă static int aead_encrypt(struct aead_request *req)
1189b189817cSHoria Geantă {
1190b189817cSHoria Geantă return aead_crypt(req, true);
1191b189817cSHoria Geantă }
1192b189817cSHoria Geantă
aead_decrypt(struct aead_request * req)1193b189817cSHoria Geantă static int aead_decrypt(struct aead_request *req)
1194b189817cSHoria Geantă {
1195b189817cSHoria Geantă return aead_crypt(req, false);
1196b189817cSHoria Geantă }
1197b189817cSHoria Geantă
ipsec_gcm_encrypt(struct aead_request * req)1198d3e41b50SHoria Geantă static int ipsec_gcm_encrypt(struct aead_request *req)
1199d3e41b50SHoria Geantă {
1200fcd23ed5SIuliana Prodan return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_crypt(req,
1201fcd23ed5SIuliana Prodan true);
1202d3e41b50SHoria Geantă }
1203d3e41b50SHoria Geantă
ipsec_gcm_decrypt(struct aead_request * req)1204d3e41b50SHoria Geantă static int ipsec_gcm_decrypt(struct aead_request *req)
1205d3e41b50SHoria Geantă {
1206fcd23ed5SIuliana Prodan return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_crypt(req,
1207fcd23ed5SIuliana Prodan false);
1208d3e41b50SHoria Geantă }
1209d3e41b50SHoria Geantă
skcipher_edesc_iv(struct skcipher_edesc * edesc)1210*660ca947SHerbert Xu static inline u8 *skcipher_edesc_iv(struct skcipher_edesc *edesc)
1211*660ca947SHerbert Xu {
1212*660ca947SHerbert Xu return PTR_ALIGN((u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes,
1213*660ca947SHerbert Xu dma_get_cache_alignment());
1214*660ca947SHerbert Xu }
1215*660ca947SHerbert Xu
skcipher_done(struct caam_drv_req * drv_req,u32 status)12169dbe3072SHoria Geantă static void skcipher_done(struct caam_drv_req *drv_req, u32 status)
1217b189817cSHoria Geantă {
12189dbe3072SHoria Geantă struct skcipher_edesc *edesc;
12199dbe3072SHoria Geantă struct skcipher_request *req = drv_req->app_ctx;
12209dbe3072SHoria Geantă struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
12214cb4f7c1SHerbert Xu struct caam_ctx *caam_ctx = crypto_skcipher_ctx_dma(skcipher);
1222b189817cSHoria Geantă struct device *qidev = caam_ctx->qidev;
12239dbe3072SHoria Geantă int ivsize = crypto_skcipher_ivsize(skcipher);
12241984aaeeSHoria Geantă int ecode = 0;
1225b189817cSHoria Geantă
12266e005503SSascha Hauer dev_dbg(qidev, "%s %d: status 0x%x\n", __func__, __LINE__, status);
1227b189817cSHoria Geantă
1228b189817cSHoria Geantă edesc = container_of(drv_req, typeof(*edesc), drv_req);
1229b189817cSHoria Geantă
1230b189817cSHoria Geantă if (status)
12311984aaeeSHoria Geantă ecode = caam_jr_strstatus(qidev, status);
1232b189817cSHoria Geantă
12336e005503SSascha Hauer print_hex_dump_debug("dstiv @" __stringify(__LINE__)": ",
12349dbe3072SHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
1235b189817cSHoria Geantă edesc->src_nents > 1 ? 100 : ivsize, 1);
12368a82451bSSascha Hauer caam_dump_sg("dst @" __stringify(__LINE__)": ",
1237b189817cSHoria Geantă DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
12389dbe3072SHoria Geantă edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
1239b189817cSHoria Geantă
12409dbe3072SHoria Geantă skcipher_unmap(qidev, edesc, req);
12413a488aaeSHoria Geantă
1242a68a1938SHoria Geantă /*
12439dbe3072SHoria Geantă * The crypto API expects us to set the IV (req->iv) to the last
1244334d37c9SHoria Geantă * ciphertext block (CBC mode) or last counter (CTR mode).
1245334d37c9SHoria Geantă * This is used e.g. by the CTS mode.
1246a68a1938SHoria Geantă */
12471ccb39ebSHoria Geantă if (!ecode)
1248*660ca947SHerbert Xu memcpy(req->iv, skcipher_edesc_iv(edesc), ivsize);
1249a68a1938SHoria Geantă
12503a488aaeSHoria Geantă qi_cache_free(edesc);
12511984aaeeSHoria Geantă skcipher_request_complete(req, ecode);
1252b189817cSHoria Geantă }
1253b189817cSHoria Geantă
skcipher_edesc_alloc(struct skcipher_request * req,bool encrypt)12549dbe3072SHoria Geantă static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
12559dbe3072SHoria Geantă bool encrypt)
1256b189817cSHoria Geantă {
12579dbe3072SHoria Geantă struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
12584cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
1259b189817cSHoria Geantă struct device *qidev = ctx->qidev;
1260019d62dbSHoria Geantă gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1261b189817cSHoria Geantă GFP_KERNEL : GFP_ATOMIC;
1262b189817cSHoria Geantă int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
12639dbe3072SHoria Geantă struct skcipher_edesc *edesc;
1264b189817cSHoria Geantă dma_addr_t iv_dma;
12653a488aaeSHoria Geantă u8 *iv;
12669dbe3072SHoria Geantă int ivsize = crypto_skcipher_ivsize(skcipher);
12673a488aaeSHoria Geantă int dst_sg_idx, qm_sg_ents, qm_sg_bytes;
1268b189817cSHoria Geantă struct qm_sg_entry *sg_table, *fd_sgt;
1269b189817cSHoria Geantă struct caam_drv_ctx *drv_ctx;
1270*660ca947SHerbert Xu unsigned int len;
1271b189817cSHoria Geantă
1272aec48adcSHoria Geantă drv_ctx = get_drv_ctx(ctx, encrypt ? ENCRYPT : DECRYPT);
12730049a132SHoria Geantă if (IS_ERR(drv_ctx))
12749dbe3072SHoria Geantă return (struct skcipher_edesc *)drv_ctx;
1275b189817cSHoria Geantă
12769dbe3072SHoria Geantă src_nents = sg_nents_for_len(req->src, req->cryptlen);
1277b189817cSHoria Geantă if (unlikely(src_nents < 0)) {
1278b189817cSHoria Geantă dev_err(qidev, "Insufficient bytes (%d) in src S/G\n",
12799dbe3072SHoria Geantă req->cryptlen);
1280b189817cSHoria Geantă return ERR_PTR(src_nents);
1281b189817cSHoria Geantă }
1282b189817cSHoria Geantă
1283b189817cSHoria Geantă if (unlikely(req->src != req->dst)) {
12849dbe3072SHoria Geantă dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
1285b189817cSHoria Geantă if (unlikely(dst_nents < 0)) {
1286b189817cSHoria Geantă dev_err(qidev, "Insufficient bytes (%d) in dst S/G\n",
12879dbe3072SHoria Geantă req->cryptlen);
1288b189817cSHoria Geantă return ERR_PTR(dst_nents);
1289b189817cSHoria Geantă }
1290b189817cSHoria Geantă
1291b189817cSHoria Geantă mapped_src_nents = dma_map_sg(qidev, req->src, src_nents,
1292b189817cSHoria Geantă DMA_TO_DEVICE);
1293b189817cSHoria Geantă if (unlikely(!mapped_src_nents)) {
1294b189817cSHoria Geantă dev_err(qidev, "unable to map source\n");
1295b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1296b189817cSHoria Geantă }
1297b189817cSHoria Geantă
1298b189817cSHoria Geantă mapped_dst_nents = dma_map_sg(qidev, req->dst, dst_nents,
1299b189817cSHoria Geantă DMA_FROM_DEVICE);
1300b189817cSHoria Geantă if (unlikely(!mapped_dst_nents)) {
1301b189817cSHoria Geantă dev_err(qidev, "unable to map destination\n");
1302b189817cSHoria Geantă dma_unmap_sg(qidev, req->src, src_nents, DMA_TO_DEVICE);
1303b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1304b189817cSHoria Geantă }
1305b189817cSHoria Geantă } else {
1306b189817cSHoria Geantă mapped_src_nents = dma_map_sg(qidev, req->src, src_nents,
1307b189817cSHoria Geantă DMA_BIDIRECTIONAL);
1308b189817cSHoria Geantă if (unlikely(!mapped_src_nents)) {
1309b189817cSHoria Geantă dev_err(qidev, "unable to map source\n");
1310b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1311b189817cSHoria Geantă }
1312b189817cSHoria Geantă }
1313b189817cSHoria Geantă
13143a488aaeSHoria Geantă qm_sg_ents = 1 + mapped_src_nents;
13153a488aaeSHoria Geantă dst_sg_idx = qm_sg_ents;
13163a488aaeSHoria Geantă
1317a5e5c133SHoria Geantă /*
1318334d37c9SHoria Geantă * Input, output HW S/G tables: [IV, src][dst, IV]
1319334d37c9SHoria Geantă * IV entries point to the same buffer
1320334d37c9SHoria Geantă * If src == dst, S/G entries are reused (S/G tables overlap)
1321334d37c9SHoria Geantă *
1322a5e5c133SHoria Geantă * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1323334d37c9SHoria Geantă * the end of the table by allocating more S/G entries.
1324a5e5c133SHoria Geantă */
1325334d37c9SHoria Geantă if (req->src != req->dst)
1326334d37c9SHoria Geantă qm_sg_ents += pad_sg_nents(mapped_dst_nents + 1);
1327a5e5c133SHoria Geantă else
1328334d37c9SHoria Geantă qm_sg_ents = 1 + pad_sg_nents(qm_sg_ents);
1329a5e5c133SHoria Geantă
13303a488aaeSHoria Geantă qm_sg_bytes = qm_sg_ents * sizeof(struct qm_sg_entry);
1331*660ca947SHerbert Xu
1332*660ca947SHerbert Xu len = offsetof(struct skcipher_edesc, sgt) + qm_sg_bytes;
1333*660ca947SHerbert Xu len = ALIGN(len, dma_get_cache_alignment());
1334*660ca947SHerbert Xu len += ivsize;
1335*660ca947SHerbert Xu
1336*660ca947SHerbert Xu if (unlikely(len > CAAM_QI_MEMCACHE_SIZE)) {
13373a488aaeSHoria Geantă dev_err(qidev, "No space for %d S/G entries and/or %dB IV\n",
13383a488aaeSHoria Geantă qm_sg_ents, ivsize);
1339b189817cSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0,
1340334d37c9SHoria Geantă 0, DMA_NONE, 0, 0);
1341b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1342b189817cSHoria Geantă }
1343b189817cSHoria Geantă
13443a488aaeSHoria Geantă /* allocate space for base edesc, link tables and IV */
1345*660ca947SHerbert Xu edesc = qi_cache_alloc(flags);
1346*660ca947SHerbert Xu if (unlikely(!edesc)) {
1347b189817cSHoria Geantă dev_err(qidev, "could not allocate extended descriptor\n");
13483a488aaeSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0,
1349334d37c9SHoria Geantă 0, DMA_NONE, 0, 0);
13503a488aaeSHoria Geantă return ERR_PTR(-ENOMEM);
13513a488aaeSHoria Geantă }
13523a488aaeSHoria Geantă
1353*660ca947SHerbert Xu edesc->src_nents = src_nents;
1354*660ca947SHerbert Xu edesc->dst_nents = dst_nents;
1355*660ca947SHerbert Xu edesc->qm_sg_bytes = qm_sg_bytes;
1356*660ca947SHerbert Xu edesc->drv_req.app_ctx = req;
1357*660ca947SHerbert Xu edesc->drv_req.cbk = skcipher_done;
1358*660ca947SHerbert Xu edesc->drv_req.drv_ctx = drv_ctx;
1359199354d7SHerbert Xu
13603a488aaeSHoria Geantă /* Make sure IV is located in a DMAable area */
13613a488aaeSHoria Geantă sg_table = &edesc->sgt[0];
1362*660ca947SHerbert Xu iv = skcipher_edesc_iv(edesc);
13639dbe3072SHoria Geantă memcpy(iv, req->iv, ivsize);
13643a488aaeSHoria Geantă
1365334d37c9SHoria Geantă iv_dma = dma_map_single(qidev, iv, ivsize, DMA_BIDIRECTIONAL);
13663a488aaeSHoria Geantă if (dma_mapping_error(qidev, iv_dma)) {
13673a488aaeSHoria Geantă dev_err(qidev, "unable to map IV\n");
13683a488aaeSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0,
1369334d37c9SHoria Geantă 0, DMA_NONE, 0, 0);
13703a488aaeSHoria Geantă qi_cache_free(edesc);
1371b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1372b189817cSHoria Geantă }
1373b189817cSHoria Geantă
1374b189817cSHoria Geantă edesc->iv_dma = iv_dma;
1375b189817cSHoria Geantă
1376b189817cSHoria Geantă dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0);
1377334d37c9SHoria Geantă sg_to_qm_sg(req->src, req->cryptlen, sg_table + 1, 0);
1378b189817cSHoria Geantă
1379334d37c9SHoria Geantă if (req->src != req->dst)
1380334d37c9SHoria Geantă sg_to_qm_sg(req->dst, req->cryptlen, sg_table + dst_sg_idx, 0);
1381334d37c9SHoria Geantă
1382334d37c9SHoria Geantă dma_to_qm_sg_one(sg_table + dst_sg_idx + mapped_dst_nents, iv_dma,
1383334d37c9SHoria Geantă ivsize, 0);
1384b189817cSHoria Geantă
1385b189817cSHoria Geantă edesc->qm_sg_dma = dma_map_single(qidev, sg_table, edesc->qm_sg_bytes,
1386b189817cSHoria Geantă DMA_TO_DEVICE);
1387b189817cSHoria Geantă if (dma_mapping_error(qidev, edesc->qm_sg_dma)) {
1388b189817cSHoria Geantă dev_err(qidev, "unable to map S/G table\n");
1389b189817cSHoria Geantă caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents,
1390334d37c9SHoria Geantă iv_dma, ivsize, DMA_BIDIRECTIONAL, 0, 0);
1391b189817cSHoria Geantă qi_cache_free(edesc);
1392b189817cSHoria Geantă return ERR_PTR(-ENOMEM);
1393b189817cSHoria Geantă }
1394b189817cSHoria Geantă
1395b189817cSHoria Geantă fd_sgt = &edesc->drv_req.fd_sgt[0];
1396b189817cSHoria Geantă
1397b189817cSHoria Geantă dma_to_qm_sg_one_last_ext(&fd_sgt[1], edesc->qm_sg_dma,
13989dbe3072SHoria Geantă ivsize + req->cryptlen, 0);
1399b189817cSHoria Geantă
1400334d37c9SHoria Geantă if (req->src == req->dst)
1401b189817cSHoria Geantă dma_to_qm_sg_one_ext(&fd_sgt[0], edesc->qm_sg_dma +
1402334d37c9SHoria Geantă sizeof(*sg_table), req->cryptlen + ivsize,
1403334d37c9SHoria Geantă 0);
1404334d37c9SHoria Geantă else
1405b189817cSHoria Geantă dma_to_qm_sg_one_ext(&fd_sgt[0], edesc->qm_sg_dma + dst_sg_idx *
1406334d37c9SHoria Geantă sizeof(*sg_table), req->cryptlen + ivsize,
1407334d37c9SHoria Geantă 0);
1408b189817cSHoria Geantă
1409b189817cSHoria Geantă return edesc;
1410b189817cSHoria Geantă }
1411b189817cSHoria Geantă
xts_skcipher_ivsize(struct skcipher_request * req)141283e8aa91SAndrei Botila static inline bool xts_skcipher_ivsize(struct skcipher_request *req)
141383e8aa91SAndrei Botila {
141483e8aa91SAndrei Botila struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
141583e8aa91SAndrei Botila unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
141683e8aa91SAndrei Botila
141783e8aa91SAndrei Botila return !!get_unaligned((u64 *)(req->iv + (ivsize / 2)));
141883e8aa91SAndrei Botila }
141983e8aa91SAndrei Botila
skcipher_crypt(struct skcipher_request * req,bool encrypt)14209dbe3072SHoria Geantă static inline int skcipher_crypt(struct skcipher_request *req, bool encrypt)
1421b189817cSHoria Geantă {
14229dbe3072SHoria Geantă struct skcipher_edesc *edesc;
14239dbe3072SHoria Geantă struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
14244cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
14253a15679bSAndrei Botila struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
1426b189817cSHoria Geantă int ret;
1427b189817cSHoria Geantă
1428297b931cSAndrei Botila /*
1429297b931cSAndrei Botila * XTS is expected to return an error even for input length = 0
1430297b931cSAndrei Botila * Note that the case input length < block size will be caught during
1431297b931cSAndrei Botila * HW offloading and return an error.
1432297b931cSAndrei Botila */
1433297b931cSAndrei Botila if (!req->cryptlen && !ctx->fallback)
143431bb2f0dSIuliana Prodan return 0;
143531bb2f0dSIuliana Prodan
14363a15679bSAndrei Botila if (ctx->fallback && ((ctrlpriv->era <= 8 && xts_skcipher_ivsize(req)) ||
143762b9a669SAndrei Botila ctx->xts_key_fallback)) {
143883e8aa91SAndrei Botila struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
143983e8aa91SAndrei Botila
144083e8aa91SAndrei Botila skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
144183e8aa91SAndrei Botila skcipher_request_set_callback(&rctx->fallback_req,
144283e8aa91SAndrei Botila req->base.flags,
144383e8aa91SAndrei Botila req->base.complete,
144483e8aa91SAndrei Botila req->base.data);
144583e8aa91SAndrei Botila skcipher_request_set_crypt(&rctx->fallback_req, req->src,
144683e8aa91SAndrei Botila req->dst, req->cryptlen, req->iv);
144783e8aa91SAndrei Botila
144883e8aa91SAndrei Botila return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
144983e8aa91SAndrei Botila crypto_skcipher_decrypt(&rctx->fallback_req);
145083e8aa91SAndrei Botila }
145183e8aa91SAndrei Botila
1452b189817cSHoria Geantă if (unlikely(caam_congested))
1453b189817cSHoria Geantă return -EAGAIN;
1454b189817cSHoria Geantă
1455b189817cSHoria Geantă /* allocate extended descriptor */
14569dbe3072SHoria Geantă edesc = skcipher_edesc_alloc(req, encrypt);
1457b189817cSHoria Geantă if (IS_ERR(edesc))
1458b189817cSHoria Geantă return PTR_ERR(edesc);
1459b189817cSHoria Geantă
1460b189817cSHoria Geantă ret = caam_qi_enqueue(ctx->qidev, &edesc->drv_req);
1461b189817cSHoria Geantă if (!ret) {
1462b189817cSHoria Geantă ret = -EINPROGRESS;
1463b189817cSHoria Geantă } else {
14649dbe3072SHoria Geantă skcipher_unmap(ctx->qidev, edesc, req);
1465b189817cSHoria Geantă qi_cache_free(edesc);
1466b189817cSHoria Geantă }
1467b189817cSHoria Geantă
1468b189817cSHoria Geantă return ret;
1469b189817cSHoria Geantă }
1470b189817cSHoria Geantă
skcipher_encrypt(struct skcipher_request * req)14719dbe3072SHoria Geantă static int skcipher_encrypt(struct skcipher_request *req)
1472b189817cSHoria Geantă {
14739dbe3072SHoria Geantă return skcipher_crypt(req, true);
1474b189817cSHoria Geantă }
1475b189817cSHoria Geantă
skcipher_decrypt(struct skcipher_request * req)14769dbe3072SHoria Geantă static int skcipher_decrypt(struct skcipher_request *req)
1477b189817cSHoria Geantă {
14789dbe3072SHoria Geantă return skcipher_crypt(req, false);
1479b189817cSHoria Geantă }
1480b189817cSHoria Geantă
14819dbe3072SHoria Geantă static struct caam_skcipher_alg driver_algs[] = {
1482b189817cSHoria Geantă {
14839dbe3072SHoria Geantă .skcipher = {
14849dbe3072SHoria Geantă .base = {
14859dbe3072SHoria Geantă .cra_name = "cbc(aes)",
14869dbe3072SHoria Geantă .cra_driver_name = "cbc-aes-caam-qi",
14879dbe3072SHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
14889dbe3072SHoria Geantă },
1489836d8f43SIuliana Prodan .setkey = aes_skcipher_setkey,
14909dbe3072SHoria Geantă .encrypt = skcipher_encrypt,
14919dbe3072SHoria Geantă .decrypt = skcipher_decrypt,
1492b189817cSHoria Geantă .min_keysize = AES_MIN_KEY_SIZE,
1493b189817cSHoria Geantă .max_keysize = AES_MAX_KEY_SIZE,
1494b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1495b189817cSHoria Geantă },
14969dbe3072SHoria Geantă .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1497b189817cSHoria Geantă },
1498b189817cSHoria Geantă {
14999dbe3072SHoria Geantă .skcipher = {
15009dbe3072SHoria Geantă .base = {
15019dbe3072SHoria Geantă .cra_name = "cbc(des3_ede)",
15029dbe3072SHoria Geantă .cra_driver_name = "cbc-3des-caam-qi",
15039dbe3072SHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
15049dbe3072SHoria Geantă },
15051b52c409SHerbert Xu .setkey = des3_skcipher_setkey,
15069dbe3072SHoria Geantă .encrypt = skcipher_encrypt,
15079dbe3072SHoria Geantă .decrypt = skcipher_decrypt,
1508b189817cSHoria Geantă .min_keysize = DES3_EDE_KEY_SIZE,
1509b189817cSHoria Geantă .max_keysize = DES3_EDE_KEY_SIZE,
1510b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
1511b189817cSHoria Geantă },
15129dbe3072SHoria Geantă .caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1513b189817cSHoria Geantă },
1514b189817cSHoria Geantă {
15159dbe3072SHoria Geantă .skcipher = {
15169dbe3072SHoria Geantă .base = {
15179dbe3072SHoria Geantă .cra_name = "cbc(des)",
15189dbe3072SHoria Geantă .cra_driver_name = "cbc-des-caam-qi",
15199dbe3072SHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
15209dbe3072SHoria Geantă },
1521836d8f43SIuliana Prodan .setkey = des_skcipher_setkey,
15229dbe3072SHoria Geantă .encrypt = skcipher_encrypt,
15239dbe3072SHoria Geantă .decrypt = skcipher_decrypt,
1524b189817cSHoria Geantă .min_keysize = DES_KEY_SIZE,
1525b189817cSHoria Geantă .max_keysize = DES_KEY_SIZE,
1526b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
1527b189817cSHoria Geantă },
15289dbe3072SHoria Geantă .caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
1529b189817cSHoria Geantă },
1530b189817cSHoria Geantă {
15319dbe3072SHoria Geantă .skcipher = {
15329dbe3072SHoria Geantă .base = {
15339dbe3072SHoria Geantă .cra_name = "ctr(aes)",
15349dbe3072SHoria Geantă .cra_driver_name = "ctr-aes-caam-qi",
15359dbe3072SHoria Geantă .cra_blocksize = 1,
15369dbe3072SHoria Geantă },
1537836d8f43SIuliana Prodan .setkey = ctr_skcipher_setkey,
15389dbe3072SHoria Geantă .encrypt = skcipher_encrypt,
15399dbe3072SHoria Geantă .decrypt = skcipher_decrypt,
1540b189817cSHoria Geantă .min_keysize = AES_MIN_KEY_SIZE,
1541b189817cSHoria Geantă .max_keysize = AES_MAX_KEY_SIZE,
1542b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
15439dbe3072SHoria Geantă .chunksize = AES_BLOCK_SIZE,
1544b189817cSHoria Geantă },
15459dbe3072SHoria Geantă .caam.class1_alg_type = OP_ALG_ALGSEL_AES |
15469dbe3072SHoria Geantă OP_ALG_AAI_CTR_MOD128,
1547b189817cSHoria Geantă },
1548b189817cSHoria Geantă {
15499dbe3072SHoria Geantă .skcipher = {
15509dbe3072SHoria Geantă .base = {
15519dbe3072SHoria Geantă .cra_name = "rfc3686(ctr(aes))",
15529dbe3072SHoria Geantă .cra_driver_name = "rfc3686-ctr-aes-caam-qi",
15539dbe3072SHoria Geantă .cra_blocksize = 1,
15549dbe3072SHoria Geantă },
1555836d8f43SIuliana Prodan .setkey = rfc3686_skcipher_setkey,
15569dbe3072SHoria Geantă .encrypt = skcipher_encrypt,
15579dbe3072SHoria Geantă .decrypt = skcipher_decrypt,
1558b189817cSHoria Geantă .min_keysize = AES_MIN_KEY_SIZE +
1559b189817cSHoria Geantă CTR_RFC3686_NONCE_SIZE,
1560b189817cSHoria Geantă .max_keysize = AES_MAX_KEY_SIZE +
1561b189817cSHoria Geantă CTR_RFC3686_NONCE_SIZE,
1562b189817cSHoria Geantă .ivsize = CTR_RFC3686_IV_SIZE,
15639dbe3072SHoria Geantă .chunksize = AES_BLOCK_SIZE,
1564b189817cSHoria Geantă },
15659dbe3072SHoria Geantă .caam = {
15669dbe3072SHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES |
15679dbe3072SHoria Geantă OP_ALG_AAI_CTR_MOD128,
15689dbe3072SHoria Geantă .rfc3686 = true,
15699dbe3072SHoria Geantă },
1570b189817cSHoria Geantă },
1571b189817cSHoria Geantă {
15729dbe3072SHoria Geantă .skcipher = {
15739dbe3072SHoria Geantă .base = {
15749dbe3072SHoria Geantă .cra_name = "xts(aes)",
15759dbe3072SHoria Geantă .cra_driver_name = "xts-aes-caam-qi",
157683e8aa91SAndrei Botila .cra_flags = CRYPTO_ALG_NEED_FALLBACK,
15779dbe3072SHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
15789dbe3072SHoria Geantă },
15799dbe3072SHoria Geantă .setkey = xts_skcipher_setkey,
15809dbe3072SHoria Geantă .encrypt = skcipher_encrypt,
15819dbe3072SHoria Geantă .decrypt = skcipher_decrypt,
1582b189817cSHoria Geantă .min_keysize = 2 * AES_MIN_KEY_SIZE,
1583b189817cSHoria Geantă .max_keysize = 2 * AES_MAX_KEY_SIZE,
1584b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1585b189817cSHoria Geantă },
15869dbe3072SHoria Geantă .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
1587b189817cSHoria Geantă },
1588b189817cSHoria Geantă };
1589b189817cSHoria Geantă
1590b189817cSHoria Geantă static struct caam_aead_alg driver_aeads[] = {
1591d3e41b50SHoria Geantă {
1592d3e41b50SHoria Geantă .aead = {
1593d3e41b50SHoria Geantă .base = {
1594d3e41b50SHoria Geantă .cra_name = "rfc4106(gcm(aes))",
1595d3e41b50SHoria Geantă .cra_driver_name = "rfc4106-gcm-aes-caam-qi",
1596d3e41b50SHoria Geantă .cra_blocksize = 1,
1597d3e41b50SHoria Geantă },
1598d3e41b50SHoria Geantă .setkey = rfc4106_setkey,
1599d3e41b50SHoria Geantă .setauthsize = rfc4106_setauthsize,
1600d3e41b50SHoria Geantă .encrypt = ipsec_gcm_encrypt,
1601d3e41b50SHoria Geantă .decrypt = ipsec_gcm_decrypt,
1602d3e41b50SHoria Geantă .ivsize = 8,
1603d3e41b50SHoria Geantă .maxauthsize = AES_BLOCK_SIZE,
1604d3e41b50SHoria Geantă },
1605d3e41b50SHoria Geantă .caam = {
1606d3e41b50SHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
160724586b5fSHerbert Xu .nodkp = true,
1608d3e41b50SHoria Geantă },
1609d3e41b50SHoria Geantă },
1610d3e41b50SHoria Geantă {
1611d3e41b50SHoria Geantă .aead = {
1612d3e41b50SHoria Geantă .base = {
1613d3e41b50SHoria Geantă .cra_name = "rfc4543(gcm(aes))",
1614d3e41b50SHoria Geantă .cra_driver_name = "rfc4543-gcm-aes-caam-qi",
1615d3e41b50SHoria Geantă .cra_blocksize = 1,
1616d3e41b50SHoria Geantă },
1617d3e41b50SHoria Geantă .setkey = rfc4543_setkey,
1618d3e41b50SHoria Geantă .setauthsize = rfc4543_setauthsize,
1619d3e41b50SHoria Geantă .encrypt = ipsec_gcm_encrypt,
1620d3e41b50SHoria Geantă .decrypt = ipsec_gcm_decrypt,
1621d3e41b50SHoria Geantă .ivsize = 8,
1622d3e41b50SHoria Geantă .maxauthsize = AES_BLOCK_SIZE,
1623d3e41b50SHoria Geantă },
1624d3e41b50SHoria Geantă .caam = {
1625d3e41b50SHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
162624586b5fSHerbert Xu .nodkp = true,
1627d3e41b50SHoria Geantă },
1628d3e41b50SHoria Geantă },
1629d3e41b50SHoria Geantă /* Galois Counter Mode */
1630d3e41b50SHoria Geantă {
1631d3e41b50SHoria Geantă .aead = {
1632d3e41b50SHoria Geantă .base = {
1633d3e41b50SHoria Geantă .cra_name = "gcm(aes)",
1634d3e41b50SHoria Geantă .cra_driver_name = "gcm-aes-caam-qi",
1635d3e41b50SHoria Geantă .cra_blocksize = 1,
1636d3e41b50SHoria Geantă },
1637d3e41b50SHoria Geantă .setkey = gcm_setkey,
1638d3e41b50SHoria Geantă .setauthsize = gcm_setauthsize,
1639d3e41b50SHoria Geantă .encrypt = aead_encrypt,
1640d3e41b50SHoria Geantă .decrypt = aead_decrypt,
1641d3e41b50SHoria Geantă .ivsize = 12,
1642d3e41b50SHoria Geantă .maxauthsize = AES_BLOCK_SIZE,
1643d3e41b50SHoria Geantă },
1644d3e41b50SHoria Geantă .caam = {
1645d3e41b50SHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
164624586b5fSHerbert Xu .nodkp = true,
1647d3e41b50SHoria Geantă }
1648d3e41b50SHoria Geantă },
1649b189817cSHoria Geantă /* single-pass ipsec_esp descriptor */
1650b189817cSHoria Geantă {
1651b189817cSHoria Geantă .aead = {
1652b189817cSHoria Geantă .base = {
1653b189817cSHoria Geantă .cra_name = "authenc(hmac(md5),cbc(aes))",
1654b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-md5-"
1655b189817cSHoria Geantă "cbc-aes-caam-qi",
1656b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1657b189817cSHoria Geantă },
1658b189817cSHoria Geantă .setkey = aead_setkey,
1659b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1660b189817cSHoria Geantă .encrypt = aead_encrypt,
1661b189817cSHoria Geantă .decrypt = aead_decrypt,
1662b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1663b189817cSHoria Geantă .maxauthsize = MD5_DIGEST_SIZE,
1664b189817cSHoria Geantă },
1665b189817cSHoria Geantă .caam = {
1666b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1667b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_MD5 |
1668b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1669b189817cSHoria Geantă }
1670b189817cSHoria Geantă },
1671b189817cSHoria Geantă {
1672b189817cSHoria Geantă .aead = {
1673b189817cSHoria Geantă .base = {
1674b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(md5),"
1675b189817cSHoria Geantă "cbc(aes)))",
1676b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-hmac-md5-"
1677b189817cSHoria Geantă "cbc-aes-caam-qi",
1678b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1679b189817cSHoria Geantă },
1680b189817cSHoria Geantă .setkey = aead_setkey,
1681b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1682b189817cSHoria Geantă .encrypt = aead_encrypt,
1683b189817cSHoria Geantă .decrypt = aead_decrypt,
1684b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1685b189817cSHoria Geantă .maxauthsize = MD5_DIGEST_SIZE,
1686b189817cSHoria Geantă },
1687b189817cSHoria Geantă .caam = {
1688b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1689b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_MD5 |
1690b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1691b189817cSHoria Geantă .geniv = true,
1692b189817cSHoria Geantă }
1693b189817cSHoria Geantă },
1694b189817cSHoria Geantă {
1695b189817cSHoria Geantă .aead = {
1696b189817cSHoria Geantă .base = {
1697b189817cSHoria Geantă .cra_name = "authenc(hmac(sha1),cbc(aes))",
1698b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha1-"
1699b189817cSHoria Geantă "cbc-aes-caam-qi",
1700b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1701b189817cSHoria Geantă },
1702b189817cSHoria Geantă .setkey = aead_setkey,
1703b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1704b189817cSHoria Geantă .encrypt = aead_encrypt,
1705b189817cSHoria Geantă .decrypt = aead_decrypt,
1706b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1707b189817cSHoria Geantă .maxauthsize = SHA1_DIGEST_SIZE,
1708b189817cSHoria Geantă },
1709b189817cSHoria Geantă .caam = {
1710b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1711b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
1712b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1713b189817cSHoria Geantă }
1714b189817cSHoria Geantă },
1715b189817cSHoria Geantă {
1716b189817cSHoria Geantă .aead = {
1717b189817cSHoria Geantă .base = {
1718b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha1),"
1719b189817cSHoria Geantă "cbc(aes)))",
1720b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
1721b189817cSHoria Geantă "hmac-sha1-cbc-aes-caam-qi",
1722b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1723b189817cSHoria Geantă },
1724b189817cSHoria Geantă .setkey = aead_setkey,
1725b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1726b189817cSHoria Geantă .encrypt = aead_encrypt,
1727b189817cSHoria Geantă .decrypt = aead_decrypt,
1728b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1729b189817cSHoria Geantă .maxauthsize = SHA1_DIGEST_SIZE,
1730b189817cSHoria Geantă },
1731b189817cSHoria Geantă .caam = {
1732b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1733b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
1734b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1735b189817cSHoria Geantă .geniv = true,
1736b189817cSHoria Geantă },
1737b189817cSHoria Geantă },
1738b189817cSHoria Geantă {
1739b189817cSHoria Geantă .aead = {
1740b189817cSHoria Geantă .base = {
1741b189817cSHoria Geantă .cra_name = "authenc(hmac(sha224),cbc(aes))",
1742b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha224-"
1743b189817cSHoria Geantă "cbc-aes-caam-qi",
1744b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1745b189817cSHoria Geantă },
1746b189817cSHoria Geantă .setkey = aead_setkey,
1747b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1748b189817cSHoria Geantă .encrypt = aead_encrypt,
1749b189817cSHoria Geantă .decrypt = aead_decrypt,
1750b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1751b189817cSHoria Geantă .maxauthsize = SHA224_DIGEST_SIZE,
1752b189817cSHoria Geantă },
1753b189817cSHoria Geantă .caam = {
1754b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1755b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
1756b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1757b189817cSHoria Geantă }
1758b189817cSHoria Geantă },
1759b189817cSHoria Geantă {
1760b189817cSHoria Geantă .aead = {
1761b189817cSHoria Geantă .base = {
1762b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha224),"
1763b189817cSHoria Geantă "cbc(aes)))",
1764b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
1765b189817cSHoria Geantă "hmac-sha224-cbc-aes-caam-qi",
1766b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1767b189817cSHoria Geantă },
1768b189817cSHoria Geantă .setkey = aead_setkey,
1769b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1770b189817cSHoria Geantă .encrypt = aead_encrypt,
1771b189817cSHoria Geantă .decrypt = aead_decrypt,
1772b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1773b189817cSHoria Geantă .maxauthsize = SHA224_DIGEST_SIZE,
1774b189817cSHoria Geantă },
1775b189817cSHoria Geantă .caam = {
1776b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1777b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
1778b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1779b189817cSHoria Geantă .geniv = true,
1780b189817cSHoria Geantă }
1781b189817cSHoria Geantă },
1782b189817cSHoria Geantă {
1783b189817cSHoria Geantă .aead = {
1784b189817cSHoria Geantă .base = {
1785b189817cSHoria Geantă .cra_name = "authenc(hmac(sha256),cbc(aes))",
1786b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha256-"
1787b189817cSHoria Geantă "cbc-aes-caam-qi",
1788b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1789b189817cSHoria Geantă },
1790b189817cSHoria Geantă .setkey = aead_setkey,
1791b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1792b189817cSHoria Geantă .encrypt = aead_encrypt,
1793b189817cSHoria Geantă .decrypt = aead_decrypt,
1794b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1795b189817cSHoria Geantă .maxauthsize = SHA256_DIGEST_SIZE,
1796b189817cSHoria Geantă },
1797b189817cSHoria Geantă .caam = {
1798b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1799b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
1800b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1801b189817cSHoria Geantă }
1802b189817cSHoria Geantă },
1803b189817cSHoria Geantă {
1804b189817cSHoria Geantă .aead = {
1805b189817cSHoria Geantă .base = {
1806b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha256),"
1807b189817cSHoria Geantă "cbc(aes)))",
1808b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
1809b189817cSHoria Geantă "hmac-sha256-cbc-aes-"
1810b189817cSHoria Geantă "caam-qi",
1811b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1812b189817cSHoria Geantă },
1813b189817cSHoria Geantă .setkey = aead_setkey,
1814b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1815b189817cSHoria Geantă .encrypt = aead_encrypt,
1816b189817cSHoria Geantă .decrypt = aead_decrypt,
1817b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1818b189817cSHoria Geantă .maxauthsize = SHA256_DIGEST_SIZE,
1819b189817cSHoria Geantă },
1820b189817cSHoria Geantă .caam = {
1821b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1822b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
1823b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1824b189817cSHoria Geantă .geniv = true,
1825b189817cSHoria Geantă }
1826b189817cSHoria Geantă },
1827b189817cSHoria Geantă {
1828b189817cSHoria Geantă .aead = {
1829b189817cSHoria Geantă .base = {
1830b189817cSHoria Geantă .cra_name = "authenc(hmac(sha384),cbc(aes))",
1831b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha384-"
1832b189817cSHoria Geantă "cbc-aes-caam-qi",
1833b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1834b189817cSHoria Geantă },
1835b189817cSHoria Geantă .setkey = aead_setkey,
1836b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1837b189817cSHoria Geantă .encrypt = aead_encrypt,
1838b189817cSHoria Geantă .decrypt = aead_decrypt,
1839b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1840b189817cSHoria Geantă .maxauthsize = SHA384_DIGEST_SIZE,
1841b189817cSHoria Geantă },
1842b189817cSHoria Geantă .caam = {
1843b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1844b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
1845b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1846b189817cSHoria Geantă }
1847b189817cSHoria Geantă },
1848b189817cSHoria Geantă {
1849b189817cSHoria Geantă .aead = {
1850b189817cSHoria Geantă .base = {
1851b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha384),"
1852b189817cSHoria Geantă "cbc(aes)))",
1853b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
1854b189817cSHoria Geantă "hmac-sha384-cbc-aes-"
1855b189817cSHoria Geantă "caam-qi",
1856b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1857b189817cSHoria Geantă },
1858b189817cSHoria Geantă .setkey = aead_setkey,
1859b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1860b189817cSHoria Geantă .encrypt = aead_encrypt,
1861b189817cSHoria Geantă .decrypt = aead_decrypt,
1862b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1863b189817cSHoria Geantă .maxauthsize = SHA384_DIGEST_SIZE,
1864b189817cSHoria Geantă },
1865b189817cSHoria Geantă .caam = {
1866b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1867b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
1868b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1869b189817cSHoria Geantă .geniv = true,
1870b189817cSHoria Geantă }
1871b189817cSHoria Geantă },
1872b189817cSHoria Geantă {
1873b189817cSHoria Geantă .aead = {
1874b189817cSHoria Geantă .base = {
1875b189817cSHoria Geantă .cra_name = "authenc(hmac(sha512),cbc(aes))",
1876b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha512-"
1877b189817cSHoria Geantă "cbc-aes-caam-qi",
1878b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1879b189817cSHoria Geantă },
1880b189817cSHoria Geantă .setkey = aead_setkey,
1881b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1882b189817cSHoria Geantă .encrypt = aead_encrypt,
1883b189817cSHoria Geantă .decrypt = aead_decrypt,
1884b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1885b189817cSHoria Geantă .maxauthsize = SHA512_DIGEST_SIZE,
1886b189817cSHoria Geantă },
1887b189817cSHoria Geantă .caam = {
1888b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1889b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
1890b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1891b189817cSHoria Geantă }
1892b189817cSHoria Geantă },
1893b189817cSHoria Geantă {
1894b189817cSHoria Geantă .aead = {
1895b189817cSHoria Geantă .base = {
1896b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha512),"
1897b189817cSHoria Geantă "cbc(aes)))",
1898b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
1899b189817cSHoria Geantă "hmac-sha512-cbc-aes-"
1900b189817cSHoria Geantă "caam-qi",
1901b189817cSHoria Geantă .cra_blocksize = AES_BLOCK_SIZE,
1902b189817cSHoria Geantă },
1903b189817cSHoria Geantă .setkey = aead_setkey,
1904b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1905b189817cSHoria Geantă .encrypt = aead_encrypt,
1906b189817cSHoria Geantă .decrypt = aead_decrypt,
1907b189817cSHoria Geantă .ivsize = AES_BLOCK_SIZE,
1908b189817cSHoria Geantă .maxauthsize = SHA512_DIGEST_SIZE,
1909b189817cSHoria Geantă },
1910b189817cSHoria Geantă .caam = {
1911b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1912b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
1913b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1914b189817cSHoria Geantă .geniv = true,
1915b189817cSHoria Geantă }
1916b189817cSHoria Geantă },
1917b189817cSHoria Geantă {
1918b189817cSHoria Geantă .aead = {
1919b189817cSHoria Geantă .base = {
1920b189817cSHoria Geantă .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
1921b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-md5-"
1922b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
1923b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1924b189817cSHoria Geantă },
19251b52c409SHerbert Xu .setkey = des3_aead_setkey,
1926b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1927b189817cSHoria Geantă .encrypt = aead_encrypt,
1928b189817cSHoria Geantă .decrypt = aead_decrypt,
1929b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
1930b189817cSHoria Geantă .maxauthsize = MD5_DIGEST_SIZE,
1931b189817cSHoria Geantă },
1932b189817cSHoria Geantă .caam = {
1933b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1934b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_MD5 |
1935b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1936b189817cSHoria Geantă }
1937b189817cSHoria Geantă },
1938b189817cSHoria Geantă {
1939b189817cSHoria Geantă .aead = {
1940b189817cSHoria Geantă .base = {
1941b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(md5),"
1942b189817cSHoria Geantă "cbc(des3_ede)))",
1943b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-hmac-md5-"
1944b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
1945b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1946b189817cSHoria Geantă },
19471b52c409SHerbert Xu .setkey = des3_aead_setkey,
1948b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1949b189817cSHoria Geantă .encrypt = aead_encrypt,
1950b189817cSHoria Geantă .decrypt = aead_decrypt,
1951b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
1952b189817cSHoria Geantă .maxauthsize = MD5_DIGEST_SIZE,
1953b189817cSHoria Geantă },
1954b189817cSHoria Geantă .caam = {
1955b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1956b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_MD5 |
1957b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1958b189817cSHoria Geantă .geniv = true,
1959b189817cSHoria Geantă }
1960b189817cSHoria Geantă },
1961b189817cSHoria Geantă {
1962b189817cSHoria Geantă .aead = {
1963b189817cSHoria Geantă .base = {
1964b189817cSHoria Geantă .cra_name = "authenc(hmac(sha1),"
1965b189817cSHoria Geantă "cbc(des3_ede))",
1966b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha1-"
1967b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
1968b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1969b189817cSHoria Geantă },
19701b52c409SHerbert Xu .setkey = des3_aead_setkey,
1971b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1972b189817cSHoria Geantă .encrypt = aead_encrypt,
1973b189817cSHoria Geantă .decrypt = aead_decrypt,
1974b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
1975b189817cSHoria Geantă .maxauthsize = SHA1_DIGEST_SIZE,
1976b189817cSHoria Geantă },
1977b189817cSHoria Geantă .caam = {
1978b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1979b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
1980b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
1981b189817cSHoria Geantă },
1982b189817cSHoria Geantă },
1983b189817cSHoria Geantă {
1984b189817cSHoria Geantă .aead = {
1985b189817cSHoria Geantă .base = {
1986b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha1),"
1987b189817cSHoria Geantă "cbc(des3_ede)))",
1988b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
1989b189817cSHoria Geantă "hmac-sha1-"
1990b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
1991b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1992b189817cSHoria Geantă },
19931b52c409SHerbert Xu .setkey = des3_aead_setkey,
1994b189817cSHoria Geantă .setauthsize = aead_setauthsize,
1995b189817cSHoria Geantă .encrypt = aead_encrypt,
1996b189817cSHoria Geantă .decrypt = aead_decrypt,
1997b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
1998b189817cSHoria Geantă .maxauthsize = SHA1_DIGEST_SIZE,
1999b189817cSHoria Geantă },
2000b189817cSHoria Geantă .caam = {
2001b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2002b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2003b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2004b189817cSHoria Geantă .geniv = true,
2005b189817cSHoria Geantă }
2006b189817cSHoria Geantă },
2007b189817cSHoria Geantă {
2008b189817cSHoria Geantă .aead = {
2009b189817cSHoria Geantă .base = {
2010b189817cSHoria Geantă .cra_name = "authenc(hmac(sha224),"
2011b189817cSHoria Geantă "cbc(des3_ede))",
2012b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha224-"
2013b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2014b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2015b189817cSHoria Geantă },
20161b52c409SHerbert Xu .setkey = des3_aead_setkey,
2017b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2018b189817cSHoria Geantă .encrypt = aead_encrypt,
2019b189817cSHoria Geantă .decrypt = aead_decrypt,
2020b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2021b189817cSHoria Geantă .maxauthsize = SHA224_DIGEST_SIZE,
2022b189817cSHoria Geantă },
2023b189817cSHoria Geantă .caam = {
2024b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2025b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2026b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2027b189817cSHoria Geantă },
2028b189817cSHoria Geantă },
2029b189817cSHoria Geantă {
2030b189817cSHoria Geantă .aead = {
2031b189817cSHoria Geantă .base = {
2032b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha224),"
2033b189817cSHoria Geantă "cbc(des3_ede)))",
2034b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2035b189817cSHoria Geantă "hmac-sha224-"
2036b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2037b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2038b189817cSHoria Geantă },
20391b52c409SHerbert Xu .setkey = des3_aead_setkey,
2040b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2041b189817cSHoria Geantă .encrypt = aead_encrypt,
2042b189817cSHoria Geantă .decrypt = aead_decrypt,
2043b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2044b189817cSHoria Geantă .maxauthsize = SHA224_DIGEST_SIZE,
2045b189817cSHoria Geantă },
2046b189817cSHoria Geantă .caam = {
2047b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2048b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2049b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2050b189817cSHoria Geantă .geniv = true,
2051b189817cSHoria Geantă }
2052b189817cSHoria Geantă },
2053b189817cSHoria Geantă {
2054b189817cSHoria Geantă .aead = {
2055b189817cSHoria Geantă .base = {
2056b189817cSHoria Geantă .cra_name = "authenc(hmac(sha256),"
2057b189817cSHoria Geantă "cbc(des3_ede))",
2058b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha256-"
2059b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2060b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2061b189817cSHoria Geantă },
20621b52c409SHerbert Xu .setkey = des3_aead_setkey,
2063b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2064b189817cSHoria Geantă .encrypt = aead_encrypt,
2065b189817cSHoria Geantă .decrypt = aead_decrypt,
2066b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2067b189817cSHoria Geantă .maxauthsize = SHA256_DIGEST_SIZE,
2068b189817cSHoria Geantă },
2069b189817cSHoria Geantă .caam = {
2070b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2071b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2072b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2073b189817cSHoria Geantă },
2074b189817cSHoria Geantă },
2075b189817cSHoria Geantă {
2076b189817cSHoria Geantă .aead = {
2077b189817cSHoria Geantă .base = {
2078b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha256),"
2079b189817cSHoria Geantă "cbc(des3_ede)))",
2080b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2081b189817cSHoria Geantă "hmac-sha256-"
2082b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2083b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2084b189817cSHoria Geantă },
20851b52c409SHerbert Xu .setkey = des3_aead_setkey,
2086b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2087b189817cSHoria Geantă .encrypt = aead_encrypt,
2088b189817cSHoria Geantă .decrypt = aead_decrypt,
2089b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2090b189817cSHoria Geantă .maxauthsize = SHA256_DIGEST_SIZE,
2091b189817cSHoria Geantă },
2092b189817cSHoria Geantă .caam = {
2093b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2094b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2095b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2096b189817cSHoria Geantă .geniv = true,
2097b189817cSHoria Geantă }
2098b189817cSHoria Geantă },
2099b189817cSHoria Geantă {
2100b189817cSHoria Geantă .aead = {
2101b189817cSHoria Geantă .base = {
2102b189817cSHoria Geantă .cra_name = "authenc(hmac(sha384),"
2103b189817cSHoria Geantă "cbc(des3_ede))",
2104b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha384-"
2105b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2106b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2107b189817cSHoria Geantă },
21081b52c409SHerbert Xu .setkey = des3_aead_setkey,
2109b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2110b189817cSHoria Geantă .encrypt = aead_encrypt,
2111b189817cSHoria Geantă .decrypt = aead_decrypt,
2112b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2113b189817cSHoria Geantă .maxauthsize = SHA384_DIGEST_SIZE,
2114b189817cSHoria Geantă },
2115b189817cSHoria Geantă .caam = {
2116b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2117b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2118b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2119b189817cSHoria Geantă },
2120b189817cSHoria Geantă },
2121b189817cSHoria Geantă {
2122b189817cSHoria Geantă .aead = {
2123b189817cSHoria Geantă .base = {
2124b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha384),"
2125b189817cSHoria Geantă "cbc(des3_ede)))",
2126b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2127b189817cSHoria Geantă "hmac-sha384-"
2128b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2129b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2130b189817cSHoria Geantă },
21311b52c409SHerbert Xu .setkey = des3_aead_setkey,
2132b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2133b189817cSHoria Geantă .encrypt = aead_encrypt,
2134b189817cSHoria Geantă .decrypt = aead_decrypt,
2135b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2136b189817cSHoria Geantă .maxauthsize = SHA384_DIGEST_SIZE,
2137b189817cSHoria Geantă },
2138b189817cSHoria Geantă .caam = {
2139b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2140b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2141b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2142b189817cSHoria Geantă .geniv = true,
2143b189817cSHoria Geantă }
2144b189817cSHoria Geantă },
2145b189817cSHoria Geantă {
2146b189817cSHoria Geantă .aead = {
2147b189817cSHoria Geantă .base = {
2148b189817cSHoria Geantă .cra_name = "authenc(hmac(sha512),"
2149b189817cSHoria Geantă "cbc(des3_ede))",
2150b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha512-"
2151b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2152b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2153b189817cSHoria Geantă },
21541b52c409SHerbert Xu .setkey = des3_aead_setkey,
2155b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2156b189817cSHoria Geantă .encrypt = aead_encrypt,
2157b189817cSHoria Geantă .decrypt = aead_decrypt,
2158b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2159b189817cSHoria Geantă .maxauthsize = SHA512_DIGEST_SIZE,
2160b189817cSHoria Geantă },
2161b189817cSHoria Geantă .caam = {
2162b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2163b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2164b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2165b189817cSHoria Geantă },
2166b189817cSHoria Geantă },
2167b189817cSHoria Geantă {
2168b189817cSHoria Geantă .aead = {
2169b189817cSHoria Geantă .base = {
2170b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha512),"
2171b189817cSHoria Geantă "cbc(des3_ede)))",
2172b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2173b189817cSHoria Geantă "hmac-sha512-"
2174b189817cSHoria Geantă "cbc-des3_ede-caam-qi",
2175b189817cSHoria Geantă .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2176b189817cSHoria Geantă },
21771b52c409SHerbert Xu .setkey = des3_aead_setkey,
2178b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2179b189817cSHoria Geantă .encrypt = aead_encrypt,
2180b189817cSHoria Geantă .decrypt = aead_decrypt,
2181b189817cSHoria Geantă .ivsize = DES3_EDE_BLOCK_SIZE,
2182b189817cSHoria Geantă .maxauthsize = SHA512_DIGEST_SIZE,
2183b189817cSHoria Geantă },
2184b189817cSHoria Geantă .caam = {
2185b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2186b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2187b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2188b189817cSHoria Geantă .geniv = true,
2189b189817cSHoria Geantă }
2190b189817cSHoria Geantă },
2191b189817cSHoria Geantă {
2192b189817cSHoria Geantă .aead = {
2193b189817cSHoria Geantă .base = {
2194b189817cSHoria Geantă .cra_name = "authenc(hmac(md5),cbc(des))",
2195b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-md5-"
2196b189817cSHoria Geantă "cbc-des-caam-qi",
2197b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2198b189817cSHoria Geantă },
2199b189817cSHoria Geantă .setkey = aead_setkey,
2200b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2201b189817cSHoria Geantă .encrypt = aead_encrypt,
2202b189817cSHoria Geantă .decrypt = aead_decrypt,
2203b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2204b189817cSHoria Geantă .maxauthsize = MD5_DIGEST_SIZE,
2205b189817cSHoria Geantă },
2206b189817cSHoria Geantă .caam = {
2207b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2208b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2209b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2210b189817cSHoria Geantă },
2211b189817cSHoria Geantă },
2212b189817cSHoria Geantă {
2213b189817cSHoria Geantă .aead = {
2214b189817cSHoria Geantă .base = {
2215b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(md5),"
2216b189817cSHoria Geantă "cbc(des)))",
2217b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-hmac-md5-"
2218b189817cSHoria Geantă "cbc-des-caam-qi",
2219b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2220b189817cSHoria Geantă },
2221b189817cSHoria Geantă .setkey = aead_setkey,
2222b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2223b189817cSHoria Geantă .encrypt = aead_encrypt,
2224b189817cSHoria Geantă .decrypt = aead_decrypt,
2225b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2226b189817cSHoria Geantă .maxauthsize = MD5_DIGEST_SIZE,
2227b189817cSHoria Geantă },
2228b189817cSHoria Geantă .caam = {
2229b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2230b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_MD5 |
2231b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2232b189817cSHoria Geantă .geniv = true,
2233b189817cSHoria Geantă }
2234b189817cSHoria Geantă },
2235b189817cSHoria Geantă {
2236b189817cSHoria Geantă .aead = {
2237b189817cSHoria Geantă .base = {
2238b189817cSHoria Geantă .cra_name = "authenc(hmac(sha1),cbc(des))",
2239b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha1-"
2240b189817cSHoria Geantă "cbc-des-caam-qi",
2241b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2242b189817cSHoria Geantă },
2243b189817cSHoria Geantă .setkey = aead_setkey,
2244b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2245b189817cSHoria Geantă .encrypt = aead_encrypt,
2246b189817cSHoria Geantă .decrypt = aead_decrypt,
2247b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2248b189817cSHoria Geantă .maxauthsize = SHA1_DIGEST_SIZE,
2249b189817cSHoria Geantă },
2250b189817cSHoria Geantă .caam = {
2251b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2252b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2253b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2254b189817cSHoria Geantă },
2255b189817cSHoria Geantă },
2256b189817cSHoria Geantă {
2257b189817cSHoria Geantă .aead = {
2258b189817cSHoria Geantă .base = {
2259b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha1),"
2260b189817cSHoria Geantă "cbc(des)))",
2261b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2262b189817cSHoria Geantă "hmac-sha1-cbc-des-caam-qi",
2263b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2264b189817cSHoria Geantă },
2265b189817cSHoria Geantă .setkey = aead_setkey,
2266b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2267b189817cSHoria Geantă .encrypt = aead_encrypt,
2268b189817cSHoria Geantă .decrypt = aead_decrypt,
2269b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2270b189817cSHoria Geantă .maxauthsize = SHA1_DIGEST_SIZE,
2271b189817cSHoria Geantă },
2272b189817cSHoria Geantă .caam = {
2273b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2274b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2275b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2276b189817cSHoria Geantă .geniv = true,
2277b189817cSHoria Geantă }
2278b189817cSHoria Geantă },
2279b189817cSHoria Geantă {
2280b189817cSHoria Geantă .aead = {
2281b189817cSHoria Geantă .base = {
2282b189817cSHoria Geantă .cra_name = "authenc(hmac(sha224),cbc(des))",
2283b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha224-"
2284b189817cSHoria Geantă "cbc-des-caam-qi",
2285b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2286b189817cSHoria Geantă },
2287b189817cSHoria Geantă .setkey = aead_setkey,
2288b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2289b189817cSHoria Geantă .encrypt = aead_encrypt,
2290b189817cSHoria Geantă .decrypt = aead_decrypt,
2291b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2292b189817cSHoria Geantă .maxauthsize = SHA224_DIGEST_SIZE,
2293b189817cSHoria Geantă },
2294b189817cSHoria Geantă .caam = {
2295b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2296b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2297b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2298b189817cSHoria Geantă },
2299b189817cSHoria Geantă },
2300b189817cSHoria Geantă {
2301b189817cSHoria Geantă .aead = {
2302b189817cSHoria Geantă .base = {
2303b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha224),"
2304b189817cSHoria Geantă "cbc(des)))",
2305b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2306b189817cSHoria Geantă "hmac-sha224-cbc-des-"
2307b189817cSHoria Geantă "caam-qi",
2308b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2309b189817cSHoria Geantă },
2310b189817cSHoria Geantă .setkey = aead_setkey,
2311b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2312b189817cSHoria Geantă .encrypt = aead_encrypt,
2313b189817cSHoria Geantă .decrypt = aead_decrypt,
2314b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2315b189817cSHoria Geantă .maxauthsize = SHA224_DIGEST_SIZE,
2316b189817cSHoria Geantă },
2317b189817cSHoria Geantă .caam = {
2318b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2319b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2320b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2321b189817cSHoria Geantă .geniv = true,
2322b189817cSHoria Geantă }
2323b189817cSHoria Geantă },
2324b189817cSHoria Geantă {
2325b189817cSHoria Geantă .aead = {
2326b189817cSHoria Geantă .base = {
2327b189817cSHoria Geantă .cra_name = "authenc(hmac(sha256),cbc(des))",
2328b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha256-"
2329b189817cSHoria Geantă "cbc-des-caam-qi",
2330b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2331b189817cSHoria Geantă },
2332b189817cSHoria Geantă .setkey = aead_setkey,
2333b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2334b189817cSHoria Geantă .encrypt = aead_encrypt,
2335b189817cSHoria Geantă .decrypt = aead_decrypt,
2336b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2337b189817cSHoria Geantă .maxauthsize = SHA256_DIGEST_SIZE,
2338b189817cSHoria Geantă },
2339b189817cSHoria Geantă .caam = {
2340b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2341b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2342b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2343b189817cSHoria Geantă },
2344b189817cSHoria Geantă },
2345b189817cSHoria Geantă {
2346b189817cSHoria Geantă .aead = {
2347b189817cSHoria Geantă .base = {
2348b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha256),"
2349b189817cSHoria Geantă "cbc(des)))",
2350b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
235184ea9543SHoria Geantă "hmac-sha256-cbc-des-"
2352b189817cSHoria Geantă "caam-qi",
2353b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2354b189817cSHoria Geantă },
2355b189817cSHoria Geantă .setkey = aead_setkey,
2356b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2357b189817cSHoria Geantă .encrypt = aead_encrypt,
2358b189817cSHoria Geantă .decrypt = aead_decrypt,
2359b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2360b189817cSHoria Geantă .maxauthsize = SHA256_DIGEST_SIZE,
2361b189817cSHoria Geantă },
2362b189817cSHoria Geantă .caam = {
2363b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2364b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2365b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2366b189817cSHoria Geantă .geniv = true,
2367b189817cSHoria Geantă },
2368b189817cSHoria Geantă },
2369b189817cSHoria Geantă {
2370b189817cSHoria Geantă .aead = {
2371b189817cSHoria Geantă .base = {
2372b189817cSHoria Geantă .cra_name = "authenc(hmac(sha384),cbc(des))",
2373b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha384-"
2374b189817cSHoria Geantă "cbc-des-caam-qi",
2375b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2376b189817cSHoria Geantă },
2377b189817cSHoria Geantă .setkey = aead_setkey,
2378b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2379b189817cSHoria Geantă .encrypt = aead_encrypt,
2380b189817cSHoria Geantă .decrypt = aead_decrypt,
2381b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2382b189817cSHoria Geantă .maxauthsize = SHA384_DIGEST_SIZE,
2383b189817cSHoria Geantă },
2384b189817cSHoria Geantă .caam = {
2385b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2386b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2387b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2388b189817cSHoria Geantă },
2389b189817cSHoria Geantă },
2390b189817cSHoria Geantă {
2391b189817cSHoria Geantă .aead = {
2392b189817cSHoria Geantă .base = {
2393b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha384),"
2394b189817cSHoria Geantă "cbc(des)))",
2395b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2396b189817cSHoria Geantă "hmac-sha384-cbc-des-"
2397b189817cSHoria Geantă "caam-qi",
2398b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2399b189817cSHoria Geantă },
2400b189817cSHoria Geantă .setkey = aead_setkey,
2401b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2402b189817cSHoria Geantă .encrypt = aead_encrypt,
2403b189817cSHoria Geantă .decrypt = aead_decrypt,
2404b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2405b189817cSHoria Geantă .maxauthsize = SHA384_DIGEST_SIZE,
2406b189817cSHoria Geantă },
2407b189817cSHoria Geantă .caam = {
2408b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2409b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2410b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2411b189817cSHoria Geantă .geniv = true,
2412b189817cSHoria Geantă }
2413b189817cSHoria Geantă },
2414b189817cSHoria Geantă {
2415b189817cSHoria Geantă .aead = {
2416b189817cSHoria Geantă .base = {
2417b189817cSHoria Geantă .cra_name = "authenc(hmac(sha512),cbc(des))",
2418b189817cSHoria Geantă .cra_driver_name = "authenc-hmac-sha512-"
2419b189817cSHoria Geantă "cbc-des-caam-qi",
2420b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2421b189817cSHoria Geantă },
2422b189817cSHoria Geantă .setkey = aead_setkey,
2423b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2424b189817cSHoria Geantă .encrypt = aead_encrypt,
2425b189817cSHoria Geantă .decrypt = aead_decrypt,
2426b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2427b189817cSHoria Geantă .maxauthsize = SHA512_DIGEST_SIZE,
2428b189817cSHoria Geantă },
2429b189817cSHoria Geantă .caam = {
2430b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2431b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2432b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2433b189817cSHoria Geantă }
2434b189817cSHoria Geantă },
2435b189817cSHoria Geantă {
2436b189817cSHoria Geantă .aead = {
2437b189817cSHoria Geantă .base = {
2438b189817cSHoria Geantă .cra_name = "echainiv(authenc(hmac(sha512),"
2439b189817cSHoria Geantă "cbc(des)))",
2440b189817cSHoria Geantă .cra_driver_name = "echainiv-authenc-"
2441b189817cSHoria Geantă "hmac-sha512-cbc-des-"
2442b189817cSHoria Geantă "caam-qi",
2443b189817cSHoria Geantă .cra_blocksize = DES_BLOCK_SIZE,
2444b189817cSHoria Geantă },
2445b189817cSHoria Geantă .setkey = aead_setkey,
2446b189817cSHoria Geantă .setauthsize = aead_setauthsize,
2447b189817cSHoria Geantă .encrypt = aead_encrypt,
2448b189817cSHoria Geantă .decrypt = aead_decrypt,
2449b189817cSHoria Geantă .ivsize = DES_BLOCK_SIZE,
2450b189817cSHoria Geantă .maxauthsize = SHA512_DIGEST_SIZE,
2451b189817cSHoria Geantă },
2452b189817cSHoria Geantă .caam = {
2453b189817cSHoria Geantă .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2454b189817cSHoria Geantă .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2455b189817cSHoria Geantă OP_ALG_AAI_HMAC_PRECOMP,
2456b189817cSHoria Geantă .geniv = true,
2457b189817cSHoria Geantă }
2458b189817cSHoria Geantă },
2459b189817cSHoria Geantă };
2460b189817cSHoria Geantă
caam_init_common(struct caam_ctx * ctx,struct caam_alg_entry * caam,bool uses_dkp)24617e0880b9SHoria Geantă static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
24627e0880b9SHoria Geantă bool uses_dkp)
2463b189817cSHoria Geantă {
2464b189817cSHoria Geantă struct caam_drv_private *priv;
2465a7cd942bSHoria Geantă struct device *dev;
2466b189817cSHoria Geantă
2467b189817cSHoria Geantă /*
2468b189817cSHoria Geantă * distribute tfms across job rings to ensure in-order
2469b189817cSHoria Geantă * crypto request processing per tfm
2470b189817cSHoria Geantă */
2471b189817cSHoria Geantă ctx->jrdev = caam_jr_alloc();
2472b189817cSHoria Geantă if (IS_ERR(ctx->jrdev)) {
2473b189817cSHoria Geantă pr_err("Job Ring Device allocation for transform failed\n");
2474b189817cSHoria Geantă return PTR_ERR(ctx->jrdev);
2475b189817cSHoria Geantă }
2476b189817cSHoria Geantă
2477a7cd942bSHoria Geantă dev = ctx->jrdev->parent;
2478a7cd942bSHoria Geantă priv = dev_get_drvdata(dev);
24797e0880b9SHoria Geantă if (priv->era >= 6 && uses_dkp)
24807e0880b9SHoria Geantă ctx->dir = DMA_BIDIRECTIONAL;
24817e0880b9SHoria Geantă else
24827e0880b9SHoria Geantă ctx->dir = DMA_TO_DEVICE;
24837e0880b9SHoria Geantă
2484a7cd942bSHoria Geantă ctx->key_dma = dma_map_single(dev, ctx->key, sizeof(ctx->key),
24857e0880b9SHoria Geantă ctx->dir);
2486a7cd942bSHoria Geantă if (dma_mapping_error(dev, ctx->key_dma)) {
2487a7cd942bSHoria Geantă dev_err(dev, "unable to map key\n");
2488b189817cSHoria Geantă caam_jr_free(ctx->jrdev);
2489b189817cSHoria Geantă return -ENOMEM;
2490b189817cSHoria Geantă }
2491b189817cSHoria Geantă
2492b189817cSHoria Geantă /* copy descriptor header template value */
2493b189817cSHoria Geantă ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
2494b189817cSHoria Geantă ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
2495b189817cSHoria Geantă
2496a7cd942bSHoria Geantă ctx->qidev = dev;
2497b189817cSHoria Geantă
2498b189817cSHoria Geantă spin_lock_init(&ctx->lock);
2499b189817cSHoria Geantă ctx->drv_ctx[ENCRYPT] = NULL;
2500b189817cSHoria Geantă ctx->drv_ctx[DECRYPT] = NULL;
2501b189817cSHoria Geantă
2502b189817cSHoria Geantă return 0;
2503b189817cSHoria Geantă }
2504b189817cSHoria Geantă
caam_cra_init(struct crypto_skcipher * tfm)25059dbe3072SHoria Geantă static int caam_cra_init(struct crypto_skcipher *tfm)
2506b189817cSHoria Geantă {
25079dbe3072SHoria Geantă struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
25089dbe3072SHoria Geantă struct caam_skcipher_alg *caam_alg =
25099dbe3072SHoria Geantă container_of(alg, typeof(*caam_alg), skcipher);
25104cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_skcipher_ctx_dma(tfm);
251183e8aa91SAndrei Botila u32 alg_aai = caam_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
251283e8aa91SAndrei Botila int ret = 0;
2513b189817cSHoria Geantă
251483e8aa91SAndrei Botila if (alg_aai == OP_ALG_AAI_XTS) {
251583e8aa91SAndrei Botila const char *tfm_name = crypto_tfm_alg_name(&tfm->base);
251683e8aa91SAndrei Botila struct crypto_skcipher *fallback;
251783e8aa91SAndrei Botila
251883e8aa91SAndrei Botila fallback = crypto_alloc_skcipher(tfm_name, 0,
251983e8aa91SAndrei Botila CRYPTO_ALG_NEED_FALLBACK);
252083e8aa91SAndrei Botila if (IS_ERR(fallback)) {
2521ab95bd2aSHoria Geantă pr_err("Failed to allocate %s fallback: %ld\n",
252283e8aa91SAndrei Botila tfm_name, PTR_ERR(fallback));
252383e8aa91SAndrei Botila return PTR_ERR(fallback);
252483e8aa91SAndrei Botila }
252583e8aa91SAndrei Botila
252683e8aa91SAndrei Botila ctx->fallback = fallback;
252783e8aa91SAndrei Botila crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_skcipher_req_ctx) +
252883e8aa91SAndrei Botila crypto_skcipher_reqsize(fallback));
252983e8aa91SAndrei Botila }
253083e8aa91SAndrei Botila
253183e8aa91SAndrei Botila ret = caam_init_common(ctx, &caam_alg->caam, false);
253283e8aa91SAndrei Botila if (ret && ctx->fallback)
253383e8aa91SAndrei Botila crypto_free_skcipher(ctx->fallback);
253483e8aa91SAndrei Botila
253583e8aa91SAndrei Botila return ret;
2536b189817cSHoria Geantă }
2537b189817cSHoria Geantă
caam_aead_init(struct crypto_aead * tfm)2538b189817cSHoria Geantă static int caam_aead_init(struct crypto_aead *tfm)
2539b189817cSHoria Geantă {
2540b189817cSHoria Geantă struct aead_alg *alg = crypto_aead_alg(tfm);
2541b189817cSHoria Geantă struct caam_aead_alg *caam_alg = container_of(alg, typeof(*caam_alg),
2542b189817cSHoria Geantă aead);
25434cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_aead_ctx_dma(tfm);
2544b189817cSHoria Geantă
254524586b5fSHerbert Xu return caam_init_common(ctx, &caam_alg->caam, !caam_alg->caam.nodkp);
2546b189817cSHoria Geantă }
2547b189817cSHoria Geantă
caam_exit_common(struct caam_ctx * ctx)2548b189817cSHoria Geantă static void caam_exit_common(struct caam_ctx *ctx)
2549b189817cSHoria Geantă {
2550b189817cSHoria Geantă caam_drv_ctx_rel(ctx->drv_ctx[ENCRYPT]);
2551b189817cSHoria Geantă caam_drv_ctx_rel(ctx->drv_ctx[DECRYPT]);
2552b189817cSHoria Geantă
2553a7cd942bSHoria Geantă dma_unmap_single(ctx->jrdev->parent, ctx->key_dma, sizeof(ctx->key),
2554a7cd942bSHoria Geantă ctx->dir);
2555b189817cSHoria Geantă
2556b189817cSHoria Geantă caam_jr_free(ctx->jrdev);
2557b189817cSHoria Geantă }
2558b189817cSHoria Geantă
caam_cra_exit(struct crypto_skcipher * tfm)25599dbe3072SHoria Geantă static void caam_cra_exit(struct crypto_skcipher *tfm)
2560b189817cSHoria Geantă {
25614cb4f7c1SHerbert Xu struct caam_ctx *ctx = crypto_skcipher_ctx_dma(tfm);
256283e8aa91SAndrei Botila
256383e8aa91SAndrei Botila if (ctx->fallback)
256483e8aa91SAndrei Botila crypto_free_skcipher(ctx->fallback);
256583e8aa91SAndrei Botila caam_exit_common(ctx);
2566b189817cSHoria Geantă }
2567b189817cSHoria Geantă
caam_aead_exit(struct crypto_aead * tfm)2568b189817cSHoria Geantă static void caam_aead_exit(struct crypto_aead *tfm)
2569b189817cSHoria Geantă {
25704cb4f7c1SHerbert Xu caam_exit_common(crypto_aead_ctx_dma(tfm));
2571b189817cSHoria Geantă }
2572b189817cSHoria Geantă
caam_qi_algapi_exit(void)25731b46c90cSHoria Geantă void caam_qi_algapi_exit(void)
2574b189817cSHoria Geantă {
2575b189817cSHoria Geantă int i;
2576b189817cSHoria Geantă
2577b189817cSHoria Geantă for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
2578b189817cSHoria Geantă struct caam_aead_alg *t_alg = driver_aeads + i;
2579b189817cSHoria Geantă
2580b189817cSHoria Geantă if (t_alg->registered)
2581b189817cSHoria Geantă crypto_unregister_aead(&t_alg->aead);
2582b189817cSHoria Geantă }
2583b189817cSHoria Geantă
25849dbe3072SHoria Geantă for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
25859dbe3072SHoria Geantă struct caam_skcipher_alg *t_alg = driver_algs + i;
2586b189817cSHoria Geantă
25879dbe3072SHoria Geantă if (t_alg->registered)
25889dbe3072SHoria Geantă crypto_unregister_skcipher(&t_alg->skcipher);
2589b189817cSHoria Geantă }
2590b189817cSHoria Geantă }
2591b189817cSHoria Geantă
caam_skcipher_alg_init(struct caam_skcipher_alg * t_alg)25929dbe3072SHoria Geantă static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
2593b189817cSHoria Geantă {
25949dbe3072SHoria Geantă struct skcipher_alg *alg = &t_alg->skcipher;
2595b189817cSHoria Geantă
25969dbe3072SHoria Geantă alg->base.cra_module = THIS_MODULE;
25979dbe3072SHoria Geantă alg->base.cra_priority = CAAM_CRA_PRIORITY;
25984cb4f7c1SHerbert Xu alg->base.cra_ctxsize = sizeof(struct caam_ctx) + crypto_dma_padding();
259983e8aa91SAndrei Botila alg->base.cra_flags |= (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
260083e8aa91SAndrei Botila CRYPTO_ALG_KERN_DRIVER_ONLY);
2601b189817cSHoria Geantă
26029dbe3072SHoria Geantă alg->init = caam_cra_init;
26039dbe3072SHoria Geantă alg->exit = caam_cra_exit;
2604b189817cSHoria Geantă }
2605b189817cSHoria Geantă
caam_aead_alg_init(struct caam_aead_alg * t_alg)2606b189817cSHoria Geantă static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
2607b189817cSHoria Geantă {
2608b189817cSHoria Geantă struct aead_alg *alg = &t_alg->aead;
2609b189817cSHoria Geantă
2610b189817cSHoria Geantă alg->base.cra_module = THIS_MODULE;
2611b189817cSHoria Geantă alg->base.cra_priority = CAAM_CRA_PRIORITY;
26124cb4f7c1SHerbert Xu alg->base.cra_ctxsize = sizeof(struct caam_ctx) + crypto_dma_padding();
2613b8aa7dc5SMikulas Patocka alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
2614b8aa7dc5SMikulas Patocka CRYPTO_ALG_KERN_DRIVER_ONLY;
2615b189817cSHoria Geantă
2616b189817cSHoria Geantă alg->init = caam_aead_init;
2617b189817cSHoria Geantă alg->exit = caam_aead_exit;
2618b189817cSHoria Geantă }
2619b189817cSHoria Geantă
caam_qi_algapi_init(struct device * ctrldev)26201b46c90cSHoria Geantă int caam_qi_algapi_init(struct device *ctrldev)
2621b189817cSHoria Geantă {
26221b46c90cSHoria Geantă struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
2623b189817cSHoria Geantă int i = 0, err = 0;
2624d239b10dSHoria Geantă u32 aes_vid, aes_inst, des_inst, md_vid, md_inst;
2625b189817cSHoria Geantă unsigned int md_limit = SHA512_DIGEST_SIZE;
2626b189817cSHoria Geantă bool registered = false;
2627b189817cSHoria Geantă
2628c9fbcf68SHoria Geantă /* Make sure this runs only on (DPAA 1.x) QI */
2629c9fbcf68SHoria Geantă if (!priv->qi_present || caam_dpaa2)
2630c9fbcf68SHoria Geantă return 0;
2631d3b5a87cSHoria Geantă
2632b189817cSHoria Geantă /*
2633b189817cSHoria Geantă * Register crypto algorithms the device supports.
2634b189817cSHoria Geantă * First, detect presence and attributes of DES, AES, and MD blocks.
2635b189817cSHoria Geantă */
2636d239b10dSHoria Geantă if (priv->era < 10) {
2637d239b10dSHoria Geantă u32 cha_vid, cha_inst;
2638d239b10dSHoria Geantă
2639b189817cSHoria Geantă cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
2640d239b10dSHoria Geantă aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
2641d239b10dSHoria Geantă md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
2642d239b10dSHoria Geantă
2643b189817cSHoria Geantă cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
2644d239b10dSHoria Geantă des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
2645d239b10dSHoria Geantă CHA_ID_LS_DES_SHIFT;
2646d239b10dSHoria Geantă aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
2647b189817cSHoria Geantă md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
2648d239b10dSHoria Geantă } else {
2649d239b10dSHoria Geantă u32 aesa, mdha;
2650d239b10dSHoria Geantă
2651d239b10dSHoria Geantă aesa = rd_reg32(&priv->ctrl->vreg.aesa);
2652d239b10dSHoria Geantă mdha = rd_reg32(&priv->ctrl->vreg.mdha);
2653d239b10dSHoria Geantă
2654d239b10dSHoria Geantă aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
2655d239b10dSHoria Geantă md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
2656d239b10dSHoria Geantă
2657d239b10dSHoria Geantă des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
2658d239b10dSHoria Geantă aes_inst = aesa & CHA_VER_NUM_MASK;
2659d239b10dSHoria Geantă md_inst = mdha & CHA_VER_NUM_MASK;
2660d239b10dSHoria Geantă }
2661b189817cSHoria Geantă
2662b189817cSHoria Geantă /* If MD is present, limit digest size based on LP256 */
2663d239b10dSHoria Geantă if (md_inst && md_vid == CHA_VER_VID_MD_LP256)
2664b189817cSHoria Geantă md_limit = SHA256_DIGEST_SIZE;
2665b189817cSHoria Geantă
2666b189817cSHoria Geantă for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
26679dbe3072SHoria Geantă struct caam_skcipher_alg *t_alg = driver_algs + i;
26689dbe3072SHoria Geantă u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
2669b189817cSHoria Geantă
2670b189817cSHoria Geantă /* Skip DES algorithms if not supported by device */
2671b189817cSHoria Geantă if (!des_inst &&
2672b189817cSHoria Geantă ((alg_sel == OP_ALG_ALGSEL_3DES) ||
2673b189817cSHoria Geantă (alg_sel == OP_ALG_ALGSEL_DES)))
2674b189817cSHoria Geantă continue;
2675b189817cSHoria Geantă
2676b189817cSHoria Geantă /* Skip AES algorithms if not supported by device */
2677b189817cSHoria Geantă if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
2678b189817cSHoria Geantă continue;
2679b189817cSHoria Geantă
26809dbe3072SHoria Geantă caam_skcipher_alg_init(t_alg);
2681b189817cSHoria Geantă
26829dbe3072SHoria Geantă err = crypto_register_skcipher(&t_alg->skcipher);
2683b189817cSHoria Geantă if (err) {
26846b175685SHoria Geantă dev_warn(ctrldev, "%s alg registration failed\n",
26859dbe3072SHoria Geantă t_alg->skcipher.base.cra_driver_name);
2686b189817cSHoria Geantă continue;
2687b189817cSHoria Geantă }
2688b189817cSHoria Geantă
26899dbe3072SHoria Geantă t_alg->registered = true;
2690b189817cSHoria Geantă registered = true;
2691b189817cSHoria Geantă }
2692b189817cSHoria Geantă
2693b189817cSHoria Geantă for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
2694b189817cSHoria Geantă struct caam_aead_alg *t_alg = driver_aeads + i;
2695b189817cSHoria Geantă u32 c1_alg_sel = t_alg->caam.class1_alg_type &
2696b189817cSHoria Geantă OP_ALG_ALGSEL_MASK;
2697b189817cSHoria Geantă u32 c2_alg_sel = t_alg->caam.class2_alg_type &
2698b189817cSHoria Geantă OP_ALG_ALGSEL_MASK;
2699b189817cSHoria Geantă u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
2700b189817cSHoria Geantă
2701b189817cSHoria Geantă /* Skip DES algorithms if not supported by device */
2702b189817cSHoria Geantă if (!des_inst &&
2703b189817cSHoria Geantă ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
2704b189817cSHoria Geantă (c1_alg_sel == OP_ALG_ALGSEL_DES)))
2705b189817cSHoria Geantă continue;
2706b189817cSHoria Geantă
2707b189817cSHoria Geantă /* Skip AES algorithms if not supported by device */
2708b189817cSHoria Geantă if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
2709b189817cSHoria Geantă continue;
2710b189817cSHoria Geantă
2711b189817cSHoria Geantă /*
2712b189817cSHoria Geantă * Check support for AES algorithms not available
2713b189817cSHoria Geantă * on LP devices.
2714b189817cSHoria Geantă */
2715d239b10dSHoria Geantă if (aes_vid == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
2716b189817cSHoria Geantă continue;
2717b189817cSHoria Geantă
2718b189817cSHoria Geantă /*
2719b189817cSHoria Geantă * Skip algorithms requiring message digests
2720b189817cSHoria Geantă * if MD or MD size is not supported by device.
2721b189817cSHoria Geantă */
2722b189817cSHoria Geantă if (c2_alg_sel &&
2723b189817cSHoria Geantă (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
2724b189817cSHoria Geantă continue;
2725b189817cSHoria Geantă
2726b189817cSHoria Geantă caam_aead_alg_init(t_alg);
2727b189817cSHoria Geantă
2728b189817cSHoria Geantă err = crypto_register_aead(&t_alg->aead);
2729b189817cSHoria Geantă if (err) {
2730b189817cSHoria Geantă pr_warn("%s alg registration failed\n",
2731b189817cSHoria Geantă t_alg->aead.base.cra_driver_name);
2732b189817cSHoria Geantă continue;
2733b189817cSHoria Geantă }
2734b189817cSHoria Geantă
2735b189817cSHoria Geantă t_alg->registered = true;
2736b189817cSHoria Geantă registered = true;
2737b189817cSHoria Geantă }
2738b189817cSHoria Geantă
2739b189817cSHoria Geantă if (registered)
27406b175685SHoria Geantă dev_info(ctrldev, "algorithms registered in /proc/crypto\n");
2741b189817cSHoria Geantă
2742b189817cSHoria Geantă return err;
2743b189817cSHoria Geantă }
2744