caamalg_desc.c (56457B)
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 */ 16static 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 */ 24static 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 */ 56void 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} 121EXPORT_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 */ 135void 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} 208EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap); 209 210static 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 */ 288void 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} 360EXPORT_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 */ 383void 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} 477EXPORT_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 */ 500void 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 549copy_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} 623EXPORT_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 */ 634void 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} 750EXPORT_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 */ 761void 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} 845EXPORT_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 */ 861void 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} 956EXPORT_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 */ 968void 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} 1051EXPORT_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 */ 1063void 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} 1134EXPORT_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 */ 1146void 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} 1222EXPORT_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 */ 1240void 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} 1355EXPORT_SYMBOL(cnstr_shdsc_chachapoly); 1356 1357/* For skcipher encrypt and decrypt, read from req->src and write to req->dst */ 1358static 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 */ 1378void 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} 1441EXPORT_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 */ 1454void 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} 1518EXPORT_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 */ 1526void 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 *)§or_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} 1580EXPORT_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 */ 1588void 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 *)§or_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} 1640EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap); 1641 1642MODULE_LICENSE("GPL"); 1643MODULE_DESCRIPTION("FSL CAAM descriptor support"); 1644MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");