• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Shared descriptors for aead, skcipher algorithms
4  *
5  * Copyright 2016-2019 NXP
6  */
7 
8 #include "compat.h"
9 #include "desc_constr.h"
10 #include "caamalg_desc.h"
11 
12 /*
13  * For aead functions, read payload and write payload,
14  * both of which are specified in req->src and req->dst
15  */
aead_append_src_dst(u32 * desc,u32 msg_type)16 static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
17 {
18 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
19 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
20 			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
21 }
22 
23 /* Set DK bit in class 1 operation if shared */
append_dec_op1(u32 * desc,u32 type)24 static inline void append_dec_op1(u32 *desc, u32 type)
25 {
26 	u32 *jump_cmd, *uncond_jump_cmd;
27 
28 	/* DK bit is valid only for AES */
29 	if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
30 		append_operation(desc, type | OP_ALG_AS_INITFINAL |
31 				 OP_ALG_DECRYPT);
32 		return;
33 	}
34 
35 	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
36 	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT);
37 	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
38 	set_jump_tgt_here(desc, jump_cmd);
39 	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT |
40 			 OP_ALG_AAI_DK);
41 	set_jump_tgt_here(desc, uncond_jump_cmd);
42 }
43 
44 /**
45  * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
46  *                               (non-protocol) with no (null) encryption.
47  * @desc: pointer to buffer used for descriptor construction
48  * @adata: pointer to authentication transform definitions.
49  *         A split key is required for SEC Era < 6; the size of the split key
50  *         is specified in this case. Valid algorithm values - one of
51  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
52  *         with OP_ALG_AAI_HMAC_PRECOMP.
53  * @icvsize: integrity check value (ICV) size (truncated or full)
54  * @era: SEC Era
55  */
cnstr_shdsc_aead_null_encap(u32 * const desc,struct alginfo * adata,unsigned int icvsize,int era)56 void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
57 				 unsigned int icvsize, int era)
58 {
59 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
60 
61 	init_sh_desc(desc, HDR_SHARE_SERIAL);
62 
63 	/* Skip if already shared */
64 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
65 				   JUMP_COND_SHRD);
66 	if (era < 6) {
67 		if (adata->key_inline)
68 			append_key_as_imm(desc, adata->key_virt,
69 					  adata->keylen_pad, adata->keylen,
70 					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
71 					  KEY_ENC);
72 		else
73 			append_key(desc, adata->key_dma, adata->keylen,
74 				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
75 	} else {
76 		append_proto_dkp(desc, adata);
77 	}
78 	set_jump_tgt_here(desc, key_jump_cmd);
79 
80 	/* assoclen + cryptlen = seqinlen */
81 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
82 
83 	/* Prepare to read and write cryptlen + assoclen bytes */
84 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
85 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
86 
87 	/*
88 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
89 	 * thus need to do some magic, i.e. self-patch the descriptor
90 	 * buffer.
91 	 */
92 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
93 				    MOVE_DEST_MATH3 |
94 				    (0x6 << MOVE_LEN_SHIFT));
95 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
96 				     MOVE_DEST_DESCBUF |
97 				     MOVE_WAITCOMP |
98 				     (0x8 << MOVE_LEN_SHIFT));
99 
100 	/* Class 2 operation */
101 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
102 			 OP_ALG_ENCRYPT);
103 
104 	/* Read and write cryptlen bytes */
105 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
106 
107 	set_move_tgt_here(desc, read_move_cmd);
108 	set_move_tgt_here(desc, write_move_cmd);
109 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
110 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
111 		    MOVE_AUX_LS);
112 
113 	/* Write ICV */
114 	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
115 			 LDST_SRCDST_BYTE_CONTEXT);
116 
117 	print_hex_dump_debug("aead null enc shdesc@" __stringify(__LINE__)": ",
118 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
119 			     1);
120 }
121 EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
122 
123 /**
124  * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
125  *                               (non-protocol) with no (null) decryption.
126  * @desc: pointer to buffer used for descriptor construction
127  * @adata: pointer to authentication transform definitions.
128  *         A split key is required for SEC Era < 6; the size of the split key
129  *         is specified in this case. Valid algorithm values - one of
130  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
131  *         with OP_ALG_AAI_HMAC_PRECOMP.
132  * @icvsize: integrity check value (ICV) size (truncated or full)
133  * @era: SEC Era
134  */
cnstr_shdsc_aead_null_decap(u32 * const desc,struct alginfo * adata,unsigned int icvsize,int era)135 void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
136 				 unsigned int icvsize, int era)
137 {
138 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
139 
140 	init_sh_desc(desc, HDR_SHARE_SERIAL);
141 
142 	/* Skip if already shared */
143 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
144 				   JUMP_COND_SHRD);
145 	if (era < 6) {
146 		if (adata->key_inline)
147 			append_key_as_imm(desc, adata->key_virt,
148 					  adata->keylen_pad, adata->keylen,
149 					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
150 					  KEY_ENC);
151 		else
152 			append_key(desc, adata->key_dma, adata->keylen,
153 				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
154 	} else {
155 		append_proto_dkp(desc, adata);
156 	}
157 	set_jump_tgt_here(desc, key_jump_cmd);
158 
159 	/* Class 2 operation */
160 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
161 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
162 
163 	/* assoclen + cryptlen = seqoutlen */
164 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
165 
166 	/* Prepare to read and write cryptlen + assoclen bytes */
167 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
168 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
169 
170 	/*
171 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
172 	 * thus need to do some magic, i.e. self-patch the descriptor
173 	 * buffer.
174 	 */
175 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
176 				    MOVE_DEST_MATH2 |
177 				    (0x6 << MOVE_LEN_SHIFT));
178 	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
179 				     MOVE_DEST_DESCBUF |
180 				     MOVE_WAITCOMP |
181 				     (0x8 << MOVE_LEN_SHIFT));
182 
183 	/* Read and write cryptlen bytes */
184 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
185 
186 	/*
187 	 * Insert a NOP here, since we need at least 4 instructions between
188 	 * code patching the descriptor buffer and the location being patched.
189 	 */
190 	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
191 	set_jump_tgt_here(desc, jump_cmd);
192 
193 	set_move_tgt_here(desc, read_move_cmd);
194 	set_move_tgt_here(desc, write_move_cmd);
195 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
196 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
197 		    MOVE_AUX_LS);
198 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
199 
200 	/* Load ICV */
201 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
202 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
203 
204 	print_hex_dump_debug("aead null dec shdesc@" __stringify(__LINE__)": ",
205 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
206 			     1);
207 }
208 EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
209 
init_sh_desc_key_aead(u32 * const desc,struct alginfo * const cdata,struct alginfo * const adata,const bool is_rfc3686,u32 * nonce,int era)210 static void init_sh_desc_key_aead(u32 * const desc,
211 				  struct alginfo * const cdata,
212 				  struct alginfo * const adata,
213 				  const bool is_rfc3686, u32 *nonce, int era)
214 {
215 	u32 *key_jump_cmd;
216 	unsigned int enckeylen = cdata->keylen;
217 
218 	/* Note: Context registers are saved. */
219 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
220 
221 	/* Skip if already shared */
222 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
223 				   JUMP_COND_SHRD);
224 
225 	/*
226 	 * RFC3686 specific:
227 	 *	| key = {AUTH_KEY, ENC_KEY, NONCE}
228 	 *	| enckeylen = encryption key size + nonce size
229 	 */
230 	if (is_rfc3686)
231 		enckeylen -= CTR_RFC3686_NONCE_SIZE;
232 
233 	if (era < 6) {
234 		if (adata->key_inline)
235 			append_key_as_imm(desc, adata->key_virt,
236 					  adata->keylen_pad, adata->keylen,
237 					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
238 					  KEY_ENC);
239 		else
240 			append_key(desc, adata->key_dma, adata->keylen,
241 				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
242 	} else {
243 		append_proto_dkp(desc, adata);
244 	}
245 
246 	if (cdata->key_inline)
247 		append_key_as_imm(desc, cdata->key_virt, enckeylen,
248 				  enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
249 	else
250 		append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
251 			   KEY_DEST_CLASS_REG);
252 
253 	/* Load Counter into CONTEXT1 reg */
254 	if (is_rfc3686) {
255 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
256 				   LDST_CLASS_IND_CCB |
257 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
258 		append_move(desc,
259 			    MOVE_SRC_OUTFIFO |
260 			    MOVE_DEST_CLASS1CTX |
261 			    (16 << MOVE_OFFSET_SHIFT) |
262 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
263 	}
264 
265 	set_jump_tgt_here(desc, key_jump_cmd);
266 }
267 
268 /**
269  * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
270  *                          (non-protocol).
271  * @desc: pointer to buffer used for descriptor construction
272  * @cdata: pointer to block cipher transform definitions
273  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
274  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
275  * @adata: pointer to authentication transform definitions.
276  *         A split key is required for SEC Era < 6; the size of the split key
277  *         is specified in this case. Valid algorithm values - one of
278  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
279  *         with OP_ALG_AAI_HMAC_PRECOMP.
280  * @ivsize: initialization vector size
281  * @icvsize: integrity check value (ICV) size (truncated or full)
282  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
283  * @nonce: pointer to rfc3686 nonce
284  * @ctx1_iv_off: IV offset in CONTEXT1 register
285  * @is_qi: true when called from caam/qi
286  * @era: SEC Era
287  */
cnstr_shdsc_aead_encap(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool is_rfc3686,u32 * nonce,const u32 ctx1_iv_off,const bool is_qi,int era)288 void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
289 			    struct alginfo *adata, unsigned int ivsize,
290 			    unsigned int icvsize, const bool is_rfc3686,
291 			    u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
292 			    int era)
293 {
294 	/* Note: Context registers are saved. */
295 	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
296 
297 	/* Class 2 operation */
298 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
299 			 OP_ALG_ENCRYPT);
300 
301 	if (is_qi) {
302 		u32 *wait_load_cmd;
303 
304 		/* REG3 = assoclen */
305 		append_seq_load(desc, 4, LDST_CLASS_DECO |
306 				LDST_SRCDST_WORD_DECO_MATH3 |
307 				(4 << LDST_OFFSET_SHIFT));
308 
309 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
310 					    JUMP_COND_CALM | JUMP_COND_NCP |
311 					    JUMP_COND_NOP | JUMP_COND_NIP |
312 					    JUMP_COND_NIFP);
313 		set_jump_tgt_here(desc, wait_load_cmd);
314 
315 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
316 				LDST_SRCDST_BYTE_CONTEXT |
317 				(ctx1_iv_off << LDST_OFFSET_SHIFT));
318 	}
319 
320 	/* Read and write assoclen bytes */
321 	if (is_qi || era < 3) {
322 		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
323 		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
324 	} else {
325 		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
326 		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
327 	}
328 
329 	/* Skip assoc data */
330 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
331 
332 	/* read assoc before reading payload */
333 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
334 				      FIFOLDST_VLF);
335 
336 	/* Load Counter into CONTEXT1 reg */
337 	if (is_rfc3686)
338 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
339 				     LDST_SRCDST_BYTE_CONTEXT |
340 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
341 				      LDST_OFFSET_SHIFT));
342 
343 	/* Class 1 operation */
344 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
345 			 OP_ALG_ENCRYPT);
346 
347 	/* Read and write cryptlen bytes */
348 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
349 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
350 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
351 
352 	/* Write ICV */
353 	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
354 			 LDST_SRCDST_BYTE_CONTEXT);
355 
356 	print_hex_dump_debug("aead enc shdesc@" __stringify(__LINE__)": ",
357 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
358 			     1);
359 }
360 EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
361 
362 /**
363  * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
364  *                          (non-protocol).
365  * @desc: pointer to buffer used for descriptor construction
366  * @cdata: pointer to block cipher transform definitions
367  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
368  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
369  * @adata: pointer to authentication transform definitions.
370  *         A split key is required for SEC Era < 6; the size of the split key
371  *         is specified in this case. Valid algorithm values - one of
372  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
373  *         with OP_ALG_AAI_HMAC_PRECOMP.
374  * @ivsize: initialization vector size
375  * @icvsize: integrity check value (ICV) size (truncated or full)
376  * @geniv: whether to generate Encrypted Chain IV
377  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
378  * @nonce: pointer to rfc3686 nonce
379  * @ctx1_iv_off: IV offset in CONTEXT1 register
380  * @is_qi: true when called from caam/qi
381  * @era: SEC Era
382  */
cnstr_shdsc_aead_decap(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool geniv,const bool is_rfc3686,u32 * nonce,const u32 ctx1_iv_off,const bool is_qi,int era)383 void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
384 			    struct alginfo *adata, unsigned int ivsize,
385 			    unsigned int icvsize, const bool geniv,
386 			    const bool is_rfc3686, u32 *nonce,
387 			    const u32 ctx1_iv_off, const bool is_qi, int era)
388 {
389 	/* Note: Context registers are saved. */
390 	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
391 
392 	/* Class 2 operation */
393 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
394 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
395 
396 	if (is_qi) {
397 		u32 *wait_load_cmd;
398 
399 		/* REG3 = assoclen */
400 		append_seq_load(desc, 4, LDST_CLASS_DECO |
401 				LDST_SRCDST_WORD_DECO_MATH3 |
402 				(4 << LDST_OFFSET_SHIFT));
403 
404 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
405 					    JUMP_COND_CALM | JUMP_COND_NCP |
406 					    JUMP_COND_NOP | JUMP_COND_NIP |
407 					    JUMP_COND_NIFP);
408 		set_jump_tgt_here(desc, wait_load_cmd);
409 
410 		if (!geniv)
411 			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
412 					LDST_SRCDST_BYTE_CONTEXT |
413 					(ctx1_iv_off << LDST_OFFSET_SHIFT));
414 	}
415 
416 	/* Read and write assoclen bytes */
417 	if (is_qi || era < 3) {
418 		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
419 		if (geniv)
420 			append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
421 						ivsize);
422 		else
423 			append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
424 					CAAM_CMD_SZ);
425 	} else {
426 		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
427 		if (geniv)
428 			append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
429 						ivsize);
430 		else
431 			append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
432 					CAAM_CMD_SZ);
433 	}
434 
435 	/* Skip assoc data */
436 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
437 
438 	/* read assoc before reading payload */
439 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
440 			     KEY_VLF);
441 
442 	if (geniv) {
443 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
444 				LDST_SRCDST_BYTE_CONTEXT |
445 				(ctx1_iv_off << LDST_OFFSET_SHIFT));
446 		append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
447 			    (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
448 	}
449 
450 	/* Load Counter into CONTEXT1 reg */
451 	if (is_rfc3686)
452 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
453 				     LDST_SRCDST_BYTE_CONTEXT |
454 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
455 				      LDST_OFFSET_SHIFT));
456 
457 	/* Choose operation */
458 	if (ctx1_iv_off)
459 		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
460 				 OP_ALG_DECRYPT);
461 	else
462 		append_dec_op1(desc, cdata->algtype);
463 
464 	/* Read and write cryptlen bytes */
465 	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
466 	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
467 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
468 
469 	/* Load ICV */
470 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
471 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
472 
473 	print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
474 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
475 			     1);
476 }
477 EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
478 
479 /**
480  * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
481  *                             (non-protocol) with HW-generated initialization
482  *                             vector.
483  * @desc: pointer to buffer used for descriptor construction
484  * @cdata: pointer to block cipher transform definitions
485  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
486  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
487  * @adata: pointer to authentication transform definitions.
488  *         A split key is required for SEC Era < 6; the size of the split key
489  *         is specified in this case. Valid algorithm values - one of
490  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
491  *         with OP_ALG_AAI_HMAC_PRECOMP.
492  * @ivsize: initialization vector size
493  * @icvsize: integrity check value (ICV) size (truncated or full)
494  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
495  * @nonce: pointer to rfc3686 nonce
496  * @ctx1_iv_off: IV offset in CONTEXT1 register
497  * @is_qi: true when called from caam/qi
498  * @era: SEC Era
499  */
cnstr_shdsc_aead_givencap(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool is_rfc3686,u32 * nonce,const u32 ctx1_iv_off,const bool is_qi,int era)500 void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
501 			       struct alginfo *adata, unsigned int ivsize,
502 			       unsigned int icvsize, const bool is_rfc3686,
503 			       u32 *nonce, const u32 ctx1_iv_off,
504 			       const bool is_qi, int era)
505 {
506 	u32 geniv, moveiv;
507 	u32 *wait_cmd;
508 
509 	/* Note: Context registers are saved. */
510 	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
511 
512 	if (is_qi) {
513 		u32 *wait_load_cmd;
514 
515 		/* REG3 = assoclen */
516 		append_seq_load(desc, 4, LDST_CLASS_DECO |
517 				LDST_SRCDST_WORD_DECO_MATH3 |
518 				(4 << LDST_OFFSET_SHIFT));
519 
520 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
521 					    JUMP_COND_CALM | JUMP_COND_NCP |
522 					    JUMP_COND_NOP | JUMP_COND_NIP |
523 					    JUMP_COND_NIFP);
524 		set_jump_tgt_here(desc, wait_load_cmd);
525 	}
526 
527 	if (is_rfc3686) {
528 		if (is_qi)
529 			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
530 					LDST_SRCDST_BYTE_CONTEXT |
531 					(ctx1_iv_off << LDST_OFFSET_SHIFT));
532 
533 		goto copy_iv;
534 	}
535 
536 	/* Generate IV */
537 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
538 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
539 		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
540 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
541 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
542 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
543 	append_move(desc, MOVE_WAITCOMP |
544 		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
545 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
546 		    (ivsize << MOVE_LEN_SHIFT));
547 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
548 
549 copy_iv:
550 	/* Copy IV to class 1 context */
551 	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
552 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
553 		    (ivsize << MOVE_LEN_SHIFT));
554 
555 	/* Return to encryption */
556 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
557 			 OP_ALG_ENCRYPT);
558 
559 	/* Read and write assoclen bytes */
560 	if (is_qi || era < 3) {
561 		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
562 		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
563 	} else {
564 		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
565 		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
566 	}
567 
568 	/* Skip assoc data */
569 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
570 
571 	/* read assoc before reading payload */
572 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
573 			     KEY_VLF);
574 
575 	/* Copy iv from outfifo to class 2 fifo */
576 	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
577 		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
578 	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
579 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
580 	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
581 			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
582 
583 	/* Load Counter into CONTEXT1 reg */
584 	if (is_rfc3686)
585 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
586 				     LDST_SRCDST_BYTE_CONTEXT |
587 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
588 				      LDST_OFFSET_SHIFT));
589 
590 	/* Class 1 operation */
591 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
592 			 OP_ALG_ENCRYPT);
593 
594 	/* Will write ivsize + cryptlen */
595 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
596 
597 	/* Not need to reload iv */
598 	append_seq_fifo_load(desc, ivsize,
599 			     FIFOLD_CLASS_SKIP);
600 
601 	/* Will read cryptlen */
602 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
603 
604 	/*
605 	 * Wait for IV transfer (ofifo -> class2) to finish before starting
606 	 * ciphertext transfer (ofifo -> external memory).
607 	 */
608 	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
609 	set_jump_tgt_here(desc, wait_cmd);
610 
611 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
612 			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
613 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
614 
615 	/* Write ICV */
616 	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
617 			 LDST_SRCDST_BYTE_CONTEXT);
618 
619 	print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
620 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
621 			     1);
622 }
623 EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
624 
625 /**
626  * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
627  * @desc: pointer to buffer used for descriptor construction
628  * @cdata: pointer to block cipher transform definitions
629  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
630  * @ivsize: initialization vector size
631  * @icvsize: integrity check value (ICV) size (truncated or full)
632  * @is_qi: true when called from caam/qi
633  */
cnstr_shdsc_gcm_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)634 void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
635 			   unsigned int ivsize, unsigned int icvsize,
636 			   const bool is_qi)
637 {
638 	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
639 	    *zero_assoc_jump_cmd2;
640 
641 	init_sh_desc(desc, HDR_SHARE_SERIAL);
642 
643 	/* skip key loading if they are loaded due to sharing */
644 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
645 				   JUMP_COND_SHRD);
646 	if (cdata->key_inline)
647 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
648 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
649 	else
650 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
651 			   KEY_DEST_CLASS_REG);
652 	set_jump_tgt_here(desc, key_jump_cmd);
653 
654 	/* class 1 operation */
655 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
656 			 OP_ALG_ENCRYPT);
657 
658 	if (is_qi) {
659 		u32 *wait_load_cmd;
660 
661 		/* REG3 = assoclen */
662 		append_seq_load(desc, 4, LDST_CLASS_DECO |
663 				LDST_SRCDST_WORD_DECO_MATH3 |
664 				(4 << LDST_OFFSET_SHIFT));
665 
666 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
667 					    JUMP_COND_CALM | JUMP_COND_NCP |
668 					    JUMP_COND_NOP | JUMP_COND_NIP |
669 					    JUMP_COND_NIFP);
670 		set_jump_tgt_here(desc, wait_load_cmd);
671 
672 		append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
673 					ivsize);
674 	} else {
675 		append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
676 				CAAM_CMD_SZ);
677 	}
678 
679 	/* if assoclen + cryptlen is ZERO, skip to ICV write */
680 	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
681 						 JUMP_COND_MATH_Z);
682 
683 	if (is_qi)
684 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
685 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
686 
687 	/* if assoclen is ZERO, skip reading the assoc data */
688 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
689 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
690 					   JUMP_COND_MATH_Z);
691 
692 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
693 
694 	/* skip assoc data */
695 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
696 
697 	/* cryptlen = seqinlen - assoclen */
698 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
699 
700 	/* if cryptlen is ZERO jump to zero-payload commands */
701 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
702 					    JUMP_COND_MATH_Z);
703 
704 	/* read assoc data */
705 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
706 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
707 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
708 
709 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
710 
711 	/* write encrypted data */
712 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
713 
714 	/* read payload data */
715 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
716 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
717 
718 	/* jump to ICV writing */
719 	if (is_qi)
720 		append_jump(desc, JUMP_TEST_ALL | 4);
721 	else
722 		append_jump(desc, JUMP_TEST_ALL | 2);
723 
724 	/* zero-payload commands */
725 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
726 
727 	/* read assoc data */
728 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
729 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
730 	if (is_qi)
731 		/* jump to ICV writing */
732 		append_jump(desc, JUMP_TEST_ALL | 2);
733 
734 	/* There is no input data */
735 	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
736 
737 	if (is_qi)
738 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
739 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
740 				     FIFOLD_TYPE_LAST1);
741 
742 	/* write ICV */
743 	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
744 			 LDST_SRCDST_BYTE_CONTEXT);
745 
746 	print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
747 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
748 			     1);
749 }
750 EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
751 
752 /**
753  * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
754  * @desc: pointer to buffer used for descriptor construction
755  * @cdata: pointer to block cipher transform definitions
756  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
757  * @ivsize: initialization vector size
758  * @icvsize: integrity check value (ICV) size (truncated or full)
759  * @is_qi: true when called from caam/qi
760  */
cnstr_shdsc_gcm_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)761 void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
762 			   unsigned int ivsize, unsigned int icvsize,
763 			   const bool is_qi)
764 {
765 	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
766 
767 	init_sh_desc(desc, HDR_SHARE_SERIAL);
768 
769 	/* skip key loading if they are loaded due to sharing */
770 	key_jump_cmd = append_jump(desc, JUMP_JSL |
771 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
772 	if (cdata->key_inline)
773 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
774 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
775 	else
776 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
777 			   KEY_DEST_CLASS_REG);
778 	set_jump_tgt_here(desc, key_jump_cmd);
779 
780 	/* class 1 operation */
781 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
782 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
783 
784 	if (is_qi) {
785 		u32 *wait_load_cmd;
786 
787 		/* REG3 = assoclen */
788 		append_seq_load(desc, 4, LDST_CLASS_DECO |
789 				LDST_SRCDST_WORD_DECO_MATH3 |
790 				(4 << LDST_OFFSET_SHIFT));
791 
792 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
793 					    JUMP_COND_CALM | JUMP_COND_NCP |
794 					    JUMP_COND_NOP | JUMP_COND_NIP |
795 					    JUMP_COND_NIFP);
796 		set_jump_tgt_here(desc, wait_load_cmd);
797 
798 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
799 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
800 	}
801 
802 	/* if assoclen is ZERO, skip reading the assoc data */
803 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
804 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
805 						 JUMP_COND_MATH_Z);
806 
807 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
808 
809 	/* skip assoc data */
810 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
811 
812 	/* read assoc data */
813 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
814 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
815 
816 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
817 
818 	/* cryptlen = seqoutlen - assoclen */
819 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
820 
821 	/* jump to zero-payload command if cryptlen is zero */
822 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
823 					    JUMP_COND_MATH_Z);
824 
825 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
826 
827 	/* store encrypted data */
828 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
829 
830 	/* read payload data */
831 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
832 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
833 
834 	/* zero-payload command */
835 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
836 
837 	/* read ICV */
838 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
839 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
840 
841 	print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
842 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
843 			     1);
844 }
845 EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
846 
847 /**
848  * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
849  *                             (non-protocol).
850  * @desc: pointer to buffer used for descriptor construction
851  * @cdata: pointer to block cipher transform definitions
852  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
853  * @ivsize: initialization vector size
854  * @icvsize: integrity check value (ICV) size (truncated or full)
855  * @is_qi: true when called from caam/qi
856  *
857  * Input sequence: AAD | PTXT
858  * Output sequence: AAD | CTXT | ICV
859  * AAD length (assoclen), which includes the IV length, is available in Math3.
860  */
cnstr_shdsc_rfc4106_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)861 void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
862 			       unsigned int ivsize, unsigned int icvsize,
863 			       const bool is_qi)
864 {
865 	u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
866 	init_sh_desc(desc, HDR_SHARE_SERIAL);
867 
868 	/* Skip key loading if it is loaded due to sharing */
869 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
870 				   JUMP_COND_SHRD);
871 	if (cdata->key_inline)
872 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
873 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
874 	else
875 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
876 			   KEY_DEST_CLASS_REG);
877 	set_jump_tgt_here(desc, key_jump_cmd);
878 
879 	/* Class 1 operation */
880 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
881 			 OP_ALG_ENCRYPT);
882 
883 	if (is_qi) {
884 		u32 *wait_load_cmd;
885 
886 		/* REG3 = assoclen */
887 		append_seq_load(desc, 4, LDST_CLASS_DECO |
888 				LDST_SRCDST_WORD_DECO_MATH3 |
889 				(4 << LDST_OFFSET_SHIFT));
890 
891 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
892 					    JUMP_COND_CALM | JUMP_COND_NCP |
893 					    JUMP_COND_NOP | JUMP_COND_NIP |
894 					    JUMP_COND_NIFP);
895 		set_jump_tgt_here(desc, wait_load_cmd);
896 
897 		/* Read salt and IV */
898 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
899 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
900 					FIFOLD_TYPE_IV);
901 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
902 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
903 	}
904 
905 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
906 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
907 
908 	/* Skip AAD */
909 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
910 
911 	/* Read cryptlen and set this value into VARSEQOUTLEN */
912 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
913 
914 	/* If cryptlen is ZERO jump to AAD command */
915 	zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
916 					    JUMP_COND_MATH_Z);
917 
918 	/* Read AAD data */
919 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
920 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
921 
922 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
923 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
924 
925 	/* Skip IV */
926 	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
927 	append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
928 
929 	/* Write encrypted data */
930 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
931 
932 	/* Read payload data */
933 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
934 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
935 
936 	/* Jump instructions to avoid double reading of AAD */
937 	skip_instructions = append_jump(desc, JUMP_TEST_ALL);
938 
939 	/* There is no input data, cryptlen = 0 */
940 	set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
941 
942 	/* Read AAD */
943 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
944 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
945 
946 	set_jump_tgt_here(desc, skip_instructions);
947 
948 	/* Write ICV */
949 	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
950 			 LDST_SRCDST_BYTE_CONTEXT);
951 
952 	print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
953 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
954 			     1);
955 }
956 EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
957 
958 /**
959  * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
960  *                             (non-protocol).
961  * @desc: pointer to buffer used for descriptor construction
962  * @cdata: pointer to block cipher transform definitions
963  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
964  * @ivsize: initialization vector size
965  * @icvsize: integrity check value (ICV) size (truncated or full)
966  * @is_qi: true when called from caam/qi
967  */
cnstr_shdsc_rfc4106_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)968 void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
969 			       unsigned int ivsize, unsigned int icvsize,
970 			       const bool is_qi)
971 {
972 	u32 *key_jump_cmd;
973 
974 	init_sh_desc(desc, HDR_SHARE_SERIAL);
975 
976 	/* Skip key loading if it is loaded due to sharing */
977 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
978 				   JUMP_COND_SHRD);
979 	if (cdata->key_inline)
980 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
981 				  cdata->keylen, CLASS_1 |
982 				  KEY_DEST_CLASS_REG);
983 	else
984 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
985 			   KEY_DEST_CLASS_REG);
986 	set_jump_tgt_here(desc, key_jump_cmd);
987 
988 	/* Class 1 operation */
989 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
990 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
991 
992 	if (is_qi) {
993 		u32 *wait_load_cmd;
994 
995 		/* REG3 = assoclen */
996 		append_seq_load(desc, 4, LDST_CLASS_DECO |
997 				LDST_SRCDST_WORD_DECO_MATH3 |
998 				(4 << LDST_OFFSET_SHIFT));
999 
1000 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1001 					    JUMP_COND_CALM | JUMP_COND_NCP |
1002 					    JUMP_COND_NOP | JUMP_COND_NIP |
1003 					    JUMP_COND_NIFP);
1004 		set_jump_tgt_here(desc, wait_load_cmd);
1005 
1006 		/* Read salt and IV */
1007 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1008 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1009 					FIFOLD_TYPE_IV);
1010 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1011 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1012 	}
1013 
1014 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
1015 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1016 
1017 	/* Read assoc data */
1018 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1019 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1020 
1021 	/* Skip IV */
1022 	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
1023 
1024 	/* Will read cryptlen bytes */
1025 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1026 
1027 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
1028 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1029 
1030 	/* Skip assoc data */
1031 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
1032 
1033 	/* Will write cryptlen bytes */
1034 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1035 
1036 	/* Store payload data */
1037 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1038 
1039 	/* Read encrypted data */
1040 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1041 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1042 
1043 	/* Read ICV */
1044 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1045 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1046 
1047 	print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
1048 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1049 			     1);
1050 }
1051 EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
1052 
1053 /**
1054  * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
1055  *                             (non-protocol).
1056  * @desc: pointer to buffer used for descriptor construction
1057  * @cdata: pointer to block cipher transform definitions
1058  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1059  * @ivsize: initialization vector size
1060  * @icvsize: integrity check value (ICV) size (truncated or full)
1061  * @is_qi: true when called from caam/qi
1062  */
cnstr_shdsc_rfc4543_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)1063 void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
1064 			       unsigned int ivsize, unsigned int icvsize,
1065 			       const bool is_qi)
1066 {
1067 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1068 
1069 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1070 
1071 	/* Skip key loading if it is loaded due to sharing */
1072 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1073 				   JUMP_COND_SHRD);
1074 	if (cdata->key_inline)
1075 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1076 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1077 	else
1078 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1079 			   KEY_DEST_CLASS_REG);
1080 	set_jump_tgt_here(desc, key_jump_cmd);
1081 
1082 	/* Class 1 operation */
1083 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1084 			 OP_ALG_ENCRYPT);
1085 
1086 	if (is_qi) {
1087 		/* assoclen is not needed, skip it */
1088 		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1089 
1090 		/* Read salt and IV */
1091 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1092 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1093 					FIFOLD_TYPE_IV);
1094 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1095 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1096 	}
1097 
1098 	/* assoclen + cryptlen = seqinlen */
1099 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
1100 
1101 	/*
1102 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
1103 	 * thus need to do some magic, i.e. self-patch the descriptor
1104 	 * buffer.
1105 	 */
1106 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1107 				    (0x6 << MOVE_LEN_SHIFT));
1108 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1109 				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1110 
1111 	/* Will read assoclen + cryptlen bytes */
1112 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1113 
1114 	/* Will write assoclen + cryptlen bytes */
1115 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1116 
1117 	/* Read and write assoclen + cryptlen bytes */
1118 	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
1119 
1120 	set_move_tgt_here(desc, read_move_cmd);
1121 	set_move_tgt_here(desc, write_move_cmd);
1122 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1123 	/* Move payload data to OFIFO */
1124 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1125 
1126 	/* Write ICV */
1127 	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
1128 			 LDST_SRCDST_BYTE_CONTEXT);
1129 
1130 	print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
1131 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1132 			     1);
1133 }
1134 EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
1135 
1136 /**
1137  * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
1138  *                             (non-protocol).
1139  * @desc: pointer to buffer used for descriptor construction
1140  * @cdata: pointer to block cipher transform definitions
1141  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1142  * @ivsize: initialization vector size
1143  * @icvsize: integrity check value (ICV) size (truncated or full)
1144  * @is_qi: true when called from caam/qi
1145  */
cnstr_shdsc_rfc4543_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)1146 void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
1147 			       unsigned int ivsize, unsigned int icvsize,
1148 			       const bool is_qi)
1149 {
1150 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1151 
1152 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1153 
1154 	/* Skip key loading if it is loaded due to sharing */
1155 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1156 				   JUMP_COND_SHRD);
1157 	if (cdata->key_inline)
1158 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1159 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1160 	else
1161 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1162 			   KEY_DEST_CLASS_REG);
1163 	set_jump_tgt_here(desc, key_jump_cmd);
1164 
1165 	/* Class 1 operation */
1166 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1167 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1168 
1169 	if (is_qi) {
1170 		/* assoclen is not needed, skip it */
1171 		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1172 
1173 		/* Read salt and IV */
1174 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1175 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1176 					FIFOLD_TYPE_IV);
1177 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1178 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1179 	}
1180 
1181 	/* assoclen + cryptlen = seqoutlen */
1182 	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1183 
1184 	/*
1185 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
1186 	 * thus need to do some magic, i.e. self-patch the descriptor
1187 	 * buffer.
1188 	 */
1189 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1190 				    (0x6 << MOVE_LEN_SHIFT));
1191 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1192 				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1193 
1194 	/* Will read assoclen + cryptlen bytes */
1195 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1196 
1197 	/* Will write assoclen + cryptlen bytes */
1198 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1199 
1200 	/* Store payload data */
1201 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1202 
1203 	/* In-snoop assoclen + cryptlen data */
1204 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
1205 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
1206 
1207 	set_move_tgt_here(desc, read_move_cmd);
1208 	set_move_tgt_here(desc, write_move_cmd);
1209 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1210 	/* Move payload data to OFIFO */
1211 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1212 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1213 
1214 	/* Read ICV */
1215 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1216 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1217 
1218 	print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
1219 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1220 			     1);
1221 }
1222 EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
1223 
1224 /**
1225  * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
1226  *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
1227  *                          descriptor (non-protocol).
1228  * @desc: pointer to buffer used for descriptor construction
1229  * @cdata: pointer to block cipher transform definitions
1230  *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
1231  *         OP_ALG_AAI_AEAD.
1232  * @adata: pointer to authentication transform definitions
1233  *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
1234  *         OP_ALG_AAI_AEAD.
1235  * @ivsize: initialization vector size
1236  * @icvsize: integrity check value (ICV) size (truncated or full)
1237  * @encap: true if encapsulation, false if decapsulation
1238  * @is_qi: true when called from caam/qi
1239  */
cnstr_shdsc_chachapoly(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool encap,const bool is_qi)1240 void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
1241 			    struct alginfo *adata, unsigned int ivsize,
1242 			    unsigned int icvsize, const bool encap,
1243 			    const bool is_qi)
1244 {
1245 	u32 *key_jump_cmd, *wait_cmd;
1246 	u32 nfifo;
1247 	const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
1248 
1249 	/* Note: Context registers are saved. */
1250 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1251 
1252 	/* skip key loading if they are loaded due to sharing */
1253 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1254 				   JUMP_COND_SHRD);
1255 
1256 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
1257 			  CLASS_1 | KEY_DEST_CLASS_REG);
1258 
1259 	/* For IPsec load the salt from keymat in the context register */
1260 	if (is_ipsec)
1261 		append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
1262 				   LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
1263 				   4 << LDST_OFFSET_SHIFT);
1264 
1265 	set_jump_tgt_here(desc, key_jump_cmd);
1266 
1267 	/* Class 2 and 1 operations: Poly & ChaCha */
1268 	if (encap) {
1269 		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1270 				 OP_ALG_ENCRYPT);
1271 		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1272 				 OP_ALG_ENCRYPT);
1273 	} else {
1274 		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1275 				 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1276 		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1277 				 OP_ALG_DECRYPT);
1278 	}
1279 
1280 	if (is_qi) {
1281 		u32 *wait_load_cmd;
1282 		u32 ctx1_iv_off = is_ipsec ? 8 : 4;
1283 
1284 		/* REG3 = assoclen */
1285 		append_seq_load(desc, 4, LDST_CLASS_DECO |
1286 				LDST_SRCDST_WORD_DECO_MATH3 |
1287 				4 << LDST_OFFSET_SHIFT);
1288 
1289 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1290 					    JUMP_COND_CALM | JUMP_COND_NCP |
1291 					    JUMP_COND_NOP | JUMP_COND_NIP |
1292 					    JUMP_COND_NIFP);
1293 		set_jump_tgt_here(desc, wait_load_cmd);
1294 
1295 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
1296 				LDST_SRCDST_BYTE_CONTEXT |
1297 				ctx1_iv_off << LDST_OFFSET_SHIFT);
1298 	}
1299 
1300 	/*
1301 	 * MAGIC with NFIFO
1302 	 * Read associated data from the input and send them to class1 and
1303 	 * class2 alignment blocks. From class1 send data to output fifo and
1304 	 * then write it to memory since we don't need to encrypt AD.
1305 	 */
1306 	nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
1307 		NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
1308 	append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
1309 			    LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
1310 
1311 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
1312 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1313 	append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
1314 			     FIFOLD_CLASS_CLASS1 | LDST_VLF);
1315 	append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
1316 			MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
1317 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
1318 
1319 	/* IPsec - copy IV at the output */
1320 	if (is_ipsec)
1321 		append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
1322 				      0x2 << 25);
1323 
1324 	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
1325 			       JUMP_COND_NOP | JUMP_TEST_ALL);
1326 	set_jump_tgt_here(desc, wait_cmd);
1327 
1328 	if (encap) {
1329 		/* Read and write cryptlen bytes */
1330 		append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1331 		append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
1332 				CAAM_CMD_SZ);
1333 		aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
1334 
1335 		/* Write ICV */
1336 		append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
1337 				 LDST_SRCDST_BYTE_CONTEXT);
1338 	} else {
1339 		/* Read and write cryptlen bytes */
1340 		append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
1341 				CAAM_CMD_SZ);
1342 		append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
1343 				CAAM_CMD_SZ);
1344 		aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
1345 
1346 		/* Load ICV for verification */
1347 		append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
1348 				     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
1349 	}
1350 
1351 	print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
1352 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1353 			     1);
1354 }
1355 EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
1356 
1357 /* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
skcipher_append_src_dst(u32 * desc)1358 static inline void skcipher_append_src_dst(u32 *desc)
1359 {
1360 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1361 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1362 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
1363 			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
1364 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1365 }
1366 
1367 /**
1368  * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
1369  * @desc: pointer to buffer used for descriptor construction
1370  * @cdata: pointer to block cipher transform definitions
1371  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1372  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1373  *                                - OP_ALG_ALGSEL_CHACHA20
1374  * @ivsize: initialization vector size
1375  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1376  * @ctx1_iv_off: IV offset in CONTEXT1 register
1377  */
cnstr_shdsc_skcipher_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,const bool is_rfc3686,const u32 ctx1_iv_off)1378 void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
1379 				unsigned int ivsize, const bool is_rfc3686,
1380 				const u32 ctx1_iv_off)
1381 {
1382 	u32 *key_jump_cmd;
1383 	u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
1384 	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1385 			    OP_ALG_ALGSEL_CHACHA20);
1386 
1387 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1388 	/* Skip if already shared */
1389 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1390 				   JUMP_COND_SHRD);
1391 
1392 	/* Load class1 key only */
1393 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1394 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1395 
1396 	/* Load nonce into CONTEXT1 reg */
1397 	if (is_rfc3686) {
1398 		const u8 *nonce = cdata->key_virt + cdata->keylen;
1399 
1400 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1401 				   LDST_CLASS_IND_CCB |
1402 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1403 		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1404 			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1405 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1406 	}
1407 
1408 	set_jump_tgt_here(desc, key_jump_cmd);
1409 
1410 	/* Load IV, if there is one */
1411 	if (ivsize)
1412 		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1413 				LDST_CLASS_1_CCB | (ctx1_iv_off <<
1414 				LDST_OFFSET_SHIFT));
1415 
1416 	/* Load counter into CONTEXT1 reg */
1417 	if (is_rfc3686)
1418 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1419 				     LDST_SRCDST_BYTE_CONTEXT |
1420 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1421 				      LDST_OFFSET_SHIFT));
1422 
1423 	/* Load operation */
1424 	if (is_chacha20)
1425 		options |= OP_ALG_AS_FINALIZE;
1426 	append_operation(desc, options);
1427 
1428 	/* Perform operation */
1429 	skcipher_append_src_dst(desc);
1430 
1431 	/* Store IV */
1432 	if (!is_chacha20 && ivsize)
1433 		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1434 				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1435 				 LDST_OFFSET_SHIFT));
1436 
1437 	print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
1438 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1439 			     1);
1440 }
1441 EXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
1442 
1443 /**
1444  * cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
1445  * @desc: pointer to buffer used for descriptor construction
1446  * @cdata: pointer to block cipher transform definitions
1447  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1448  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1449  *                                - OP_ALG_ALGSEL_CHACHA20
1450  * @ivsize: initialization vector size
1451  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1452  * @ctx1_iv_off: IV offset in CONTEXT1 register
1453  */
cnstr_shdsc_skcipher_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,const bool is_rfc3686,const u32 ctx1_iv_off)1454 void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
1455 				unsigned int ivsize, const bool is_rfc3686,
1456 				const u32 ctx1_iv_off)
1457 {
1458 	u32 *key_jump_cmd;
1459 	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1460 			    OP_ALG_ALGSEL_CHACHA20);
1461 
1462 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1463 	/* Skip if already shared */
1464 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1465 				   JUMP_COND_SHRD);
1466 
1467 	/* Load class1 key only */
1468 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1469 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1470 
1471 	/* Load nonce into CONTEXT1 reg */
1472 	if (is_rfc3686) {
1473 		const u8 *nonce = cdata->key_virt + cdata->keylen;
1474 
1475 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1476 				   LDST_CLASS_IND_CCB |
1477 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1478 		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1479 			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1480 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1481 	}
1482 
1483 	set_jump_tgt_here(desc, key_jump_cmd);
1484 
1485 	/* Load IV, if there is one */
1486 	if (ivsize)
1487 		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1488 				LDST_CLASS_1_CCB | (ctx1_iv_off <<
1489 				LDST_OFFSET_SHIFT));
1490 
1491 	/* Load counter into CONTEXT1 reg */
1492 	if (is_rfc3686)
1493 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1494 				     LDST_SRCDST_BYTE_CONTEXT |
1495 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1496 				      LDST_OFFSET_SHIFT));
1497 
1498 	/* Choose operation */
1499 	if (ctx1_iv_off)
1500 		append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
1501 				 OP_ALG_DECRYPT);
1502 	else
1503 		append_dec_op1(desc, cdata->algtype);
1504 
1505 	/* Perform operation */
1506 	skcipher_append_src_dst(desc);
1507 
1508 	/* Store IV */
1509 	if (!is_chacha20 && ivsize)
1510 		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1511 				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1512 				 LDST_OFFSET_SHIFT));
1513 
1514 	print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
1515 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1516 			     1);
1517 }
1518 EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
1519 
1520 /**
1521  * cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
1522  * @desc: pointer to buffer used for descriptor construction
1523  * @cdata: pointer to block cipher transform definitions
1524  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1525  */
cnstr_shdsc_xts_skcipher_encap(u32 * const desc,struct alginfo * cdata)1526 void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
1527 {
1528 	/*
1529 	 * Set sector size to a big value, practically disabling
1530 	 * sector size segmentation in xts implementation. We cannot
1531 	 * take full advantage of this HW feature with existing
1532 	 * crypto API / dm-crypt SW architecture.
1533 	 */
1534 	__be64 sector_size = cpu_to_be64(BIT(15));
1535 	u32 *key_jump_cmd;
1536 
1537 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1538 	/* Skip if already shared */
1539 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1540 				   JUMP_COND_SHRD);
1541 
1542 	/* Load class1 keys only */
1543 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1544 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1545 
1546 	/* Load sector size with index 40 bytes (0x28) */
1547 	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1548 			   LDST_SRCDST_BYTE_CONTEXT |
1549 			   (0x28 << LDST_OFFSET_SHIFT));
1550 
1551 	set_jump_tgt_here(desc, key_jump_cmd);
1552 
1553 	/*
1554 	 * create sequence for loading the sector index / 16B tweak value
1555 	 * Lower 8B of IV - sector index / tweak lower half
1556 	 * Upper 8B of IV - upper half of 16B tweak
1557 	 */
1558 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1559 			(0x20 << LDST_OFFSET_SHIFT));
1560 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1561 			(0x30 << LDST_OFFSET_SHIFT));
1562 
1563 	/* Load operation */
1564 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1565 			 OP_ALG_ENCRYPT);
1566 
1567 	/* Perform operation */
1568 	skcipher_append_src_dst(desc);
1569 
1570 	/* Store lower 8B and upper 8B of IV */
1571 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1572 			 (0x20 << LDST_OFFSET_SHIFT));
1573 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1574 			 (0x30 << LDST_OFFSET_SHIFT));
1575 
1576 	print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
1577 			     ": ", DUMP_PREFIX_ADDRESS, 16, 4,
1578 			     desc, desc_bytes(desc), 1);
1579 }
1580 EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
1581 
1582 /**
1583  * cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
1584  * @desc: pointer to buffer used for descriptor construction
1585  * @cdata: pointer to block cipher transform definitions
1586  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1587  */
cnstr_shdsc_xts_skcipher_decap(u32 * const desc,struct alginfo * cdata)1588 void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
1589 {
1590 	/*
1591 	 * Set sector size to a big value, practically disabling
1592 	 * sector size segmentation in xts implementation. We cannot
1593 	 * take full advantage of this HW feature with existing
1594 	 * crypto API / dm-crypt SW architecture.
1595 	 */
1596 	__be64 sector_size = cpu_to_be64(BIT(15));
1597 	u32 *key_jump_cmd;
1598 
1599 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1600 	/* Skip if already shared */
1601 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1602 				   JUMP_COND_SHRD);
1603 
1604 	/* Load class1 key only */
1605 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1606 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1607 
1608 	/* Load sector size with index 40 bytes (0x28) */
1609 	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1610 			   LDST_SRCDST_BYTE_CONTEXT |
1611 			   (0x28 << LDST_OFFSET_SHIFT));
1612 
1613 	set_jump_tgt_here(desc, key_jump_cmd);
1614 
1615 	/*
1616 	 * create sequence for loading the sector index / 16B tweak value
1617 	 * Lower 8B of IV - sector index / tweak lower half
1618 	 * Upper 8B of IV - upper half of 16B tweak
1619 	 */
1620 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1621 			(0x20 << LDST_OFFSET_SHIFT));
1622 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1623 			(0x30 << LDST_OFFSET_SHIFT));
1624 	/* Load operation */
1625 	append_dec_op1(desc, cdata->algtype);
1626 
1627 	/* Perform operation */
1628 	skcipher_append_src_dst(desc);
1629 
1630 	/* Store lower 8B and upper 8B of IV */
1631 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1632 			 (0x20 << LDST_OFFSET_SHIFT));
1633 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1634 			 (0x30 << LDST_OFFSET_SHIFT));
1635 
1636 	print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
1637 			     ": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
1638 			     desc_bytes(desc), 1);
1639 }
1640 EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
1641 
1642 MODULE_LICENSE("GPL");
1643 MODULE_DESCRIPTION("FSL CAAM descriptor support");
1644 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
1645