2 * Shared descriptors for aead, ablkcipher algorithms
8 #include "desc_constr.h"
9 #include "caamalg_desc.h"
12 * For aead functions, read payload and write payload,
13 * both of which are specified in req->src and req->dst
15 static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
17 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
18 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
19 KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
22 /* Set DK bit in class 1 operation if shared */
23 static inline void append_dec_op1(u32 *desc, u32 type)
25 u32 *jump_cmd, *uncond_jump_cmd;
27 /* DK bit is valid only for AES */
28 if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
29 append_operation(desc, type | OP_ALG_AS_INITFINAL |
34 jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
35 append_operation(desc, type | OP_ALG_AS_INITFINAL |
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_INITFINAL |
40 OP_ALG_DECRYPT | OP_ALG_AAI_DK);
41 set_jump_tgt_here(desc, uncond_jump_cmd);
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)
56 void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
57 unsigned int icvsize, int era)
59 u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
61 init_sh_desc(desc, HDR_SHARE_SERIAL);
63 /* Skip if already shared */
64 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
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 |
73 append_key(desc, adata->key_dma, adata->keylen,
74 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
76 append_proto_dkp(desc, adata);
78 set_jump_tgt_here(desc, key_jump_cmd);
80 /* assoclen + cryptlen = seqinlen */
81 append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
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);
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
92 read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
94 (0x6 << MOVE_LEN_SHIFT));
95 write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
98 (0x8 << MOVE_LEN_SHIFT));
100 /* Class 2 operation */
101 append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
104 /* Read and write cryptlen bytes */
105 aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
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 |
114 append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
115 LDST_SRCDST_BYTE_CONTEXT);
118 print_hex_dump(KERN_ERR,
119 "aead null enc shdesc@" __stringify(__LINE__)": ",
120 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
123 EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
126 * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
127 * (non-protocol) with no (null) decryption.
128 * @desc: pointer to buffer used for descriptor construction
129 * @adata: pointer to authentication transform definitions.
130 * A split key is required for SEC Era < 6; the size of the split key
131 * is specified in this case. Valid algorithm values - one of
132 * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
133 * with OP_ALG_AAI_HMAC_PRECOMP.
134 * @icvsize: integrity check value (ICV) size (truncated or full)
137 void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
138 unsigned int icvsize, int era)
140 u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
142 init_sh_desc(desc, HDR_SHARE_SERIAL);
144 /* Skip if already shared */
145 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
148 if (adata->key_inline)
149 append_key_as_imm(desc, adata->key_virt,
150 adata->keylen_pad, adata->keylen,
151 CLASS_2 | KEY_DEST_MDHA_SPLIT |
154 append_key(desc, adata->key_dma, adata->keylen,
155 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
157 append_proto_dkp(desc, adata);
159 set_jump_tgt_here(desc, key_jump_cmd);
161 /* Class 2 operation */
162 append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
163 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
165 /* assoclen + cryptlen = seqoutlen */
166 append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
168 /* Prepare to read and write cryptlen + assoclen bytes */
169 append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
170 append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
173 * MOVE_LEN opcode is not available in all SEC HW revisions,
174 * thus need to do some magic, i.e. self-patch the descriptor
177 read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
179 (0x6 << MOVE_LEN_SHIFT));
180 write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
183 (0x8 << MOVE_LEN_SHIFT));
185 /* Read and write cryptlen bytes */
186 aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
189 * Insert a NOP here, since we need at least 4 instructions between
190 * code patching the descriptor buffer and the location being patched.
192 jump_cmd = append_jump(desc, JUMP_TEST_ALL);
193 set_jump_tgt_here(desc, jump_cmd);
195 set_move_tgt_here(desc, read_move_cmd);
196 set_move_tgt_here(desc, write_move_cmd);
197 append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
198 append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
200 append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
203 append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
204 FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
207 print_hex_dump(KERN_ERR,
208 "aead null dec shdesc@" __stringify(__LINE__)": ",
209 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
212 EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
214 static void init_sh_desc_key_aead(u32 * const desc,
215 struct alginfo * const cdata,
216 struct alginfo * const adata,
217 const bool is_rfc3686, u32 *nonce, int era)
220 unsigned int enckeylen = cdata->keylen;
222 /* Note: Context registers are saved. */
223 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
225 /* Skip if already shared */
226 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
231 * | key = {AUTH_KEY, ENC_KEY, NONCE}
232 * | enckeylen = encryption key size + nonce size
235 enckeylen -= CTR_RFC3686_NONCE_SIZE;
238 if (adata->key_inline)
239 append_key_as_imm(desc, adata->key_virt,
240 adata->keylen_pad, adata->keylen,
241 CLASS_2 | KEY_DEST_MDHA_SPLIT |
244 append_key(desc, adata->key_dma, adata->keylen,
245 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
247 append_proto_dkp(desc, adata);
250 if (cdata->key_inline)
251 append_key_as_imm(desc, cdata->key_virt, enckeylen,
252 enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
254 append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
257 /* Load Counter into CONTEXT1 reg */
259 append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
261 LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
264 MOVE_DEST_CLASS1CTX |
265 (16 << MOVE_OFFSET_SHIFT) |
266 (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
269 set_jump_tgt_here(desc, key_jump_cmd);
273 * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
275 * @desc: pointer to buffer used for descriptor construction
276 * @cdata: pointer to block cipher transform definitions
277 * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
278 * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
279 * @adata: pointer to authentication transform definitions.
280 * A split key is required for SEC Era < 6; the size of the split key
281 * is specified in this case. Valid algorithm values - one of
282 * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
283 * with OP_ALG_AAI_HMAC_PRECOMP.
284 * @ivsize: initialization vector size
285 * @icvsize: integrity check value (ICV) size (truncated or full)
286 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
287 * @nonce: pointer to rfc3686 nonce
288 * @ctx1_iv_off: IV offset in CONTEXT1 register
289 * @is_qi: true when called from caam/qi
292 void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
293 struct alginfo *adata, unsigned int ivsize,
294 unsigned int icvsize, const bool is_rfc3686,
295 u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
298 /* Note: Context registers are saved. */
299 init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
301 /* Class 2 operation */
302 append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
308 /* REG3 = assoclen */
309 append_seq_load(desc, 4, LDST_CLASS_DECO |
310 LDST_SRCDST_WORD_DECO_MATH3 |
311 (4 << LDST_OFFSET_SHIFT));
313 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
314 JUMP_COND_CALM | JUMP_COND_NCP |
315 JUMP_COND_NOP | JUMP_COND_NIP |
317 set_jump_tgt_here(desc, wait_load_cmd);
319 append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
320 LDST_SRCDST_BYTE_CONTEXT |
321 (ctx1_iv_off << LDST_OFFSET_SHIFT));
324 /* Read and write assoclen bytes */
325 if (is_qi || era < 3) {
326 append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
327 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
329 append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
330 append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
333 /* Skip assoc data */
334 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
336 /* read assoc before reading payload */
337 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
340 /* Load Counter into CONTEXT1 reg */
342 append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
343 LDST_SRCDST_BYTE_CONTEXT |
344 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
347 /* Class 1 operation */
348 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
351 /* Read and write cryptlen bytes */
352 append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
353 append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
354 aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
357 append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
358 LDST_SRCDST_BYTE_CONTEXT);
361 print_hex_dump(KERN_ERR, "aead enc shdesc@" __stringify(__LINE__)": ",
362 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
365 EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
368 * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
370 * @desc: pointer to buffer used for descriptor construction
371 * @cdata: pointer to block cipher transform definitions
372 * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
373 * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
374 * @adata: pointer to authentication transform definitions.
375 * A split key is required for SEC Era < 6; the size of the split key
376 * is specified in this case. Valid algorithm values - one of
377 * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
378 * with OP_ALG_AAI_HMAC_PRECOMP.
379 * @ivsize: initialization vector size
380 * @icvsize: integrity check value (ICV) size (truncated or full)
381 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
382 * @nonce: pointer to rfc3686 nonce
383 * @ctx1_iv_off: IV offset in CONTEXT1 register
384 * @is_qi: true when called from caam/qi
387 void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
388 struct alginfo *adata, unsigned int ivsize,
389 unsigned int icvsize, const bool geniv,
390 const bool is_rfc3686, u32 *nonce,
391 const u32 ctx1_iv_off, const bool is_qi, int era)
393 /* Note: Context registers are saved. */
394 init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
396 /* Class 2 operation */
397 append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
398 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
403 /* REG3 = assoclen */
404 append_seq_load(desc, 4, LDST_CLASS_DECO |
405 LDST_SRCDST_WORD_DECO_MATH3 |
406 (4 << LDST_OFFSET_SHIFT));
408 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
409 JUMP_COND_CALM | JUMP_COND_NCP |
410 JUMP_COND_NOP | JUMP_COND_NIP |
412 set_jump_tgt_here(desc, wait_load_cmd);
415 append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
416 LDST_SRCDST_BYTE_CONTEXT |
417 (ctx1_iv_off << LDST_OFFSET_SHIFT));
420 /* Read and write assoclen bytes */
421 if (is_qi || era < 3) {
422 append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
424 append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
427 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
430 append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
432 append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
435 append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
439 /* Skip assoc data */
440 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
442 /* read assoc before reading payload */
443 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
447 append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
448 LDST_SRCDST_BYTE_CONTEXT |
449 (ctx1_iv_off << LDST_OFFSET_SHIFT));
450 append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
451 (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
454 /* Load Counter into CONTEXT1 reg */
456 append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
457 LDST_SRCDST_BYTE_CONTEXT |
458 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
461 /* Choose operation */
463 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
466 append_dec_op1(desc, cdata->algtype);
468 /* Read and write cryptlen bytes */
469 append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
470 append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
471 aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
474 append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
475 FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
478 print_hex_dump(KERN_ERR, "aead dec shdesc@" __stringify(__LINE__)": ",
479 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
482 EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
485 * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
486 * (non-protocol) with HW-generated initialization
488 * @desc: pointer to buffer used for descriptor construction
489 * @cdata: pointer to block cipher transform definitions
490 * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
491 * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
492 * @adata: pointer to authentication transform definitions.
493 * A split key is required for SEC Era < 6; the size of the split key
494 * is specified in this case. Valid algorithm values - one of
495 * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
496 * with OP_ALG_AAI_HMAC_PRECOMP.
497 * @ivsize: initialization vector size
498 * @icvsize: integrity check value (ICV) size (truncated or full)
499 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
500 * @nonce: pointer to rfc3686 nonce
501 * @ctx1_iv_off: IV offset in CONTEXT1 register
502 * @is_qi: true when called from caam/qi
505 void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
506 struct alginfo *adata, unsigned int ivsize,
507 unsigned int icvsize, const bool is_rfc3686,
508 u32 *nonce, const u32 ctx1_iv_off,
509 const bool is_qi, int era)
514 /* Note: Context registers are saved. */
515 init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
520 /* REG3 = assoclen */
521 append_seq_load(desc, 4, LDST_CLASS_DECO |
522 LDST_SRCDST_WORD_DECO_MATH3 |
523 (4 << LDST_OFFSET_SHIFT));
525 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
526 JUMP_COND_CALM | JUMP_COND_NCP |
527 JUMP_COND_NOP | JUMP_COND_NIP |
529 set_jump_tgt_here(desc, wait_load_cmd);
534 append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
535 LDST_SRCDST_BYTE_CONTEXT |
536 (ctx1_iv_off << LDST_OFFSET_SHIFT));
542 geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
543 NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
544 NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
545 append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
546 LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
547 append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
548 append_move(desc, MOVE_WAITCOMP |
549 MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
550 (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
551 (ivsize << MOVE_LEN_SHIFT));
552 append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
555 /* Copy IV to class 1 context */
556 append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
557 (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
558 (ivsize << MOVE_LEN_SHIFT));
560 /* Return to encryption */
561 append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
564 /* Read and write assoclen bytes */
565 if (is_qi || era < 3) {
566 append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
567 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
569 append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
570 append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
573 /* Skip assoc data */
574 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
576 /* read assoc before reading payload */
577 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
580 /* Copy iv from outfifo to class 2 fifo */
581 moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
582 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
583 append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
584 LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
585 append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
586 LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
588 /* Load Counter into CONTEXT1 reg */
590 append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
591 LDST_SRCDST_BYTE_CONTEXT |
592 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
595 /* Class 1 operation */
596 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
599 /* Will write ivsize + cryptlen */
600 append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
602 /* Not need to reload iv */
603 append_seq_fifo_load(desc, ivsize,
606 /* Will read cryptlen */
607 append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
610 * Wait for IV transfer (ofifo -> class2) to finish before starting
611 * ciphertext transfer (ofifo -> external memory).
613 wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
614 set_jump_tgt_here(desc, wait_cmd);
616 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
617 FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
618 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
621 append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
622 LDST_SRCDST_BYTE_CONTEXT);
625 print_hex_dump(KERN_ERR,
626 "aead givenc shdesc@" __stringify(__LINE__)": ",
627 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
630 EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
633 * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
634 * @desc: pointer to buffer used for descriptor construction
635 * @cdata: pointer to block cipher transform definitions
636 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
637 * @ivsize: initialization vector size
638 * @icvsize: integrity check value (ICV) size (truncated or full)
639 * @is_qi: true when called from caam/qi
641 void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
642 unsigned int ivsize, unsigned int icvsize,
645 u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
646 *zero_assoc_jump_cmd2;
648 init_sh_desc(desc, HDR_SHARE_SERIAL);
650 /* skip key loading if they are loaded due to sharing */
651 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
653 if (cdata->key_inline)
654 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
655 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
657 append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
659 set_jump_tgt_here(desc, key_jump_cmd);
661 /* class 1 operation */
662 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
668 /* REG3 = assoclen */
669 append_seq_load(desc, 4, LDST_CLASS_DECO |
670 LDST_SRCDST_WORD_DECO_MATH3 |
671 (4 << LDST_OFFSET_SHIFT));
673 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
674 JUMP_COND_CALM | JUMP_COND_NCP |
675 JUMP_COND_NOP | JUMP_COND_NIP |
677 set_jump_tgt_here(desc, wait_load_cmd);
679 append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
682 append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
686 /* if assoclen + cryptlen is ZERO, skip to ICV write */
687 zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
691 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
692 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
694 /* if assoclen is ZERO, skip reading the assoc data */
695 append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
696 zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
699 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
701 /* skip assoc data */
702 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
704 /* cryptlen = seqinlen - assoclen */
705 append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
707 /* if cryptlen is ZERO jump to zero-payload commands */
708 zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
711 /* read assoc data */
712 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
713 FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
714 set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
716 append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
718 /* write encrypted data */
719 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
721 /* read payload data */
722 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
723 FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
725 /* jump to ICV writing */
727 append_jump(desc, JUMP_TEST_ALL | 4);
729 append_jump(desc, JUMP_TEST_ALL | 2);
731 /* zero-payload commands */
732 set_jump_tgt_here(desc, zero_payload_jump_cmd);
734 /* read assoc data */
735 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
736 FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
738 /* jump to ICV writing */
739 append_jump(desc, JUMP_TEST_ALL | 2);
741 /* There is no input data */
742 set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
745 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
746 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
750 append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
751 LDST_SRCDST_BYTE_CONTEXT);
754 print_hex_dump(KERN_ERR, "gcm enc shdesc@" __stringify(__LINE__)": ",
755 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
758 EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
761 * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
762 * @desc: pointer to buffer used for descriptor construction
763 * @cdata: pointer to block cipher transform definitions
764 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
765 * @ivsize: initialization vector size
766 * @icvsize: integrity check value (ICV) size (truncated or full)
767 * @is_qi: true when called from caam/qi
769 void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
770 unsigned int ivsize, unsigned int icvsize,
773 u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
775 init_sh_desc(desc, HDR_SHARE_SERIAL);
777 /* skip key loading if they are loaded due to sharing */
778 key_jump_cmd = append_jump(desc, JUMP_JSL |
779 JUMP_TEST_ALL | JUMP_COND_SHRD);
780 if (cdata->key_inline)
781 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
782 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
784 append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
786 set_jump_tgt_here(desc, key_jump_cmd);
788 /* class 1 operation */
789 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
790 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
795 /* REG3 = assoclen */
796 append_seq_load(desc, 4, LDST_CLASS_DECO |
797 LDST_SRCDST_WORD_DECO_MATH3 |
798 (4 << LDST_OFFSET_SHIFT));
800 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
801 JUMP_COND_CALM | JUMP_COND_NCP |
802 JUMP_COND_NOP | JUMP_COND_NIP |
804 set_jump_tgt_here(desc, wait_load_cmd);
806 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
807 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
810 /* if assoclen is ZERO, skip reading the assoc data */
811 append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
812 zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
815 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
817 /* skip assoc data */
818 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
820 /* read assoc data */
821 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
822 FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
824 set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
826 /* cryptlen = seqoutlen - assoclen */
827 append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
829 /* jump to zero-payload command if cryptlen is zero */
830 zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
833 append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
835 /* store encrypted data */
836 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
838 /* read payload data */
839 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
840 FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
842 /* zero-payload command */
843 set_jump_tgt_here(desc, zero_payload_jump_cmd);
846 append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
847 FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
850 print_hex_dump(KERN_ERR, "gcm dec shdesc@" __stringify(__LINE__)": ",
851 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
854 EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
857 * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
859 * @desc: pointer to buffer used for descriptor construction
860 * @cdata: pointer to block cipher transform definitions
861 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
862 * @ivsize: initialization vector size
863 * @icvsize: integrity check value (ICV) size (truncated or full)
864 * @is_qi: true when called from caam/qi
866 void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
867 unsigned int ivsize, unsigned int icvsize,
872 init_sh_desc(desc, HDR_SHARE_SERIAL);
874 /* Skip key loading if it is loaded due to sharing */
875 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
877 if (cdata->key_inline)
878 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
879 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
881 append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
883 set_jump_tgt_here(desc, key_jump_cmd);
885 /* Class 1 operation */
886 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
892 /* REG3 = assoclen */
893 append_seq_load(desc, 4, LDST_CLASS_DECO |
894 LDST_SRCDST_WORD_DECO_MATH3 |
895 (4 << LDST_OFFSET_SHIFT));
897 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
898 JUMP_COND_CALM | JUMP_COND_NCP |
899 JUMP_COND_NOP | JUMP_COND_NIP |
901 set_jump_tgt_here(desc, wait_load_cmd);
903 /* Read salt and IV */
904 append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
905 cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
907 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
908 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
911 append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
912 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
914 /* Read assoc data */
915 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
916 FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
919 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
921 /* Will read cryptlen bytes */
922 append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
924 /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
925 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
927 /* Skip assoc data */
928 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
930 /* cryptlen = seqoutlen - assoclen */
931 append_math_sub(desc, VARSEQOUTLEN, VARSEQINLEN, REG0, CAAM_CMD_SZ);
933 /* Write encrypted data */
934 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
936 /* Read payload data */
937 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
938 FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
941 append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
942 LDST_SRCDST_BYTE_CONTEXT);
945 print_hex_dump(KERN_ERR,
946 "rfc4106 enc shdesc@" __stringify(__LINE__)": ",
947 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
950 EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
953 * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
955 * @desc: pointer to buffer used for descriptor construction
956 * @cdata: pointer to block cipher transform definitions
957 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
958 * @ivsize: initialization vector size
959 * @icvsize: integrity check value (ICV) size (truncated or full)
960 * @is_qi: true when called from caam/qi
962 void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
963 unsigned int ivsize, unsigned int icvsize,
968 init_sh_desc(desc, HDR_SHARE_SERIAL);
970 /* Skip key loading if it is loaded due to sharing */
971 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
973 if (cdata->key_inline)
974 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
975 cdata->keylen, CLASS_1 |
978 append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
980 set_jump_tgt_here(desc, key_jump_cmd);
982 /* Class 1 operation */
983 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
984 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
989 /* REG3 = assoclen */
990 append_seq_load(desc, 4, LDST_CLASS_DECO |
991 LDST_SRCDST_WORD_DECO_MATH3 |
992 (4 << LDST_OFFSET_SHIFT));
994 wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
995 JUMP_COND_CALM | JUMP_COND_NCP |
996 JUMP_COND_NOP | JUMP_COND_NIP |
998 set_jump_tgt_here(desc, wait_load_cmd);
1000 /* Read salt and IV */
1001 append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1002 cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1004 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1005 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1008 append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
1009 append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1011 /* Read assoc data */
1012 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1013 FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1016 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
1018 /* Will read cryptlen bytes */
1019 append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1021 /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
1022 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1024 /* Skip assoc data */
1025 append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
1027 /* Will write cryptlen bytes */
1028 append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1030 /* Store payload data */
1031 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1033 /* Read encrypted data */
1034 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1035 FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1038 append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1039 FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1042 print_hex_dump(KERN_ERR,
1043 "rfc4106 dec shdesc@" __stringify(__LINE__)": ",
1044 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1047 EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
1050 * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
1052 * @desc: pointer to buffer used for descriptor construction
1053 * @cdata: pointer to block cipher transform definitions
1054 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1055 * @ivsize: initialization vector size
1056 * @icvsize: integrity check value (ICV) size (truncated or full)
1057 * @is_qi: true when called from caam/qi
1059 void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
1060 unsigned int ivsize, unsigned int icvsize,
1063 u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1065 init_sh_desc(desc, HDR_SHARE_SERIAL);
1067 /* Skip key loading if it is loaded due to sharing */
1068 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1070 if (cdata->key_inline)
1071 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1072 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1074 append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1075 KEY_DEST_CLASS_REG);
1076 set_jump_tgt_here(desc, key_jump_cmd);
1078 /* Class 1 operation */
1079 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1083 /* assoclen is not needed, skip it */
1084 append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1086 /* Read salt and IV */
1087 append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1088 cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1090 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1091 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1094 /* assoclen + cryptlen = seqinlen */
1095 append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
1098 * MOVE_LEN opcode is not available in all SEC HW revisions,
1099 * thus need to do some magic, i.e. self-patch the descriptor
1102 read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1103 (0x6 << MOVE_LEN_SHIFT));
1104 write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1105 (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1107 /* Will read assoclen + cryptlen bytes */
1108 append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1110 /* Will write assoclen + cryptlen bytes */
1111 append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1113 /* Read and write assoclen + cryptlen bytes */
1114 aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
1116 set_move_tgt_here(desc, read_move_cmd);
1117 set_move_tgt_here(desc, write_move_cmd);
1118 append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1119 /* Move payload data to OFIFO */
1120 append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1123 append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
1124 LDST_SRCDST_BYTE_CONTEXT);
1127 print_hex_dump(KERN_ERR,
1128 "rfc4543 enc shdesc@" __stringify(__LINE__)": ",
1129 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1132 EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
1135 * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
1137 * @desc: pointer to buffer used for descriptor construction
1138 * @cdata: pointer to block cipher transform definitions
1139 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1140 * @ivsize: initialization vector size
1141 * @icvsize: integrity check value (ICV) size (truncated or full)
1142 * @is_qi: true when called from caam/qi
1144 void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
1145 unsigned int ivsize, unsigned int icvsize,
1148 u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1150 init_sh_desc(desc, HDR_SHARE_SERIAL);
1152 /* Skip key loading if it is loaded due to sharing */
1153 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1155 if (cdata->key_inline)
1156 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1157 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1159 append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1160 KEY_DEST_CLASS_REG);
1161 set_jump_tgt_here(desc, key_jump_cmd);
1163 /* Class 1 operation */
1164 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1165 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1168 /* assoclen is not needed, skip it */
1169 append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1171 /* Read salt and IV */
1172 append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1173 cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1175 append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1176 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1179 /* assoclen + cryptlen = seqoutlen */
1180 append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1183 * MOVE_LEN opcode is not available in all SEC HW revisions,
1184 * thus need to do some magic, i.e. self-patch the descriptor
1187 read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1188 (0x6 << MOVE_LEN_SHIFT));
1189 write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1190 (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1192 /* Will read assoclen + cryptlen bytes */
1193 append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1195 /* Will write assoclen + cryptlen bytes */
1196 append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1198 /* Store payload data */
1199 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1201 /* In-snoop assoclen + cryptlen data */
1202 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
1203 FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
1205 set_move_tgt_here(desc, read_move_cmd);
1206 set_move_tgt_here(desc, write_move_cmd);
1207 append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1208 /* Move payload data to OFIFO */
1209 append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1210 append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1213 append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1214 FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1217 print_hex_dump(KERN_ERR,
1218 "rfc4543 dec shdesc@" __stringify(__LINE__)": ",
1219 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1222 EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
1225 * For ablkcipher encrypt and decrypt, read from req->src and
1228 static inline void ablkcipher_append_src_dst(u32 *desc)
1230 append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1231 append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1232 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
1233 KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
1234 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1238 * cnstr_shdsc_ablkcipher_encap - ablkcipher encapsulation shared descriptor
1239 * @desc: pointer to buffer used for descriptor construction
1240 * @cdata: pointer to block cipher transform definitions
1241 * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1242 * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
1243 * @ivsize: initialization vector size
1244 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1245 * @ctx1_iv_off: IV offset in CONTEXT1 register
1247 void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
1248 unsigned int ivsize, const bool is_rfc3686,
1249 const u32 ctx1_iv_off)
1253 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1254 /* Skip if already shared */
1255 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1258 /* Load class1 key only */
1259 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1260 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1262 /* Load nonce into CONTEXT1 reg */
1264 const u8 *nonce = cdata->key_virt + cdata->keylen;
1266 append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1267 LDST_CLASS_IND_CCB |
1268 LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1269 append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1270 MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1271 (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1274 set_jump_tgt_here(desc, key_jump_cmd);
1277 append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1278 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1280 /* Load counter into CONTEXT1 reg */
1282 append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1283 LDST_SRCDST_BYTE_CONTEXT |
1284 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1285 LDST_OFFSET_SHIFT));
1287 /* Load operation */
1288 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1291 /* Perform operation */
1292 ablkcipher_append_src_dst(desc);
1295 print_hex_dump(KERN_ERR,
1296 "ablkcipher enc shdesc@" __stringify(__LINE__)": ",
1297 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1300 EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_encap);
1303 * cnstr_shdsc_ablkcipher_decap - ablkcipher decapsulation shared descriptor
1304 * @desc: pointer to buffer used for descriptor construction
1305 * @cdata: pointer to block cipher transform definitions
1306 * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1307 * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
1308 * @ivsize: initialization vector size
1309 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1310 * @ctx1_iv_off: IV offset in CONTEXT1 register
1312 void cnstr_shdsc_ablkcipher_decap(u32 * const desc, struct alginfo *cdata,
1313 unsigned int ivsize, const bool is_rfc3686,
1314 const u32 ctx1_iv_off)
1318 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1319 /* Skip if already shared */
1320 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1323 /* Load class1 key only */
1324 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1325 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1327 /* Load nonce into CONTEXT1 reg */
1329 const u8 *nonce = cdata->key_virt + cdata->keylen;
1331 append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1332 LDST_CLASS_IND_CCB |
1333 LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1334 append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1335 MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1336 (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1339 set_jump_tgt_here(desc, key_jump_cmd);
1342 append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1343 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1345 /* Load counter into CONTEXT1 reg */
1347 append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1348 LDST_SRCDST_BYTE_CONTEXT |
1349 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1350 LDST_OFFSET_SHIFT));
1352 /* Choose operation */
1354 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1357 append_dec_op1(desc, cdata->algtype);
1359 /* Perform operation */
1360 ablkcipher_append_src_dst(desc);
1363 print_hex_dump(KERN_ERR,
1364 "ablkcipher dec shdesc@" __stringify(__LINE__)": ",
1365 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1368 EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_decap);
1371 * cnstr_shdsc_ablkcipher_givencap - ablkcipher encapsulation shared descriptor
1372 * with HW-generated initialization vector.
1373 * @desc: pointer to buffer used for descriptor construction
1374 * @cdata: pointer to block cipher transform definitions
1375 * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1376 * with OP_ALG_AAI_CBC.
1377 * @ivsize: initialization vector size
1378 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1379 * @ctx1_iv_off: IV offset in CONTEXT1 register
1381 void cnstr_shdsc_ablkcipher_givencap(u32 * const desc, struct alginfo *cdata,
1382 unsigned int ivsize, const bool is_rfc3686,
1383 const u32 ctx1_iv_off)
1385 u32 *key_jump_cmd, geniv;
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 |
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);
1396 /* Load Nonce into CONTEXT1 reg */
1398 const u8 *nonce = cdata->key_virt + cdata->keylen;
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));
1407 set_jump_tgt_here(desc, key_jump_cmd);
1410 geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
1411 NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 | NFIFOENTRY_PTYPE_RND |
1412 (ivsize << NFIFOENTRY_DLEN_SHIFT);
1413 append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
1414 LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
1415 append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1416 append_move(desc, MOVE_WAITCOMP | MOVE_SRC_INFIFO |
1417 MOVE_DEST_CLASS1CTX | (ivsize << MOVE_LEN_SHIFT) |
1418 (ctx1_iv_off << MOVE_OFFSET_SHIFT));
1419 append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1421 /* Copy generated IV to memory */
1422 append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1423 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1425 /* Load Counter into CONTEXT1 reg */
1427 append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1428 LDST_SRCDST_BYTE_CONTEXT |
1429 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1430 LDST_OFFSET_SHIFT));
1433 append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
1434 (1 << JUMP_OFFSET_SHIFT));
1436 /* Load operation */
1437 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1440 /* Perform operation */
1441 ablkcipher_append_src_dst(desc);
1444 print_hex_dump(KERN_ERR,
1445 "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
1446 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1449 EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_givencap);
1452 * cnstr_shdsc_xts_ablkcipher_encap - xts ablkcipher encapsulation shared
1454 * @desc: pointer to buffer used for descriptor construction
1455 * @cdata: pointer to block cipher transform definitions
1456 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1458 void cnstr_shdsc_xts_ablkcipher_encap(u32 * const desc, struct alginfo *cdata)
1461 * Set sector size to a big value, practically disabling
1462 * sector size segmentation in xts implementation. We cannot
1463 * take full advantage of this HW feature with existing
1464 * crypto API / dm-crypt SW architecture.
1466 __be64 sector_size = cpu_to_be64(BIT(15));
1469 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1470 /* Skip if already shared */
1471 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1474 /* Load class1 keys only */
1475 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1476 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1478 /* Load sector size with index 40 bytes (0x28) */
1479 append_load_as_imm(desc, (void *)§or_size, 8, LDST_CLASS_1_CCB |
1480 LDST_SRCDST_BYTE_CONTEXT |
1481 (0x28 << LDST_OFFSET_SHIFT));
1483 set_jump_tgt_here(desc, key_jump_cmd);
1486 * create sequence for loading the sector index
1487 * Upper 8B of IV - will be used as sector index
1488 * Lower 8B of IV - will be discarded
1490 append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1491 (0x20 << LDST_OFFSET_SHIFT));
1492 append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1494 /* Load operation */
1495 append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1498 /* Perform operation */
1499 ablkcipher_append_src_dst(desc);
1502 print_hex_dump(KERN_ERR,
1503 "xts ablkcipher enc shdesc@" __stringify(__LINE__) ": ",
1504 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1507 EXPORT_SYMBOL(cnstr_shdsc_xts_ablkcipher_encap);
1510 * cnstr_shdsc_xts_ablkcipher_decap - xts ablkcipher decapsulation shared
1512 * @desc: pointer to buffer used for descriptor construction
1513 * @cdata: pointer to block cipher transform definitions
1514 * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1516 void cnstr_shdsc_xts_ablkcipher_decap(u32 * const desc, struct alginfo *cdata)
1519 * Set sector size to a big value, practically disabling
1520 * sector size segmentation in xts implementation. We cannot
1521 * take full advantage of this HW feature with existing
1522 * crypto API / dm-crypt SW architecture.
1524 __be64 sector_size = cpu_to_be64(BIT(15));
1527 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1528 /* Skip if already shared */
1529 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1532 /* Load class1 key only */
1533 append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1534 cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1536 /* Load sector size with index 40 bytes (0x28) */
1537 append_load_as_imm(desc, (void *)§or_size, 8, LDST_CLASS_1_CCB |
1538 LDST_SRCDST_BYTE_CONTEXT |
1539 (0x28 << LDST_OFFSET_SHIFT));
1541 set_jump_tgt_here(desc, key_jump_cmd);
1544 * create sequence for loading the sector index
1545 * Upper 8B of IV - will be used as sector index
1546 * Lower 8B of IV - will be discarded
1548 append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1549 (0x20 << LDST_OFFSET_SHIFT));
1550 append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1552 /* Load operation */
1553 append_dec_op1(desc, cdata->algtype);
1555 /* Perform operation */
1556 ablkcipher_append_src_dst(desc);
1559 print_hex_dump(KERN_ERR,
1560 "xts ablkcipher dec shdesc@" __stringify(__LINE__) ": ",
1561 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1564 EXPORT_SYMBOL(cnstr_shdsc_xts_ablkcipher_decap);
1566 MODULE_LICENSE("GPL");
1567 MODULE_DESCRIPTION("FSL CAAM descriptor support");
1568 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");