linux/drivers/crypto/caam/caamalg_desc.c
<<
>>
Prefs
   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 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
 377 * @nonce: pointer to rfc3686 nonce
 378 * @ctx1_iv_off: IV offset in CONTEXT1 register
 379 * @is_qi: true when called from caam/qi
 380 * @era: SEC Era
 381 */
 382void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
 383                            struct alginfo *adata, unsigned int ivsize,
 384                            unsigned int icvsize, const bool geniv,
 385                            const bool is_rfc3686, u32 *nonce,
 386                            const u32 ctx1_iv_off, const bool is_qi, int era)
 387{
 388        /* Note: Context registers are saved. */
 389        init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
 390
 391        /* Class 2 operation */
 392        append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 393                         OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 394
 395        if (is_qi) {
 396                u32 *wait_load_cmd;
 397
 398                /* REG3 = assoclen */
 399                append_seq_load(desc, 4, LDST_CLASS_DECO |
 400                                LDST_SRCDST_WORD_DECO_MATH3 |
 401                                (4 << LDST_OFFSET_SHIFT));
 402
 403                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 404                                            JUMP_COND_CALM | JUMP_COND_NCP |
 405                                            JUMP_COND_NOP | JUMP_COND_NIP |
 406                                            JUMP_COND_NIFP);
 407                set_jump_tgt_here(desc, wait_load_cmd);
 408
 409                if (!geniv)
 410                        append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 411                                        LDST_SRCDST_BYTE_CONTEXT |
 412                                        (ctx1_iv_off << LDST_OFFSET_SHIFT));
 413        }
 414
 415        /* Read and write assoclen bytes */
 416        if (is_qi || era < 3) {
 417                append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 418                if (geniv)
 419                        append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
 420                                                ivsize);
 421                else
 422                        append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
 423                                        CAAM_CMD_SZ);
 424        } else {
 425                append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 426                if (geniv)
 427                        append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
 428                                                ivsize);
 429                else
 430                        append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
 431                                        CAAM_CMD_SZ);
 432        }
 433
 434        /* Skip assoc data */
 435        append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 436
 437        /* read assoc before reading payload */
 438        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
 439                             KEY_VLF);
 440
 441        if (geniv) {
 442                append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 443                                LDST_SRCDST_BYTE_CONTEXT |
 444                                (ctx1_iv_off << LDST_OFFSET_SHIFT));
 445                append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
 446                            (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
 447        }
 448
 449        /* Load Counter into CONTEXT1 reg */
 450        if (is_rfc3686)
 451                append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
 452                                     LDST_SRCDST_BYTE_CONTEXT |
 453                                     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
 454                                      LDST_OFFSET_SHIFT));
 455
 456        /* Choose operation */
 457        if (ctx1_iv_off)
 458                append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 459                                 OP_ALG_DECRYPT);
 460        else
 461                append_dec_op1(desc, cdata->algtype);
 462
 463        /* Read and write cryptlen bytes */
 464        append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 465        append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 466        aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
 467
 468        /* Load ICV */
 469        append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
 470                             FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
 471
 472        print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
 473                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 474                             1);
 475}
 476EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
 477
 478/**
 479 * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
 480 *                             (non-protocol) with HW-generated initialization
 481 *                             vector.
 482 * @desc: pointer to buffer used for descriptor construction
 483 * @cdata: pointer to block cipher transform definitions
 484 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
 485 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
 486 * @adata: pointer to authentication transform definitions.
 487 *         A split key is required for SEC Era < 6; the size of the split key
 488 *         is specified in this case. Valid algorithm values - one of
 489 *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
 490 *         with OP_ALG_AAI_HMAC_PRECOMP.
 491 * @ivsize: initialization vector size
 492 * @icvsize: integrity check value (ICV) size (truncated or full)
 493 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
 494 * @nonce: pointer to rfc3686 nonce
 495 * @ctx1_iv_off: IV offset in CONTEXT1 register
 496 * @is_qi: true when called from caam/qi
 497 * @era: SEC Era
 498 */
 499void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
 500                               struct alginfo *adata, unsigned int ivsize,
 501                               unsigned int icvsize, const bool is_rfc3686,
 502                               u32 *nonce, const u32 ctx1_iv_off,
 503                               const bool is_qi, int era)
 504{
 505        u32 geniv, moveiv;
 506        u32 *wait_cmd;
 507
 508        /* Note: Context registers are saved. */
 509        init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
 510
 511        if (is_qi) {
 512                u32 *wait_load_cmd;
 513
 514                /* REG3 = assoclen */
 515                append_seq_load(desc, 4, LDST_CLASS_DECO |
 516                                LDST_SRCDST_WORD_DECO_MATH3 |
 517                                (4 << LDST_OFFSET_SHIFT));
 518
 519                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 520                                            JUMP_COND_CALM | JUMP_COND_NCP |
 521                                            JUMP_COND_NOP | JUMP_COND_NIP |
 522                                            JUMP_COND_NIFP);
 523                set_jump_tgt_here(desc, wait_load_cmd);
 524        }
 525
 526        if (is_rfc3686) {
 527                if (is_qi)
 528                        append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 529                                        LDST_SRCDST_BYTE_CONTEXT |
 530                                        (ctx1_iv_off << LDST_OFFSET_SHIFT));
 531
 532                goto copy_iv;
 533        }
 534
 535        /* Generate IV */
 536        geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
 537                NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
 538                NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
 539        append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
 540                            LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
 541        append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
 542        append_move(desc, MOVE_WAITCOMP |
 543                    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
 544                    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
 545                    (ivsize << MOVE_LEN_SHIFT));
 546        append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
 547
 548copy_iv:
 549        /* Copy IV to class 1 context */
 550        append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
 551                    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
 552                    (ivsize << MOVE_LEN_SHIFT));
 553
 554        /* Return to encryption */
 555        append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 556                         OP_ALG_ENCRYPT);
 557
 558        /* Read and write assoclen bytes */
 559        if (is_qi || era < 3) {
 560                append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 561                append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 562        } else {
 563                append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 564                append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 565        }
 566
 567        /* Skip assoc data */
 568        append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 569
 570        /* read assoc before reading payload */
 571        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
 572                             KEY_VLF);
 573
 574        /* Copy iv from outfifo to class 2 fifo */
 575        moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
 576                 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
 577        append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
 578                            LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
 579        append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
 580                            LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
 581
 582        /* Load Counter into CONTEXT1 reg */
 583        if (is_rfc3686)
 584                append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
 585                                     LDST_SRCDST_BYTE_CONTEXT |
 586                                     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
 587                                      LDST_OFFSET_SHIFT));
 588
 589        /* Class 1 operation */
 590        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 591                         OP_ALG_ENCRYPT);
 592
 593        /* Will write ivsize + cryptlen */
 594        append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 595
 596        /* Not need to reload iv */
 597        append_seq_fifo_load(desc, ivsize,
 598                             FIFOLD_CLASS_SKIP);
 599
 600        /* Will read cryptlen */
 601        append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 602
 603        /*
 604         * Wait for IV transfer (ofifo -> class2) to finish before starting
 605         * ciphertext transfer (ofifo -> external memory).
 606         */
 607        wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
 608        set_jump_tgt_here(desc, wait_cmd);
 609
 610        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
 611                             FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
 612        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
 613
 614        /* Write ICV */
 615        append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
 616                         LDST_SRCDST_BYTE_CONTEXT);
 617
 618        print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
 619                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 620                             1);
 621}
 622EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
 623
 624/**
 625 * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
 626 * @desc: pointer to buffer used for descriptor construction
 627 * @cdata: pointer to block cipher transform definitions
 628 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 629 * @ivsize: initialization vector size
 630 * @icvsize: integrity check value (ICV) size (truncated or full)
 631 * @is_qi: true when called from caam/qi
 632 */
 633void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
 634                           unsigned int ivsize, unsigned int icvsize,
 635                           const bool is_qi)
 636{
 637        u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
 638            *zero_assoc_jump_cmd2;
 639
 640        init_sh_desc(desc, HDR_SHARE_SERIAL);
 641
 642        /* skip key loading if they are loaded due to sharing */
 643        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 644                                   JUMP_COND_SHRD);
 645        if (cdata->key_inline)
 646                append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 647                                  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 648        else
 649                append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 650                           KEY_DEST_CLASS_REG);
 651        set_jump_tgt_here(desc, key_jump_cmd);
 652
 653        /* class 1 operation */
 654        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 655                         OP_ALG_ENCRYPT);
 656
 657        if (is_qi) {
 658                u32 *wait_load_cmd;
 659
 660                /* REG3 = assoclen */
 661                append_seq_load(desc, 4, LDST_CLASS_DECO |
 662                                LDST_SRCDST_WORD_DECO_MATH3 |
 663                                (4 << LDST_OFFSET_SHIFT));
 664
 665                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 666                                            JUMP_COND_CALM | JUMP_COND_NCP |
 667                                            JUMP_COND_NOP | JUMP_COND_NIP |
 668                                            JUMP_COND_NIFP);
 669                set_jump_tgt_here(desc, wait_load_cmd);
 670
 671                append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
 672                                        ivsize);
 673        } else {
 674                append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
 675                                CAAM_CMD_SZ);
 676        }
 677
 678        /* if assoclen + cryptlen is ZERO, skip to ICV write */
 679        zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
 680                                                 JUMP_COND_MATH_Z);
 681
 682        if (is_qi)
 683                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 684                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
 685
 686        /* if assoclen is ZERO, skip reading the assoc data */
 687        append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 688        zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
 689                                           JUMP_COND_MATH_Z);
 690
 691        append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 692
 693        /* skip assoc data */
 694        append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 695
 696        /* cryptlen = seqinlen - assoclen */
 697        append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
 698
 699        /* if cryptlen is ZERO jump to zero-payload commands */
 700        zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
 701                                            JUMP_COND_MATH_Z);
 702
 703        /* read assoc data */
 704        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 705                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
 706        set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
 707
 708        append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 709
 710        /* write encrypted data */
 711        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
 712
 713        /* read payload data */
 714        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 715                             FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
 716
 717        /* jump to ICV writing */
 718        if (is_qi)
 719                append_jump(desc, JUMP_TEST_ALL | 4);
 720        else
 721                append_jump(desc, JUMP_TEST_ALL | 2);
 722
 723        /* zero-payload commands */
 724        set_jump_tgt_here(desc, zero_payload_jump_cmd);
 725
 726        /* read assoc data */
 727        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 728                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
 729        if (is_qi)
 730                /* jump to ICV writing */
 731                append_jump(desc, JUMP_TEST_ALL | 2);
 732
 733        /* There is no input data */
 734        set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
 735
 736        if (is_qi)
 737                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 738                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
 739                                     FIFOLD_TYPE_LAST1);
 740
 741        /* write ICV */
 742        append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
 743                         LDST_SRCDST_BYTE_CONTEXT);
 744
 745        print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
 746                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 747                             1);
 748}
 749EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
 750
 751/**
 752 * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
 753 * @desc: pointer to buffer used for descriptor construction
 754 * @cdata: pointer to block cipher transform definitions
 755 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 756 * @ivsize: initialization vector size
 757 * @icvsize: integrity check value (ICV) size (truncated or full)
 758 * @is_qi: true when called from caam/qi
 759 */
 760void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
 761                           unsigned int ivsize, unsigned int icvsize,
 762                           const bool is_qi)
 763{
 764        u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
 765
 766        init_sh_desc(desc, HDR_SHARE_SERIAL);
 767
 768        /* skip key loading if they are loaded due to sharing */
 769        key_jump_cmd = append_jump(desc, JUMP_JSL |
 770                                   JUMP_TEST_ALL | JUMP_COND_SHRD);
 771        if (cdata->key_inline)
 772                append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 773                                  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 774        else
 775                append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 776                           KEY_DEST_CLASS_REG);
 777        set_jump_tgt_here(desc, key_jump_cmd);
 778
 779        /* class 1 operation */
 780        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 781                         OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 782
 783        if (is_qi) {
 784                u32 *wait_load_cmd;
 785
 786                /* REG3 = assoclen */
 787                append_seq_load(desc, 4, LDST_CLASS_DECO |
 788                                LDST_SRCDST_WORD_DECO_MATH3 |
 789                                (4 << LDST_OFFSET_SHIFT));
 790
 791                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 792                                            JUMP_COND_CALM | JUMP_COND_NCP |
 793                                            JUMP_COND_NOP | JUMP_COND_NIP |
 794                                            JUMP_COND_NIFP);
 795                set_jump_tgt_here(desc, wait_load_cmd);
 796
 797                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 798                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
 799        }
 800
 801        /* if assoclen is ZERO, skip reading the assoc data */
 802        append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 803        zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
 804                                                 JUMP_COND_MATH_Z);
 805
 806        append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 807
 808        /* skip assoc data */
 809        append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 810
 811        /* read assoc data */
 812        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 813                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
 814
 815        set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
 816
 817        /* cryptlen = seqoutlen - assoclen */
 818        append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 819
 820        /* jump to zero-payload command if cryptlen is zero */
 821        zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
 822                                            JUMP_COND_MATH_Z);
 823
 824        append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 825
 826        /* store encrypted data */
 827        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
 828
 829        /* read payload data */
 830        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 831                             FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
 832
 833        /* zero-payload command */
 834        set_jump_tgt_here(desc, zero_payload_jump_cmd);
 835
 836        /* read ICV */
 837        append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
 838                             FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
 839
 840        print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
 841                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 842                             1);
 843}
 844EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
 845
 846/**
 847 * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
 848 *                             (non-protocol).
 849 * @desc: pointer to buffer used for descriptor construction
 850 * @cdata: pointer to block cipher transform definitions
 851 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 852 * @ivsize: initialization vector size
 853 * @icvsize: integrity check value (ICV) size (truncated or full)
 854 * @is_qi: true when called from caam/qi
 855 *
 856 * Input sequence: AAD | PTXT
 857 * Output sequence: AAD | CTXT | ICV
 858 * AAD length (assoclen), which includes the IV length, is available in Math3.
 859 */
 860void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
 861                               unsigned int ivsize, unsigned int icvsize,
 862                               const bool is_qi)
 863{
 864        u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
 865        init_sh_desc(desc, HDR_SHARE_SERIAL);
 866
 867        /* Skip key loading if it is loaded due to sharing */
 868        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 869                                   JUMP_COND_SHRD);
 870        if (cdata->key_inline)
 871                append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 872                                  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 873        else
 874                append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 875                           KEY_DEST_CLASS_REG);
 876        set_jump_tgt_here(desc, key_jump_cmd);
 877
 878        /* Class 1 operation */
 879        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 880                         OP_ALG_ENCRYPT);
 881
 882        if (is_qi) {
 883                u32 *wait_load_cmd;
 884
 885                /* REG3 = assoclen */
 886                append_seq_load(desc, 4, LDST_CLASS_DECO |
 887                                LDST_SRCDST_WORD_DECO_MATH3 |
 888                                (4 << LDST_OFFSET_SHIFT));
 889
 890                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 891                                            JUMP_COND_CALM | JUMP_COND_NCP |
 892                                            JUMP_COND_NOP | JUMP_COND_NIP |
 893                                            JUMP_COND_NIFP);
 894                set_jump_tgt_here(desc, wait_load_cmd);
 895
 896                /* Read salt and IV */
 897                append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
 898                                        cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
 899                                        FIFOLD_TYPE_IV);
 900                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 901                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
 902        }
 903
 904        append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
 905        append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 906
 907        /* Skip AAD */
 908        append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 909
 910        /* Read cryptlen and set this value into VARSEQOUTLEN */
 911        append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
 912
 913        /* If cryptlen is ZERO jump to AAD command */
 914        zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
 915                                            JUMP_COND_MATH_Z);
 916
 917        /* Read AAD data */
 918        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 919                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
 920
 921        /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
 922        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
 923
 924        /* Skip IV */
 925        append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
 926        append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
 927
 928        /* Write encrypted data */
 929        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
 930
 931        /* Read payload data */
 932        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 933                             FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
 934
 935        /* Jump instructions to avoid double reading of AAD */
 936        skip_instructions = append_jump(desc, JUMP_TEST_ALL);
 937
 938        /* There is no input data, cryptlen = 0 */
 939        set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
 940
 941        /* Read AAD */
 942        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 943                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
 944
 945        set_jump_tgt_here(desc, skip_instructions);
 946
 947        /* Write ICV */
 948        append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
 949                         LDST_SRCDST_BYTE_CONTEXT);
 950
 951        print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
 952                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 953                             1);
 954}
 955EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
 956
 957/**
 958 * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
 959 *                             (non-protocol).
 960 * @desc: pointer to buffer used for descriptor construction
 961 * @cdata: pointer to block cipher transform definitions
 962 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 963 * @ivsize: initialization vector size
 964 * @icvsize: integrity check value (ICV) size (truncated or full)
 965 * @is_qi: true when called from caam/qi
 966 */
 967void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
 968                               unsigned int ivsize, unsigned int icvsize,
 969                               const bool is_qi)
 970{
 971        u32 *key_jump_cmd;
 972
 973        init_sh_desc(desc, HDR_SHARE_SERIAL);
 974
 975        /* Skip key loading if it is loaded due to sharing */
 976        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 977                                   JUMP_COND_SHRD);
 978        if (cdata->key_inline)
 979                append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 980                                  cdata->keylen, CLASS_1 |
 981                                  KEY_DEST_CLASS_REG);
 982        else
 983                append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 984                           KEY_DEST_CLASS_REG);
 985        set_jump_tgt_here(desc, key_jump_cmd);
 986
 987        /* Class 1 operation */
 988        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 989                         OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 990
 991        if (is_qi) {
 992                u32 *wait_load_cmd;
 993
 994                /* REG3 = assoclen */
 995                append_seq_load(desc, 4, LDST_CLASS_DECO |
 996                                LDST_SRCDST_WORD_DECO_MATH3 |
 997                                (4 << LDST_OFFSET_SHIFT));
 998
 999                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1000                                            JUMP_COND_CALM | JUMP_COND_NCP |
1001                                            JUMP_COND_NOP | JUMP_COND_NIP |
1002                                            JUMP_COND_NIFP);
1003                set_jump_tgt_here(desc, wait_load_cmd);
1004
1005                /* Read salt and IV */
1006                append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1007                                        cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1008                                        FIFOLD_TYPE_IV);
1009                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1010                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1011        }
1012
1013        append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
1014        append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1015
1016        /* Read assoc data */
1017        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1018                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1019
1020        /* Skip IV */
1021        append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
1022
1023        /* Will read cryptlen bytes */
1024        append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1025
1026        /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
1027        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1028
1029        /* Skip assoc data */
1030        append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
1031
1032        /* Will write cryptlen bytes */
1033        append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1034
1035        /* Store payload data */
1036        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1037
1038        /* Read encrypted data */
1039        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1040                             FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1041
1042        /* Read ICV */
1043        append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1044                             FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1045
1046        print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
1047                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1048                             1);
1049}
1050EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
1051
1052/**
1053 * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
1054 *                             (non-protocol).
1055 * @desc: pointer to buffer used for descriptor construction
1056 * @cdata: pointer to block cipher transform definitions
1057 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1058 * @ivsize: initialization vector size
1059 * @icvsize: integrity check value (ICV) size (truncated or full)
1060 * @is_qi: true when called from caam/qi
1061 */
1062void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
1063                               unsigned int ivsize, unsigned int icvsize,
1064                               const bool is_qi)
1065{
1066        u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1067
1068        init_sh_desc(desc, HDR_SHARE_SERIAL);
1069
1070        /* Skip key loading if it is loaded due to sharing */
1071        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1072                                   JUMP_COND_SHRD);
1073        if (cdata->key_inline)
1074                append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1075                                  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1076        else
1077                append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1078                           KEY_DEST_CLASS_REG);
1079        set_jump_tgt_here(desc, key_jump_cmd);
1080
1081        /* Class 1 operation */
1082        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1083                         OP_ALG_ENCRYPT);
1084
1085        if (is_qi) {
1086                /* assoclen is not needed, skip it */
1087                append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1088
1089                /* Read salt and IV */
1090                append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1091                                        cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1092                                        FIFOLD_TYPE_IV);
1093                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1094                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1095        }
1096
1097        /* assoclen + cryptlen = seqinlen */
1098        append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
1099
1100        /*
1101         * MOVE_LEN opcode is not available in all SEC HW revisions,
1102         * thus need to do some magic, i.e. self-patch the descriptor
1103         * buffer.
1104         */
1105        read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1106                                    (0x6 << MOVE_LEN_SHIFT));
1107        write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1108                                     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1109
1110        /* Will read assoclen + cryptlen bytes */
1111        append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1112
1113        /* Will write assoclen + cryptlen bytes */
1114        append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1115
1116        /* Read and write assoclen + cryptlen bytes */
1117        aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
1118
1119        set_move_tgt_here(desc, read_move_cmd);
1120        set_move_tgt_here(desc, write_move_cmd);
1121        append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1122        /* Move payload data to OFIFO */
1123        append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1124
1125        /* Write ICV */
1126        append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
1127                         LDST_SRCDST_BYTE_CONTEXT);
1128
1129        print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
1130                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1131                             1);
1132}
1133EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
1134
1135/**
1136 * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
1137 *                             (non-protocol).
1138 * @desc: pointer to buffer used for descriptor construction
1139 * @cdata: pointer to block cipher transform definitions
1140 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1141 * @ivsize: initialization vector size
1142 * @icvsize: integrity check value (ICV) size (truncated or full)
1143 * @is_qi: true when called from caam/qi
1144 */
1145void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
1146                               unsigned int ivsize, unsigned int icvsize,
1147                               const bool is_qi)
1148{
1149        u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1150
1151        init_sh_desc(desc, HDR_SHARE_SERIAL);
1152
1153        /* Skip key loading if it is loaded due to sharing */
1154        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1155                                   JUMP_COND_SHRD);
1156        if (cdata->key_inline)
1157                append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1158                                  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1159        else
1160                append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1161                           KEY_DEST_CLASS_REG);
1162        set_jump_tgt_here(desc, key_jump_cmd);
1163
1164        /* Class 1 operation */
1165        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1166                         OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1167
1168        if (is_qi) {
1169                /* assoclen is not needed, skip it */
1170                append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1171
1172                /* Read salt and IV */
1173                append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1174                                        cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1175                                        FIFOLD_TYPE_IV);
1176                append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1177                                     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1178        }
1179
1180        /* assoclen + cryptlen = seqoutlen */
1181        append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1182
1183        /*
1184         * MOVE_LEN opcode is not available in all SEC HW revisions,
1185         * thus need to do some magic, i.e. self-patch the descriptor
1186         * buffer.
1187         */
1188        read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1189                                    (0x6 << MOVE_LEN_SHIFT));
1190        write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1191                                     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1192
1193        /* Will read assoclen + cryptlen bytes */
1194        append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1195
1196        /* Will write assoclen + cryptlen bytes */
1197        append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1198
1199        /* Store payload data */
1200        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1201
1202        /* In-snoop assoclen + cryptlen data */
1203        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
1204                             FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
1205
1206        set_move_tgt_here(desc, read_move_cmd);
1207        set_move_tgt_here(desc, write_move_cmd);
1208        append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1209        /* Move payload data to OFIFO */
1210        append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1211        append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1212
1213        /* Read ICV */
1214        append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1215                             FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1216
1217        print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
1218                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1219                             1);
1220}
1221EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
1222
1223/**
1224 * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
1225 *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
1226 *                          descriptor (non-protocol).
1227 * @desc: pointer to buffer used for descriptor construction
1228 * @cdata: pointer to block cipher transform definitions
1229 *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
1230 *         OP_ALG_AAI_AEAD.
1231 * @adata: pointer to authentication transform definitions
1232 *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
1233 *         OP_ALG_AAI_AEAD.
1234 * @ivsize: initialization vector size
1235 * @icvsize: integrity check value (ICV) size (truncated or full)
1236 * @encap: true if encapsulation, false if decapsulation
1237 * @is_qi: true when called from caam/qi
1238 */
1239void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
1240                            struct alginfo *adata, unsigned int ivsize,
1241                            unsigned int icvsize, const bool encap,
1242                            const bool is_qi)
1243{
1244        u32 *key_jump_cmd, *wait_cmd;
1245        u32 nfifo;
1246        const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
1247
1248        /* Note: Context registers are saved. */
1249        init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1250
1251        /* skip key loading if they are loaded due to sharing */
1252        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1253                                   JUMP_COND_SHRD);
1254
1255        append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
1256                          CLASS_1 | KEY_DEST_CLASS_REG);
1257
1258        /* For IPsec load the salt from keymat in the context register */
1259        if (is_ipsec)
1260                append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
1261                                   LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
1262                                   4 << LDST_OFFSET_SHIFT);
1263
1264        set_jump_tgt_here(desc, key_jump_cmd);
1265
1266        /* Class 2 and 1 operations: Poly & ChaCha */
1267        if (encap) {
1268                append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1269                                 OP_ALG_ENCRYPT);
1270                append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1271                                 OP_ALG_ENCRYPT);
1272        } else {
1273                append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1274                                 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1275                append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1276                                 OP_ALG_DECRYPT);
1277        }
1278
1279        if (is_qi) {
1280                u32 *wait_load_cmd;
1281                u32 ctx1_iv_off = is_ipsec ? 8 : 4;
1282
1283                /* REG3 = assoclen */
1284                append_seq_load(desc, 4, LDST_CLASS_DECO |
1285                                LDST_SRCDST_WORD_DECO_MATH3 |
1286                                4 << LDST_OFFSET_SHIFT);
1287
1288                wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1289                                            JUMP_COND_CALM | JUMP_COND_NCP |
1290                                            JUMP_COND_NOP | JUMP_COND_NIP |
1291                                            JUMP_COND_NIFP);
1292                set_jump_tgt_here(desc, wait_load_cmd);
1293
1294                append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
1295                                LDST_SRCDST_BYTE_CONTEXT |
1296                                ctx1_iv_off << LDST_OFFSET_SHIFT);
1297        }
1298
1299        /*
1300         * MAGIC with NFIFO
1301         * Read associated data from the input and send them to class1 and
1302         * class2 alignment blocks. From class1 send data to output fifo and
1303         * then write it to memory since we don't need to encrypt AD.
1304         */
1305        nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
1306                NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
1307        append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
1308                            LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
1309
1310        append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
1311        append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1312        append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
1313                             FIFOLD_CLASS_CLASS1 | LDST_VLF);
1314        append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
1315                        MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
1316        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
1317
1318        /* IPsec - copy IV at the output */
1319        if (is_ipsec)
1320                append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
1321                                      0x2 << 25);
1322
1323        wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
1324                               JUMP_COND_NOP | JUMP_TEST_ALL);
1325        set_jump_tgt_here(desc, wait_cmd);
1326
1327        if (encap) {
1328                /* Read and write cryptlen bytes */
1329                append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1330                append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
1331                                CAAM_CMD_SZ);
1332                aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
1333
1334                /* Write ICV */
1335                append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
1336                                 LDST_SRCDST_BYTE_CONTEXT);
1337        } else {
1338                /* Read and write cryptlen bytes */
1339                append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
1340                                CAAM_CMD_SZ);
1341                append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
1342                                CAAM_CMD_SZ);
1343                aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
1344
1345                /* Load ICV for verification */
1346                append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
1347                                     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
1348        }
1349
1350        print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
1351                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1352                             1);
1353}
1354EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
1355
1356/* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
1357static inline void skcipher_append_src_dst(u32 *desc)
1358{
1359        append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1360        append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1361        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
1362                             KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
1363        append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1364}
1365
1366/**
1367 * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
1368 * @desc: pointer to buffer used for descriptor construction
1369 * @cdata: pointer to block cipher transform definitions
1370 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1371 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1372 *                                - OP_ALG_ALGSEL_CHACHA20
1373 * @ivsize: initialization vector size
1374 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1375 * @ctx1_iv_off: IV offset in CONTEXT1 register
1376 */
1377void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
1378                                unsigned int ivsize, const bool is_rfc3686,
1379                                const u32 ctx1_iv_off)
1380{
1381        u32 *key_jump_cmd;
1382        u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
1383        bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1384                            OP_ALG_ALGSEL_CHACHA20);
1385
1386        init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1387        /* Skip if already shared */
1388        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1389                                   JUMP_COND_SHRD);
1390
1391        /* Load class1 key only */
1392        append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1393                          cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1394
1395        /* Load nonce into CONTEXT1 reg */
1396        if (is_rfc3686) {
1397                const u8 *nonce = cdata->key_virt + cdata->keylen;
1398
1399                append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1400                                   LDST_CLASS_IND_CCB |
1401                                   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1402                append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1403                            MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1404                            (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1405        }
1406
1407        set_jump_tgt_here(desc, key_jump_cmd);
1408
1409        /* Load IV, if there is one */
1410        if (ivsize)
1411                append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1412                                LDST_CLASS_1_CCB | (ctx1_iv_off <<
1413                                LDST_OFFSET_SHIFT));
1414
1415        /* Load counter into CONTEXT1 reg */
1416        if (is_rfc3686)
1417                append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1418                                     LDST_SRCDST_BYTE_CONTEXT |
1419                                     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1420                                      LDST_OFFSET_SHIFT));
1421
1422        /* Load operation */
1423        if (is_chacha20)
1424                options |= OP_ALG_AS_FINALIZE;
1425        append_operation(desc, options);
1426
1427        /* Perform operation */
1428        skcipher_append_src_dst(desc);
1429
1430        /* Store IV */
1431        if (!is_chacha20 && ivsize)
1432                append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1433                                 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1434                                 LDST_OFFSET_SHIFT));
1435
1436        print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
1437                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1438                             1);
1439}
1440EXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
1441
1442/**
1443 * cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
1444 * @desc: pointer to buffer used for descriptor construction
1445 * @cdata: pointer to block cipher transform definitions
1446 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1447 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1448 *                                - OP_ALG_ALGSEL_CHACHA20
1449 * @ivsize: initialization vector size
1450 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1451 * @ctx1_iv_off: IV offset in CONTEXT1 register
1452 */
1453void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
1454                                unsigned int ivsize, const bool is_rfc3686,
1455                                const u32 ctx1_iv_off)
1456{
1457        u32 *key_jump_cmd;
1458        bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1459                            OP_ALG_ALGSEL_CHACHA20);
1460
1461        init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1462        /* Skip if already shared */
1463        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1464                                   JUMP_COND_SHRD);
1465
1466        /* Load class1 key only */
1467        append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1468                          cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1469
1470        /* Load nonce into CONTEXT1 reg */
1471        if (is_rfc3686) {
1472                const u8 *nonce = cdata->key_virt + cdata->keylen;
1473
1474                append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1475                                   LDST_CLASS_IND_CCB |
1476                                   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1477                append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1478                            MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1479                            (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1480        }
1481
1482        set_jump_tgt_here(desc, key_jump_cmd);
1483
1484        /* Load IV, if there is one */
1485        if (ivsize)
1486                append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1487                                LDST_CLASS_1_CCB | (ctx1_iv_off <<
1488                                LDST_OFFSET_SHIFT));
1489
1490        /* Load counter into CONTEXT1 reg */
1491        if (is_rfc3686)
1492                append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1493                                     LDST_SRCDST_BYTE_CONTEXT |
1494                                     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1495                                      LDST_OFFSET_SHIFT));
1496
1497        /* Choose operation */
1498        if (ctx1_iv_off)
1499                append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
1500                                 OP_ALG_DECRYPT);
1501        else
1502                append_dec_op1(desc, cdata->algtype);
1503
1504        /* Perform operation */
1505        skcipher_append_src_dst(desc);
1506
1507        /* Store IV */
1508        if (!is_chacha20 && ivsize)
1509                append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1510                                 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1511                                 LDST_OFFSET_SHIFT));
1512
1513        print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
1514                             DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1515                             1);
1516}
1517EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
1518
1519/**
1520 * cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
1521 * @desc: pointer to buffer used for descriptor construction
1522 * @cdata: pointer to block cipher transform definitions
1523 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1524 */
1525void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
1526{
1527        /*
1528         * Set sector size to a big value, practically disabling
1529         * sector size segmentation in xts implementation. We cannot
1530         * take full advantage of this HW feature with existing
1531         * crypto API / dm-crypt SW architecture.
1532         */
1533        __be64 sector_size = cpu_to_be64(BIT(15));
1534        u32 *key_jump_cmd;
1535
1536        init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1537        /* Skip if already shared */
1538        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1539                                   JUMP_COND_SHRD);
1540
1541        /* Load class1 keys only */
1542        append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1543                          cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1544
1545        /* Load sector size with index 40 bytes (0x28) */
1546        append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1547                           LDST_SRCDST_BYTE_CONTEXT |
1548                           (0x28 << LDST_OFFSET_SHIFT));
1549
1550        set_jump_tgt_here(desc, key_jump_cmd);
1551
1552        /*
1553         * create sequence for loading the sector index
1554         * Upper 8B of IV - will be used as sector index
1555         * Lower 8B of IV - will be discarded
1556         */
1557        append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1558                        (0x20 << LDST_OFFSET_SHIFT));
1559        append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1560
1561        /* Load operation */
1562        append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1563                         OP_ALG_ENCRYPT);
1564
1565        /* Perform operation */
1566        skcipher_append_src_dst(desc);
1567
1568        /* Store upper 8B of IV */
1569        append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1570                         (0x20 << LDST_OFFSET_SHIFT));
1571
1572        print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
1573                             ": ", DUMP_PREFIX_ADDRESS, 16, 4,
1574                             desc, desc_bytes(desc), 1);
1575}
1576EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
1577
1578/**
1579 * cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
1580 * @desc: pointer to buffer used for descriptor construction
1581 * @cdata: pointer to block cipher transform definitions
1582 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1583 */
1584void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
1585{
1586        /*
1587         * Set sector size to a big value, practically disabling
1588         * sector size segmentation in xts implementation. We cannot
1589         * take full advantage of this HW feature with existing
1590         * crypto API / dm-crypt SW architecture.
1591         */
1592        __be64 sector_size = cpu_to_be64(BIT(15));
1593        u32 *key_jump_cmd;
1594
1595        init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1596        /* Skip if already shared */
1597        key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1598                                   JUMP_COND_SHRD);
1599
1600        /* Load class1 key only */
1601        append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1602                          cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1603
1604        /* Load sector size with index 40 bytes (0x28) */
1605        append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1606                           LDST_SRCDST_BYTE_CONTEXT |
1607                           (0x28 << LDST_OFFSET_SHIFT));
1608
1609        set_jump_tgt_here(desc, key_jump_cmd);
1610
1611        /*
1612         * create sequence for loading the sector index
1613         * Upper 8B of IV - will be used as sector index
1614         * Lower 8B of IV - will be discarded
1615         */
1616        append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1617                        (0x20 << LDST_OFFSET_SHIFT));
1618        append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1619
1620        /* Load operation */
1621        append_dec_op1(desc, cdata->algtype);
1622
1623        /* Perform operation */
1624        skcipher_append_src_dst(desc);
1625
1626        /* Store upper 8B of IV */
1627        append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1628                         (0x20 << LDST_OFFSET_SHIFT));
1629
1630        print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
1631                             ": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
1632                             desc_bytes(desc), 1);
1633}
1634EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
1635
1636MODULE_LICENSE("GPL");
1637MODULE_DESCRIPTION("FSL CAAM descriptor support");
1638MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
1639