18e8ec596SKim Phillips /* 28e8ec596SKim Phillips * caam - Freescale FSL CAAM support for crypto API 38e8ec596SKim Phillips * 48e8ec596SKim Phillips * Copyright 2008-2011 Freescale Semiconductor, Inc. 58e8ec596SKim Phillips * 68e8ec596SKim Phillips * Based on talitos crypto API driver. 78e8ec596SKim Phillips * 88e8ec596SKim Phillips * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008): 98e8ec596SKim Phillips * 108e8ec596SKim Phillips * --------------- --------------- 118e8ec596SKim Phillips * | JobDesc #1 |-------------------->| ShareDesc | 128e8ec596SKim Phillips * | *(packet 1) | | (PDB) | 138e8ec596SKim Phillips * --------------- |------------->| (hashKey) | 148e8ec596SKim Phillips * . | | (cipherKey) | 158e8ec596SKim Phillips * . | |-------->| (operation) | 168e8ec596SKim Phillips * --------------- | | --------------- 178e8ec596SKim Phillips * | JobDesc #2 |------| | 188e8ec596SKim Phillips * | *(packet 2) | | 198e8ec596SKim Phillips * --------------- | 208e8ec596SKim Phillips * . | 218e8ec596SKim Phillips * . | 228e8ec596SKim Phillips * --------------- | 238e8ec596SKim Phillips * | JobDesc #3 |------------ 248e8ec596SKim Phillips * | *(packet 3) | 258e8ec596SKim Phillips * --------------- 268e8ec596SKim Phillips * 278e8ec596SKim Phillips * The SharedDesc never changes for a connection unless rekeyed, but 288e8ec596SKim Phillips * each packet will likely be in a different place. So all we need 298e8ec596SKim Phillips * to know to process the packet is where the input is, where the 308e8ec596SKim Phillips * output goes, and what context we want to process with. Context is 318e8ec596SKim Phillips * in the SharedDesc, packet references in the JobDesc. 328e8ec596SKim Phillips * 338e8ec596SKim Phillips * So, a job desc looks like: 348e8ec596SKim Phillips * 358e8ec596SKim Phillips * --------------------- 368e8ec596SKim Phillips * | Header | 378e8ec596SKim Phillips * | ShareDesc Pointer | 388e8ec596SKim Phillips * | SEQ_OUT_PTR | 398e8ec596SKim Phillips * | (output buffer) | 406ec47334SYuan Kang * | (output length) | 418e8ec596SKim Phillips * | SEQ_IN_PTR | 428e8ec596SKim Phillips * | (input buffer) | 436ec47334SYuan Kang * | (input length) | 448e8ec596SKim Phillips * --------------------- 458e8ec596SKim Phillips */ 468e8ec596SKim Phillips 478e8ec596SKim Phillips #include "compat.h" 488e8ec596SKim Phillips 498e8ec596SKim Phillips #include "regs.h" 508e8ec596SKim Phillips #include "intern.h" 518e8ec596SKim Phillips #include "desc_constr.h" 528e8ec596SKim Phillips #include "jr.h" 538e8ec596SKim Phillips #include "error.h" 54a299c837SYuan Kang #include "sg_sw_sec4.h" 554c1ec1f9SYuan Kang #include "key_gen.h" 568e8ec596SKim Phillips 578e8ec596SKim Phillips /* 588e8ec596SKim Phillips * crypto alg 598e8ec596SKim Phillips */ 608e8ec596SKim Phillips #define CAAM_CRA_PRIORITY 3000 618e8ec596SKim Phillips /* max key is sum of AES_MAX_KEY_SIZE, max split key size */ 628e8ec596SKim Phillips #define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + \ 638e8ec596SKim Phillips SHA512_DIGEST_SIZE * 2) 648e8ec596SKim Phillips /* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ 658e8ec596SKim Phillips #define CAAM_MAX_IV_LENGTH 16 668e8ec596SKim Phillips 674427b1b4SKim Phillips /* length of descriptors text */ 681acebad3SYuan Kang #define DESC_AEAD_BASE (4 * CAAM_CMD_SZ) 694464a7d4SHoria Geanta #define DESC_AEAD_ENC_LEN (DESC_AEAD_BASE + 15 * CAAM_CMD_SZ) 704464a7d4SHoria Geanta #define DESC_AEAD_DEC_LEN (DESC_AEAD_BASE + 18 * CAAM_CMD_SZ) 711acebad3SYuan Kang #define DESC_AEAD_GIVENC_LEN (DESC_AEAD_ENC_LEN + 7 * CAAM_CMD_SZ) 721acebad3SYuan Kang 73ae4a825fSHoria Geanta #define DESC_AEAD_NULL_BASE (3 * CAAM_CMD_SZ) 74ae4a825fSHoria Geanta #define DESC_AEAD_NULL_ENC_LEN (DESC_AEAD_NULL_BASE + 14 * CAAM_CMD_SZ) 75ae4a825fSHoria Geanta #define DESC_AEAD_NULL_DEC_LEN (DESC_AEAD_NULL_BASE + 17 * CAAM_CMD_SZ) 76ae4a825fSHoria Geanta 77acdca31dSYuan Kang #define DESC_ABLKCIPHER_BASE (3 * CAAM_CMD_SZ) 78acdca31dSYuan Kang #define DESC_ABLKCIPHER_ENC_LEN (DESC_ABLKCIPHER_BASE + \ 79acdca31dSYuan Kang 20 * CAAM_CMD_SZ) 80acdca31dSYuan Kang #define DESC_ABLKCIPHER_DEC_LEN (DESC_ABLKCIPHER_BASE + \ 81acdca31dSYuan Kang 15 * CAAM_CMD_SZ) 82acdca31dSYuan Kang 831acebad3SYuan Kang #define DESC_MAX_USED_BYTES (DESC_AEAD_GIVENC_LEN + \ 841acebad3SYuan Kang CAAM_MAX_KEY_SIZE) 851acebad3SYuan Kang #define DESC_MAX_USED_LEN (DESC_MAX_USED_BYTES / CAAM_CMD_SZ) 864427b1b4SKim Phillips 878e8ec596SKim Phillips #ifdef DEBUG 888e8ec596SKim Phillips /* for print_hex_dumps with line references */ 898e8ec596SKim Phillips #define debug(format, arg...) printk(format, arg) 908e8ec596SKim Phillips #else 918e8ec596SKim Phillips #define debug(format, arg...) 928e8ec596SKim Phillips #endif 93cfc6f11bSRuchika Gupta static struct list_head alg_list; 948e8ec596SKim Phillips 951acebad3SYuan Kang /* Set DK bit in class 1 operation if shared */ 961acebad3SYuan Kang static inline void append_dec_op1(u32 *desc, u32 type) 971acebad3SYuan Kang { 981acebad3SYuan Kang u32 *jump_cmd, *uncond_jump_cmd; 991acebad3SYuan Kang 1001acebad3SYuan Kang jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD); 1011acebad3SYuan Kang append_operation(desc, type | OP_ALG_AS_INITFINAL | 1021acebad3SYuan Kang OP_ALG_DECRYPT); 1031acebad3SYuan Kang uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL); 1041acebad3SYuan Kang set_jump_tgt_here(desc, jump_cmd); 1051acebad3SYuan Kang append_operation(desc, type | OP_ALG_AS_INITFINAL | 1061acebad3SYuan Kang OP_ALG_DECRYPT | OP_ALG_AAI_DK); 1071acebad3SYuan Kang set_jump_tgt_here(desc, uncond_jump_cmd); 1081acebad3SYuan Kang } 1091acebad3SYuan Kang 1101acebad3SYuan Kang /* 1111acebad3SYuan Kang * For aead functions, read payload and write payload, 1121acebad3SYuan Kang * both of which are specified in req->src and req->dst 1131acebad3SYuan Kang */ 1141acebad3SYuan Kang static inline void aead_append_src_dst(u32 *desc, u32 msg_type) 1151acebad3SYuan Kang { 116ae4a825fSHoria Geanta append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); 1171acebad3SYuan Kang append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | 1181acebad3SYuan Kang KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH); 1191acebad3SYuan Kang } 1201acebad3SYuan Kang 1211acebad3SYuan Kang /* 1221acebad3SYuan Kang * For aead encrypt and decrypt, read iv for both classes 1231acebad3SYuan Kang */ 1241acebad3SYuan Kang static inline void aead_append_ld_iv(u32 *desc, int ivsize) 1251acebad3SYuan Kang { 1261acebad3SYuan Kang append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT | 1271acebad3SYuan Kang LDST_CLASS_1_CCB | ivsize); 1281acebad3SYuan Kang append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ivsize); 1291acebad3SYuan Kang } 1301acebad3SYuan Kang 1311acebad3SYuan Kang /* 132acdca31dSYuan Kang * For ablkcipher encrypt and decrypt, read from req->src and 133acdca31dSYuan Kang * write to req->dst 134acdca31dSYuan Kang */ 135acdca31dSYuan Kang static inline void ablkcipher_append_src_dst(u32 *desc) 136acdca31dSYuan Kang { 13770d793ccSKim Phillips append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 13870d793ccSKim Phillips append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 13970d793ccSKim Phillips append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | 14070d793ccSKim Phillips KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1); 14170d793ccSKim Phillips append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); 142acdca31dSYuan Kang } 143acdca31dSYuan Kang 144acdca31dSYuan Kang /* 1451acebad3SYuan Kang * If all data, including src (with assoc and iv) or dst (with iv only) are 1461acebad3SYuan Kang * contiguous 1471acebad3SYuan Kang */ 1481acebad3SYuan Kang #define GIV_SRC_CONTIG 1 1491acebad3SYuan Kang #define GIV_DST_CONTIG (1 << 1) 1501acebad3SYuan Kang 1518e8ec596SKim Phillips /* 1528e8ec596SKim Phillips * per-session context 1538e8ec596SKim Phillips */ 1548e8ec596SKim Phillips struct caam_ctx { 1558e8ec596SKim Phillips struct device *jrdev; 1561acebad3SYuan Kang u32 sh_desc_enc[DESC_MAX_USED_LEN]; 1571acebad3SYuan Kang u32 sh_desc_dec[DESC_MAX_USED_LEN]; 1581acebad3SYuan Kang u32 sh_desc_givenc[DESC_MAX_USED_LEN]; 1591acebad3SYuan Kang dma_addr_t sh_desc_enc_dma; 1601acebad3SYuan Kang dma_addr_t sh_desc_dec_dma; 1611acebad3SYuan Kang dma_addr_t sh_desc_givenc_dma; 1628e8ec596SKim Phillips u32 class1_alg_type; 1638e8ec596SKim Phillips u32 class2_alg_type; 1648e8ec596SKim Phillips u32 alg_op; 1651acebad3SYuan Kang u8 key[CAAM_MAX_KEY_SIZE]; 166885e9e2fSYuan Kang dma_addr_t key_dma; 1678e8ec596SKim Phillips unsigned int enckeylen; 1688e8ec596SKim Phillips unsigned int split_key_len; 1698e8ec596SKim Phillips unsigned int split_key_pad_len; 1708e8ec596SKim Phillips unsigned int authsize; 1718e8ec596SKim Phillips }; 1728e8ec596SKim Phillips 1731acebad3SYuan Kang static void append_key_aead(u32 *desc, struct caam_ctx *ctx, 1741acebad3SYuan Kang int keys_fit_inline) 1751acebad3SYuan Kang { 1761acebad3SYuan Kang if (keys_fit_inline) { 1771acebad3SYuan Kang append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len, 1781acebad3SYuan Kang ctx->split_key_len, CLASS_2 | 1791acebad3SYuan Kang KEY_DEST_MDHA_SPLIT | KEY_ENC); 1801acebad3SYuan Kang append_key_as_imm(desc, (void *)ctx->key + 1811acebad3SYuan Kang ctx->split_key_pad_len, ctx->enckeylen, 1821acebad3SYuan Kang ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); 1831acebad3SYuan Kang } else { 1841acebad3SYuan Kang append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 | 1851acebad3SYuan Kang KEY_DEST_MDHA_SPLIT | KEY_ENC); 1861acebad3SYuan Kang append_key(desc, ctx->key_dma + ctx->split_key_pad_len, 1871acebad3SYuan Kang ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); 1881acebad3SYuan Kang } 1891acebad3SYuan Kang } 1901acebad3SYuan Kang 1911acebad3SYuan Kang static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx, 1921acebad3SYuan Kang int keys_fit_inline) 1931acebad3SYuan Kang { 1941acebad3SYuan Kang u32 *key_jump_cmd; 1951acebad3SYuan Kang 19661bb86bbSKim Phillips init_sh_desc(desc, HDR_SHARE_SERIAL); 1971acebad3SYuan Kang 1981acebad3SYuan Kang /* Skip if already shared */ 1991acebad3SYuan Kang key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 2001acebad3SYuan Kang JUMP_COND_SHRD); 2011acebad3SYuan Kang 2021acebad3SYuan Kang append_key_aead(desc, ctx, keys_fit_inline); 2031acebad3SYuan Kang 2041acebad3SYuan Kang set_jump_tgt_here(desc, key_jump_cmd); 2051acebad3SYuan Kang } 2061acebad3SYuan Kang 207ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead) 208ae4a825fSHoria Geanta { 209ae4a825fSHoria Geanta struct aead_tfm *tfm = &aead->base.crt_aead; 210ae4a825fSHoria Geanta struct caam_ctx *ctx = crypto_aead_ctx(aead); 211ae4a825fSHoria Geanta struct device *jrdev = ctx->jrdev; 212ae4a825fSHoria Geanta bool keys_fit_inline = false; 213ae4a825fSHoria Geanta u32 *key_jump_cmd, *jump_cmd, *read_move_cmd, *write_move_cmd; 214ae4a825fSHoria Geanta u32 *desc; 215ae4a825fSHoria Geanta 216ae4a825fSHoria Geanta /* 217ae4a825fSHoria Geanta * Job Descriptor and Shared Descriptors 218ae4a825fSHoria Geanta * must all fit into the 64-word Descriptor h/w Buffer 219ae4a825fSHoria Geanta */ 220ae4a825fSHoria Geanta if (DESC_AEAD_NULL_ENC_LEN + DESC_JOB_IO_LEN + 221ae4a825fSHoria Geanta ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX) 222ae4a825fSHoria Geanta keys_fit_inline = true; 223ae4a825fSHoria Geanta 224ae4a825fSHoria Geanta /* aead_encrypt shared descriptor */ 225ae4a825fSHoria Geanta desc = ctx->sh_desc_enc; 226ae4a825fSHoria Geanta 227ae4a825fSHoria Geanta init_sh_desc(desc, HDR_SHARE_SERIAL); 228ae4a825fSHoria Geanta 229ae4a825fSHoria Geanta /* Skip if already shared */ 230ae4a825fSHoria Geanta key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 231ae4a825fSHoria Geanta JUMP_COND_SHRD); 232ae4a825fSHoria Geanta if (keys_fit_inline) 233ae4a825fSHoria Geanta append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len, 234ae4a825fSHoria Geanta ctx->split_key_len, CLASS_2 | 235ae4a825fSHoria Geanta KEY_DEST_MDHA_SPLIT | KEY_ENC); 236ae4a825fSHoria Geanta else 237ae4a825fSHoria Geanta append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 | 238ae4a825fSHoria Geanta KEY_DEST_MDHA_SPLIT | KEY_ENC); 239ae4a825fSHoria Geanta set_jump_tgt_here(desc, key_jump_cmd); 240ae4a825fSHoria Geanta 241ae4a825fSHoria Geanta /* cryptlen = seqoutlen - authsize */ 242ae4a825fSHoria Geanta append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); 243ae4a825fSHoria Geanta 244ae4a825fSHoria Geanta /* 245ae4a825fSHoria Geanta * NULL encryption; IV is zero 246ae4a825fSHoria Geanta * assoclen = (assoclen + cryptlen) - cryptlen 247ae4a825fSHoria Geanta */ 248ae4a825fSHoria Geanta append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ); 249ae4a825fSHoria Geanta 250ae4a825fSHoria Geanta /* read assoc before reading payload */ 251ae4a825fSHoria Geanta append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | 252ae4a825fSHoria Geanta KEY_VLF); 253ae4a825fSHoria Geanta 254ae4a825fSHoria Geanta /* Prepare to read and write cryptlen bytes */ 255ae4a825fSHoria Geanta append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); 256ae4a825fSHoria Geanta append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); 257ae4a825fSHoria Geanta 258ae4a825fSHoria Geanta /* 259ae4a825fSHoria Geanta * MOVE_LEN opcode is not available in all SEC HW revisions, 260ae4a825fSHoria Geanta * thus need to do some magic, i.e. self-patch the descriptor 261ae4a825fSHoria Geanta * buffer. 262ae4a825fSHoria Geanta */ 263ae4a825fSHoria Geanta read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | 264ae4a825fSHoria Geanta MOVE_DEST_MATH3 | 265ae4a825fSHoria Geanta (0x6 << MOVE_LEN_SHIFT)); 266ae4a825fSHoria Geanta write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | 267ae4a825fSHoria Geanta MOVE_DEST_DESCBUF | 268ae4a825fSHoria Geanta MOVE_WAITCOMP | 269ae4a825fSHoria Geanta (0x8 << MOVE_LEN_SHIFT)); 270ae4a825fSHoria Geanta 271ae4a825fSHoria Geanta /* Class 2 operation */ 272ae4a825fSHoria Geanta append_operation(desc, ctx->class2_alg_type | 273ae4a825fSHoria Geanta OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 274ae4a825fSHoria Geanta 275ae4a825fSHoria Geanta /* Read and write cryptlen bytes */ 276ae4a825fSHoria Geanta aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1); 277ae4a825fSHoria Geanta 278ae4a825fSHoria Geanta set_move_tgt_here(desc, read_move_cmd); 279ae4a825fSHoria Geanta set_move_tgt_here(desc, write_move_cmd); 280ae4a825fSHoria Geanta append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); 281ae4a825fSHoria Geanta append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO | 282ae4a825fSHoria Geanta MOVE_AUX_LS); 283ae4a825fSHoria Geanta 284ae4a825fSHoria Geanta /* Write ICV */ 285ae4a825fSHoria Geanta append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB | 286ae4a825fSHoria Geanta LDST_SRCDST_BYTE_CONTEXT); 287ae4a825fSHoria Geanta 288ae4a825fSHoria Geanta ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, 289ae4a825fSHoria Geanta desc_bytes(desc), 290ae4a825fSHoria Geanta DMA_TO_DEVICE); 291ae4a825fSHoria Geanta if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { 292ae4a825fSHoria Geanta dev_err(jrdev, "unable to map shared descriptor\n"); 293ae4a825fSHoria Geanta return -ENOMEM; 294ae4a825fSHoria Geanta } 295ae4a825fSHoria Geanta #ifdef DEBUG 296ae4a825fSHoria Geanta print_hex_dump(KERN_ERR, 297ae4a825fSHoria Geanta "aead null enc shdesc@"__stringify(__LINE__)": ", 298ae4a825fSHoria Geanta DUMP_PREFIX_ADDRESS, 16, 4, desc, 299ae4a825fSHoria Geanta desc_bytes(desc), 1); 300ae4a825fSHoria Geanta #endif 301ae4a825fSHoria Geanta 302ae4a825fSHoria Geanta /* 303ae4a825fSHoria Geanta * Job Descriptor and Shared Descriptors 304ae4a825fSHoria Geanta * must all fit into the 64-word Descriptor h/w Buffer 305ae4a825fSHoria Geanta */ 30680cd88f2SVakul Garg keys_fit_inline = false; 307ae4a825fSHoria Geanta if (DESC_AEAD_NULL_DEC_LEN + DESC_JOB_IO_LEN + 308ae4a825fSHoria Geanta ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX) 309ae4a825fSHoria Geanta keys_fit_inline = true; 310ae4a825fSHoria Geanta 311ae4a825fSHoria Geanta desc = ctx->sh_desc_dec; 312ae4a825fSHoria Geanta 313ae4a825fSHoria Geanta /* aead_decrypt shared descriptor */ 314ae4a825fSHoria Geanta init_sh_desc(desc, HDR_SHARE_SERIAL); 315ae4a825fSHoria Geanta 316ae4a825fSHoria Geanta /* Skip if already shared */ 317ae4a825fSHoria Geanta key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 318ae4a825fSHoria Geanta JUMP_COND_SHRD); 319ae4a825fSHoria Geanta if (keys_fit_inline) 320ae4a825fSHoria Geanta append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len, 321ae4a825fSHoria Geanta ctx->split_key_len, CLASS_2 | 322ae4a825fSHoria Geanta KEY_DEST_MDHA_SPLIT | KEY_ENC); 323ae4a825fSHoria Geanta else 324ae4a825fSHoria Geanta append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 | 325ae4a825fSHoria Geanta KEY_DEST_MDHA_SPLIT | KEY_ENC); 326ae4a825fSHoria Geanta set_jump_tgt_here(desc, key_jump_cmd); 327ae4a825fSHoria Geanta 328ae4a825fSHoria Geanta /* Class 2 operation */ 329ae4a825fSHoria Geanta append_operation(desc, ctx->class2_alg_type | 330ae4a825fSHoria Geanta OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON); 331ae4a825fSHoria Geanta 332ae4a825fSHoria Geanta /* assoclen + cryptlen = seqinlen - ivsize - authsize */ 333ae4a825fSHoria Geanta append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, 334ae4a825fSHoria Geanta ctx->authsize + tfm->ivsize); 335ae4a825fSHoria Geanta /* assoclen = (assoclen + cryptlen) - cryptlen */ 336ae4a825fSHoria Geanta append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ); 337ae4a825fSHoria Geanta append_math_sub(desc, VARSEQINLEN, REG3, REG2, CAAM_CMD_SZ); 338ae4a825fSHoria Geanta 339ae4a825fSHoria Geanta /* read assoc before reading payload */ 340ae4a825fSHoria Geanta append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | 341ae4a825fSHoria Geanta KEY_VLF); 342ae4a825fSHoria Geanta 343ae4a825fSHoria Geanta /* Prepare to read and write cryptlen bytes */ 344ae4a825fSHoria Geanta append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ); 345ae4a825fSHoria Geanta append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ); 346ae4a825fSHoria Geanta 347ae4a825fSHoria Geanta /* 348ae4a825fSHoria Geanta * MOVE_LEN opcode is not available in all SEC HW revisions, 349ae4a825fSHoria Geanta * thus need to do some magic, i.e. self-patch the descriptor 350ae4a825fSHoria Geanta * buffer. 351ae4a825fSHoria Geanta */ 352ae4a825fSHoria Geanta read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | 353ae4a825fSHoria Geanta MOVE_DEST_MATH2 | 354ae4a825fSHoria Geanta (0x6 << MOVE_LEN_SHIFT)); 355ae4a825fSHoria Geanta write_move_cmd = append_move(desc, MOVE_SRC_MATH2 | 356ae4a825fSHoria Geanta MOVE_DEST_DESCBUF | 357ae4a825fSHoria Geanta MOVE_WAITCOMP | 358ae4a825fSHoria Geanta (0x8 << MOVE_LEN_SHIFT)); 359ae4a825fSHoria Geanta 360ae4a825fSHoria Geanta /* Read and write cryptlen bytes */ 361ae4a825fSHoria Geanta aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1); 362ae4a825fSHoria Geanta 363ae4a825fSHoria Geanta /* 364ae4a825fSHoria Geanta * Insert a NOP here, since we need at least 4 instructions between 365ae4a825fSHoria Geanta * code patching the descriptor buffer and the location being patched. 366ae4a825fSHoria Geanta */ 367ae4a825fSHoria Geanta jump_cmd = append_jump(desc, JUMP_TEST_ALL); 368ae4a825fSHoria Geanta set_jump_tgt_here(desc, jump_cmd); 369ae4a825fSHoria Geanta 370ae4a825fSHoria Geanta set_move_tgt_here(desc, read_move_cmd); 371ae4a825fSHoria Geanta set_move_tgt_here(desc, write_move_cmd); 372ae4a825fSHoria Geanta append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); 373ae4a825fSHoria Geanta append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO | 374ae4a825fSHoria Geanta MOVE_AUX_LS); 375ae4a825fSHoria Geanta append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); 376ae4a825fSHoria Geanta 377ae4a825fSHoria Geanta /* Load ICV */ 378ae4a825fSHoria Geanta append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 | 379ae4a825fSHoria Geanta FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV); 380ae4a825fSHoria Geanta 381ae4a825fSHoria Geanta ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, 382ae4a825fSHoria Geanta desc_bytes(desc), 383ae4a825fSHoria Geanta DMA_TO_DEVICE); 384ae4a825fSHoria Geanta if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) { 385ae4a825fSHoria Geanta dev_err(jrdev, "unable to map shared descriptor\n"); 386ae4a825fSHoria Geanta return -ENOMEM; 387ae4a825fSHoria Geanta } 388ae4a825fSHoria Geanta #ifdef DEBUG 389ae4a825fSHoria Geanta print_hex_dump(KERN_ERR, 390ae4a825fSHoria Geanta "aead null dec shdesc@"__stringify(__LINE__)": ", 391ae4a825fSHoria Geanta DUMP_PREFIX_ADDRESS, 16, 4, desc, 392ae4a825fSHoria Geanta desc_bytes(desc), 1); 393ae4a825fSHoria Geanta #endif 394ae4a825fSHoria Geanta 395ae4a825fSHoria Geanta return 0; 396ae4a825fSHoria Geanta } 397ae4a825fSHoria Geanta 3981acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead) 3991acebad3SYuan Kang { 4001acebad3SYuan Kang struct aead_tfm *tfm = &aead->base.crt_aead; 4011acebad3SYuan Kang struct caam_ctx *ctx = crypto_aead_ctx(aead); 4021acebad3SYuan Kang struct device *jrdev = ctx->jrdev; 4032af8f4a2SKim Phillips bool keys_fit_inline = false; 4041acebad3SYuan Kang u32 geniv, moveiv; 4051acebad3SYuan Kang u32 *desc; 4061acebad3SYuan Kang 407ae4a825fSHoria Geanta if (!ctx->authsize) 4081acebad3SYuan Kang return 0; 4091acebad3SYuan Kang 410ae4a825fSHoria Geanta /* NULL encryption / decryption */ 411ae4a825fSHoria Geanta if (!ctx->enckeylen) 412ae4a825fSHoria Geanta return aead_null_set_sh_desc(aead); 413ae4a825fSHoria Geanta 4141acebad3SYuan Kang /* 4151acebad3SYuan Kang * Job Descriptor and Shared Descriptors 4161acebad3SYuan Kang * must all fit into the 64-word Descriptor h/w Buffer 4171acebad3SYuan Kang */ 4181acebad3SYuan Kang if (DESC_AEAD_ENC_LEN + DESC_JOB_IO_LEN + 4191acebad3SYuan Kang ctx->split_key_pad_len + ctx->enckeylen <= 4201acebad3SYuan Kang CAAM_DESC_BYTES_MAX) 4212af8f4a2SKim Phillips keys_fit_inline = true; 4221acebad3SYuan Kang 4231acebad3SYuan Kang /* aead_encrypt shared descriptor */ 4241acebad3SYuan Kang desc = ctx->sh_desc_enc; 4251acebad3SYuan Kang 4261acebad3SYuan Kang init_sh_desc_key_aead(desc, ctx, keys_fit_inline); 4271acebad3SYuan Kang 4281acebad3SYuan Kang /* Class 2 operation */ 4291acebad3SYuan Kang append_operation(desc, ctx->class2_alg_type | 4301acebad3SYuan Kang OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 4311acebad3SYuan Kang 4321acebad3SYuan Kang /* cryptlen = seqoutlen - authsize */ 4331acebad3SYuan Kang append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); 4341acebad3SYuan Kang 4351acebad3SYuan Kang /* assoclen + cryptlen = seqinlen - ivsize */ 4361acebad3SYuan Kang append_math_sub_imm_u32(desc, REG2, SEQINLEN, IMM, tfm->ivsize); 4371acebad3SYuan Kang 4384464a7d4SHoria Geanta /* assoclen = (assoclen + cryptlen) - cryptlen */ 4391acebad3SYuan Kang append_math_sub(desc, VARSEQINLEN, REG2, REG3, CAAM_CMD_SZ); 4401acebad3SYuan Kang 4411acebad3SYuan Kang /* read assoc before reading payload */ 4421acebad3SYuan Kang append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | 4431acebad3SYuan Kang KEY_VLF); 4441acebad3SYuan Kang aead_append_ld_iv(desc, tfm->ivsize); 4451acebad3SYuan Kang 4461acebad3SYuan Kang /* Class 1 operation */ 4471acebad3SYuan Kang append_operation(desc, ctx->class1_alg_type | 4481acebad3SYuan Kang OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 4491acebad3SYuan Kang 4501acebad3SYuan Kang /* Read and write cryptlen bytes */ 4511acebad3SYuan Kang append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); 4521acebad3SYuan Kang append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); 4531acebad3SYuan Kang aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2); 4541acebad3SYuan Kang 4551acebad3SYuan Kang /* Write ICV */ 4561acebad3SYuan Kang append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB | 4571acebad3SYuan Kang LDST_SRCDST_BYTE_CONTEXT); 4581acebad3SYuan Kang 4591acebad3SYuan Kang ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, 4601acebad3SYuan Kang desc_bytes(desc), 4611acebad3SYuan Kang DMA_TO_DEVICE); 4621acebad3SYuan Kang if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { 4631acebad3SYuan Kang dev_err(jrdev, "unable to map shared descriptor\n"); 4641acebad3SYuan Kang return -ENOMEM; 4651acebad3SYuan Kang } 4661acebad3SYuan Kang #ifdef DEBUG 467514df281SAlex Porosanu print_hex_dump(KERN_ERR, "aead enc shdesc@"__stringify(__LINE__)": ", 4681acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, desc, 4691acebad3SYuan Kang desc_bytes(desc), 1); 4701acebad3SYuan Kang #endif 4711acebad3SYuan Kang 4721acebad3SYuan Kang /* 4731acebad3SYuan Kang * Job Descriptor and Shared Descriptors 4741acebad3SYuan Kang * must all fit into the 64-word Descriptor h/w Buffer 4751acebad3SYuan Kang */ 47680cd88f2SVakul Garg keys_fit_inline = false; 4771acebad3SYuan Kang if (DESC_AEAD_DEC_LEN + DESC_JOB_IO_LEN + 4781acebad3SYuan Kang ctx->split_key_pad_len + ctx->enckeylen <= 4791acebad3SYuan Kang CAAM_DESC_BYTES_MAX) 4802af8f4a2SKim Phillips keys_fit_inline = true; 4811acebad3SYuan Kang 4824464a7d4SHoria Geanta /* aead_decrypt shared descriptor */ 4831acebad3SYuan Kang desc = ctx->sh_desc_dec; 4841acebad3SYuan Kang 4854464a7d4SHoria Geanta init_sh_desc_key_aead(desc, ctx, keys_fit_inline); 4861acebad3SYuan Kang 4871acebad3SYuan Kang /* Class 2 operation */ 4881acebad3SYuan Kang append_operation(desc, ctx->class2_alg_type | 4891acebad3SYuan Kang OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON); 4901acebad3SYuan Kang 4914464a7d4SHoria Geanta /* assoclen + cryptlen = seqinlen - ivsize - authsize */ 4921acebad3SYuan Kang append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, 493ae4a825fSHoria Geanta ctx->authsize + tfm->ivsize); 4941acebad3SYuan Kang /* assoclen = (assoclen + cryptlen) - cryptlen */ 4951acebad3SYuan Kang append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ); 4961acebad3SYuan Kang append_math_sub(desc, VARSEQINLEN, REG3, REG2, CAAM_CMD_SZ); 4971acebad3SYuan Kang 4981acebad3SYuan Kang /* read assoc before reading payload */ 4991acebad3SYuan Kang append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | 5001acebad3SYuan Kang KEY_VLF); 5011acebad3SYuan Kang 5021acebad3SYuan Kang aead_append_ld_iv(desc, tfm->ivsize); 5031acebad3SYuan Kang 5041acebad3SYuan Kang append_dec_op1(desc, ctx->class1_alg_type); 5051acebad3SYuan Kang 5061acebad3SYuan Kang /* Read and write cryptlen bytes */ 5071acebad3SYuan Kang append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ); 5081acebad3SYuan Kang append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ); 5091acebad3SYuan Kang aead_append_src_dst(desc, FIFOLD_TYPE_MSG); 5101acebad3SYuan Kang 5111acebad3SYuan Kang /* Load ICV */ 5121acebad3SYuan Kang append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 | 5131acebad3SYuan Kang FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV); 5141acebad3SYuan Kang 5151acebad3SYuan Kang ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, 5161acebad3SYuan Kang desc_bytes(desc), 5171acebad3SYuan Kang DMA_TO_DEVICE); 5181acebad3SYuan Kang if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) { 5191acebad3SYuan Kang dev_err(jrdev, "unable to map shared descriptor\n"); 5201acebad3SYuan Kang return -ENOMEM; 5211acebad3SYuan Kang } 5221acebad3SYuan Kang #ifdef DEBUG 523514df281SAlex Porosanu print_hex_dump(KERN_ERR, "aead dec shdesc@"__stringify(__LINE__)": ", 5241acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, desc, 5251acebad3SYuan Kang desc_bytes(desc), 1); 5261acebad3SYuan Kang #endif 5271acebad3SYuan Kang 5281acebad3SYuan Kang /* 5291acebad3SYuan Kang * Job Descriptor and Shared Descriptors 5301acebad3SYuan Kang * must all fit into the 64-word Descriptor h/w Buffer 5311acebad3SYuan Kang */ 53280cd88f2SVakul Garg keys_fit_inline = false; 5331acebad3SYuan Kang if (DESC_AEAD_GIVENC_LEN + DESC_JOB_IO_LEN + 5341acebad3SYuan Kang ctx->split_key_pad_len + ctx->enckeylen <= 5351acebad3SYuan Kang CAAM_DESC_BYTES_MAX) 5362af8f4a2SKim Phillips keys_fit_inline = true; 5371acebad3SYuan Kang 5381acebad3SYuan Kang /* aead_givencrypt shared descriptor */ 5391acebad3SYuan Kang desc = ctx->sh_desc_givenc; 5401acebad3SYuan Kang 5411acebad3SYuan Kang init_sh_desc_key_aead(desc, ctx, keys_fit_inline); 5421acebad3SYuan Kang 5431acebad3SYuan Kang /* Generate IV */ 5441acebad3SYuan Kang geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO | 5451acebad3SYuan Kang NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 | 5461acebad3SYuan Kang NFIFOENTRY_PTYPE_RND | (tfm->ivsize << NFIFOENTRY_DLEN_SHIFT); 5471acebad3SYuan Kang append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB | 5481acebad3SYuan Kang LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM); 5491acebad3SYuan Kang append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); 5501acebad3SYuan Kang append_move(desc, MOVE_SRC_INFIFO | 5511acebad3SYuan Kang MOVE_DEST_CLASS1CTX | (tfm->ivsize << MOVE_LEN_SHIFT)); 5521acebad3SYuan Kang append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); 5531acebad3SYuan Kang 5541acebad3SYuan Kang /* Copy IV to class 1 context */ 5551acebad3SYuan Kang append_move(desc, MOVE_SRC_CLASS1CTX | 5561acebad3SYuan Kang MOVE_DEST_OUTFIFO | (tfm->ivsize << MOVE_LEN_SHIFT)); 5571acebad3SYuan Kang 5581acebad3SYuan Kang /* Return to encryption */ 5591acebad3SYuan Kang append_operation(desc, ctx->class2_alg_type | 5601acebad3SYuan Kang OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 5611acebad3SYuan Kang 5621acebad3SYuan Kang /* ivsize + cryptlen = seqoutlen - authsize */ 5631acebad3SYuan Kang append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); 5641acebad3SYuan Kang 5651acebad3SYuan Kang /* assoclen = seqinlen - (ivsize + cryptlen) */ 5661acebad3SYuan Kang append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ); 5671acebad3SYuan Kang 5681acebad3SYuan Kang /* read assoc before reading payload */ 5691acebad3SYuan Kang append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | 5701acebad3SYuan Kang KEY_VLF); 5711acebad3SYuan Kang 5721acebad3SYuan Kang /* Copy iv from class 1 ctx to class 2 fifo*/ 5731acebad3SYuan Kang moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 | 5741acebad3SYuan Kang NFIFOENTRY_DTYPE_MSG | (tfm->ivsize << NFIFOENTRY_DLEN_SHIFT); 5751acebad3SYuan Kang append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB | 5761acebad3SYuan Kang LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM); 5771acebad3SYuan Kang append_load_imm_u32(desc, tfm->ivsize, LDST_CLASS_2_CCB | 5781acebad3SYuan Kang LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM); 5791acebad3SYuan Kang 5801acebad3SYuan Kang /* Class 1 operation */ 5811acebad3SYuan Kang append_operation(desc, ctx->class1_alg_type | 5821acebad3SYuan Kang OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 5831acebad3SYuan Kang 5841acebad3SYuan Kang /* Will write ivsize + cryptlen */ 5851acebad3SYuan Kang append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 5861acebad3SYuan Kang 5871acebad3SYuan Kang /* Not need to reload iv */ 5881acebad3SYuan Kang append_seq_fifo_load(desc, tfm->ivsize, 5891acebad3SYuan Kang FIFOLD_CLASS_SKIP); 5901acebad3SYuan Kang 5911acebad3SYuan Kang /* Will read cryptlen */ 5921acebad3SYuan Kang append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 5931acebad3SYuan Kang aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2); 5941acebad3SYuan Kang 5951acebad3SYuan Kang /* Write ICV */ 5961acebad3SYuan Kang append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB | 5971acebad3SYuan Kang LDST_SRCDST_BYTE_CONTEXT); 5981acebad3SYuan Kang 5991acebad3SYuan Kang ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc, 6001acebad3SYuan Kang desc_bytes(desc), 6011acebad3SYuan Kang DMA_TO_DEVICE); 6021acebad3SYuan Kang if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) { 6031acebad3SYuan Kang dev_err(jrdev, "unable to map shared descriptor\n"); 6041acebad3SYuan Kang return -ENOMEM; 6051acebad3SYuan Kang } 6061acebad3SYuan Kang #ifdef DEBUG 607514df281SAlex Porosanu print_hex_dump(KERN_ERR, "aead givenc shdesc@"__stringify(__LINE__)": ", 6081acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, desc, 6091acebad3SYuan Kang desc_bytes(desc), 1); 6101acebad3SYuan Kang #endif 6111acebad3SYuan Kang 6121acebad3SYuan Kang return 0; 6131acebad3SYuan Kang } 6141acebad3SYuan Kang 6150e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc, 6168e8ec596SKim Phillips unsigned int authsize) 6178e8ec596SKim Phillips { 6188e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(authenc); 6198e8ec596SKim Phillips 6208e8ec596SKim Phillips ctx->authsize = authsize; 6211acebad3SYuan Kang aead_set_sh_desc(authenc); 6228e8ec596SKim Phillips 6238e8ec596SKim Phillips return 0; 6248e8ec596SKim Phillips } 6258e8ec596SKim Phillips 6264c1ec1f9SYuan Kang static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in, 6274c1ec1f9SYuan Kang u32 authkeylen) 6288e8ec596SKim Phillips { 6294c1ec1f9SYuan Kang return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len, 6304c1ec1f9SYuan Kang ctx->split_key_pad_len, key_in, authkeylen, 6314c1ec1f9SYuan Kang ctx->alg_op); 6328e8ec596SKim Phillips } 6338e8ec596SKim Phillips 6340e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead, 6358e8ec596SKim Phillips const u8 *key, unsigned int keylen) 6368e8ec596SKim Phillips { 6378e8ec596SKim Phillips /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */ 6388e8ec596SKim Phillips static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; 6398e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 6408e8ec596SKim Phillips struct device *jrdev = ctx->jrdev; 6414e6e0b27SHoria Geanta struct crypto_authenc_keys keys; 6428e8ec596SKim Phillips int ret = 0; 6438e8ec596SKim Phillips 6444e6e0b27SHoria Geanta if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) 6458e8ec596SKim Phillips goto badkey; 6468e8ec596SKim Phillips 6478e8ec596SKim Phillips /* Pick class 2 key length from algorithm submask */ 6488e8ec596SKim Phillips ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> 6498e8ec596SKim Phillips OP_ALG_ALGSEL_SHIFT] * 2; 6508e8ec596SKim Phillips ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16); 6518e8ec596SKim Phillips 6524e6e0b27SHoria Geanta if (ctx->split_key_pad_len + keys.enckeylen > CAAM_MAX_KEY_SIZE) 6534e6e0b27SHoria Geanta goto badkey; 6544e6e0b27SHoria Geanta 6558e8ec596SKim Phillips #ifdef DEBUG 6568e8ec596SKim Phillips printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n", 6574e6e0b27SHoria Geanta keys.authkeylen + keys.enckeylen, keys.enckeylen, 6584e6e0b27SHoria Geanta keys.authkeylen); 6598e8ec596SKim Phillips printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n", 6608e8ec596SKim Phillips ctx->split_key_len, ctx->split_key_pad_len); 661514df281SAlex Porosanu print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", 6628e8ec596SKim Phillips DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 6638e8ec596SKim Phillips #endif 6648e8ec596SKim Phillips 6654e6e0b27SHoria Geanta ret = gen_split_aead_key(ctx, keys.authkey, keys.authkeylen); 6668e8ec596SKim Phillips if (ret) { 6678e8ec596SKim Phillips goto badkey; 6688e8ec596SKim Phillips } 6698e8ec596SKim Phillips 6708e8ec596SKim Phillips /* postpend encryption key to auth split key */ 6714e6e0b27SHoria Geanta memcpy(ctx->key + ctx->split_key_pad_len, keys.enckey, keys.enckeylen); 6728e8ec596SKim Phillips 673885e9e2fSYuan Kang ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len + 6744e6e0b27SHoria Geanta keys.enckeylen, DMA_TO_DEVICE); 675885e9e2fSYuan Kang if (dma_mapping_error(jrdev, ctx->key_dma)) { 6768e8ec596SKim Phillips dev_err(jrdev, "unable to map key i/o memory\n"); 6778e8ec596SKim Phillips return -ENOMEM; 6788e8ec596SKim Phillips } 6798e8ec596SKim Phillips #ifdef DEBUG 680514df281SAlex Porosanu print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ", 6818e8ec596SKim Phillips DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, 6824e6e0b27SHoria Geanta ctx->split_key_pad_len + keys.enckeylen, 1); 6838e8ec596SKim Phillips #endif 6848e8ec596SKim Phillips 6854e6e0b27SHoria Geanta ctx->enckeylen = keys.enckeylen; 6868e8ec596SKim Phillips 6871acebad3SYuan Kang ret = aead_set_sh_desc(aead); 6888e8ec596SKim Phillips if (ret) { 689885e9e2fSYuan Kang dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len + 6904e6e0b27SHoria Geanta keys.enckeylen, DMA_TO_DEVICE); 6918e8ec596SKim Phillips } 6928e8ec596SKim Phillips 6938e8ec596SKim Phillips return ret; 6948e8ec596SKim Phillips badkey: 6958e8ec596SKim Phillips crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); 6968e8ec596SKim Phillips return -EINVAL; 6978e8ec596SKim Phillips } 6988e8ec596SKim Phillips 699acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, 700acdca31dSYuan Kang const u8 *key, unsigned int keylen) 701acdca31dSYuan Kang { 702acdca31dSYuan Kang struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); 703acdca31dSYuan Kang struct ablkcipher_tfm *tfm = &ablkcipher->base.crt_ablkcipher; 704acdca31dSYuan Kang struct device *jrdev = ctx->jrdev; 705acdca31dSYuan Kang int ret = 0; 7064464a7d4SHoria Geanta u32 *key_jump_cmd; 707acdca31dSYuan Kang u32 *desc; 708acdca31dSYuan Kang 709acdca31dSYuan Kang #ifdef DEBUG 710514df281SAlex Porosanu print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", 711acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 712acdca31dSYuan Kang #endif 713acdca31dSYuan Kang 714acdca31dSYuan Kang memcpy(ctx->key, key, keylen); 715acdca31dSYuan Kang ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen, 716acdca31dSYuan Kang DMA_TO_DEVICE); 717acdca31dSYuan Kang if (dma_mapping_error(jrdev, ctx->key_dma)) { 718acdca31dSYuan Kang dev_err(jrdev, "unable to map key i/o memory\n"); 719acdca31dSYuan Kang return -ENOMEM; 720acdca31dSYuan Kang } 721acdca31dSYuan Kang ctx->enckeylen = keylen; 722acdca31dSYuan Kang 723acdca31dSYuan Kang /* ablkcipher_encrypt shared descriptor */ 724acdca31dSYuan Kang desc = ctx->sh_desc_enc; 72561bb86bbSKim Phillips init_sh_desc(desc, HDR_SHARE_SERIAL); 726acdca31dSYuan Kang /* Skip if already shared */ 727acdca31dSYuan Kang key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 728acdca31dSYuan Kang JUMP_COND_SHRD); 729acdca31dSYuan Kang 730acdca31dSYuan Kang /* Load class1 key only */ 731acdca31dSYuan Kang append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, 732acdca31dSYuan Kang ctx->enckeylen, CLASS_1 | 733acdca31dSYuan Kang KEY_DEST_CLASS_REG); 734acdca31dSYuan Kang 735acdca31dSYuan Kang set_jump_tgt_here(desc, key_jump_cmd); 736acdca31dSYuan Kang 737acdca31dSYuan Kang /* Load iv */ 738acdca31dSYuan Kang append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT | 739acdca31dSYuan Kang LDST_CLASS_1_CCB | tfm->ivsize); 740acdca31dSYuan Kang 741acdca31dSYuan Kang /* Load operation */ 742acdca31dSYuan Kang append_operation(desc, ctx->class1_alg_type | 743acdca31dSYuan Kang OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 744acdca31dSYuan Kang 745acdca31dSYuan Kang /* Perform operation */ 746acdca31dSYuan Kang ablkcipher_append_src_dst(desc); 747acdca31dSYuan Kang 748acdca31dSYuan Kang ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, 749acdca31dSYuan Kang desc_bytes(desc), 750acdca31dSYuan Kang DMA_TO_DEVICE); 751acdca31dSYuan Kang if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { 752acdca31dSYuan Kang dev_err(jrdev, "unable to map shared descriptor\n"); 753acdca31dSYuan Kang return -ENOMEM; 754acdca31dSYuan Kang } 755acdca31dSYuan Kang #ifdef DEBUG 756514df281SAlex Porosanu print_hex_dump(KERN_ERR, 757514df281SAlex Porosanu "ablkcipher enc shdesc@"__stringify(__LINE__)": ", 758acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, desc, 759acdca31dSYuan Kang desc_bytes(desc), 1); 760acdca31dSYuan Kang #endif 761acdca31dSYuan Kang /* ablkcipher_decrypt shared descriptor */ 762acdca31dSYuan Kang desc = ctx->sh_desc_dec; 763acdca31dSYuan Kang 76461bb86bbSKim Phillips init_sh_desc(desc, HDR_SHARE_SERIAL); 765acdca31dSYuan Kang /* Skip if already shared */ 766acdca31dSYuan Kang key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 767acdca31dSYuan Kang JUMP_COND_SHRD); 768acdca31dSYuan Kang 769acdca31dSYuan Kang /* Load class1 key only */ 770acdca31dSYuan Kang append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, 771acdca31dSYuan Kang ctx->enckeylen, CLASS_1 | 772acdca31dSYuan Kang KEY_DEST_CLASS_REG); 773acdca31dSYuan Kang 774acdca31dSYuan Kang set_jump_tgt_here(desc, key_jump_cmd); 775acdca31dSYuan Kang 776acdca31dSYuan Kang /* load IV */ 777acdca31dSYuan Kang append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT | 778acdca31dSYuan Kang LDST_CLASS_1_CCB | tfm->ivsize); 779acdca31dSYuan Kang 780acdca31dSYuan Kang /* Choose operation */ 781acdca31dSYuan Kang append_dec_op1(desc, ctx->class1_alg_type); 782acdca31dSYuan Kang 783acdca31dSYuan Kang /* Perform operation */ 784acdca31dSYuan Kang ablkcipher_append_src_dst(desc); 785acdca31dSYuan Kang 786acdca31dSYuan Kang ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, 787acdca31dSYuan Kang desc_bytes(desc), 788acdca31dSYuan Kang DMA_TO_DEVICE); 789acdca31dSYuan Kang if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { 790acdca31dSYuan Kang dev_err(jrdev, "unable to map shared descriptor\n"); 791acdca31dSYuan Kang return -ENOMEM; 792acdca31dSYuan Kang } 793acdca31dSYuan Kang 794acdca31dSYuan Kang #ifdef DEBUG 795514df281SAlex Porosanu print_hex_dump(KERN_ERR, 796514df281SAlex Porosanu "ablkcipher dec shdesc@"__stringify(__LINE__)": ", 797acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, desc, 798acdca31dSYuan Kang desc_bytes(desc), 1); 799acdca31dSYuan Kang #endif 800acdca31dSYuan Kang 801acdca31dSYuan Kang return ret; 802acdca31dSYuan Kang } 803acdca31dSYuan Kang 8048e8ec596SKim Phillips /* 8051acebad3SYuan Kang * aead_edesc - s/w-extended aead descriptor 8061acebad3SYuan Kang * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist 807643b39b0SYuan Kang * @assoc_chained: if source is chained 8088e8ec596SKim Phillips * @src_nents: number of segments in input scatterlist 809643b39b0SYuan Kang * @src_chained: if source is chained 8108e8ec596SKim Phillips * @dst_nents: number of segments in output scatterlist 811643b39b0SYuan Kang * @dst_chained: if destination is chained 8121acebad3SYuan Kang * @iv_dma: dma address of iv for checking continuity and link table 8138e8ec596SKim Phillips * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) 814a299c837SYuan Kang * @sec4_sg_bytes: length of dma mapped sec4_sg space 815a299c837SYuan Kang * @sec4_sg_dma: bus physical mapped address of h/w link table 8168e8ec596SKim Phillips * @hw_desc: the h/w job descriptor followed by any referenced link tables 8178e8ec596SKim Phillips */ 8180e479300SYuan Kang struct aead_edesc { 8198e8ec596SKim Phillips int assoc_nents; 820643b39b0SYuan Kang bool assoc_chained; 8218e8ec596SKim Phillips int src_nents; 822643b39b0SYuan Kang bool src_chained; 8238e8ec596SKim Phillips int dst_nents; 824643b39b0SYuan Kang bool dst_chained; 8251acebad3SYuan Kang dma_addr_t iv_dma; 826a299c837SYuan Kang int sec4_sg_bytes; 827a299c837SYuan Kang dma_addr_t sec4_sg_dma; 828a299c837SYuan Kang struct sec4_sg_entry *sec4_sg; 8298e8ec596SKim Phillips u32 hw_desc[0]; 8308e8ec596SKim Phillips }; 8318e8ec596SKim Phillips 832acdca31dSYuan Kang /* 833acdca31dSYuan Kang * ablkcipher_edesc - s/w-extended ablkcipher descriptor 834acdca31dSYuan Kang * @src_nents: number of segments in input scatterlist 835643b39b0SYuan Kang * @src_chained: if source is chained 836acdca31dSYuan Kang * @dst_nents: number of segments in output scatterlist 837643b39b0SYuan Kang * @dst_chained: if destination is chained 838acdca31dSYuan Kang * @iv_dma: dma address of iv for checking continuity and link table 839acdca31dSYuan Kang * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) 840a299c837SYuan Kang * @sec4_sg_bytes: length of dma mapped sec4_sg space 841a299c837SYuan Kang * @sec4_sg_dma: bus physical mapped address of h/w link table 842acdca31dSYuan Kang * @hw_desc: the h/w job descriptor followed by any referenced link tables 843acdca31dSYuan Kang */ 844acdca31dSYuan Kang struct ablkcipher_edesc { 845acdca31dSYuan Kang int src_nents; 846643b39b0SYuan Kang bool src_chained; 847acdca31dSYuan Kang int dst_nents; 848643b39b0SYuan Kang bool dst_chained; 849acdca31dSYuan Kang dma_addr_t iv_dma; 850a299c837SYuan Kang int sec4_sg_bytes; 851a299c837SYuan Kang dma_addr_t sec4_sg_dma; 852a299c837SYuan Kang struct sec4_sg_entry *sec4_sg; 853acdca31dSYuan Kang u32 hw_desc[0]; 854acdca31dSYuan Kang }; 855acdca31dSYuan Kang 8561acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src, 857643b39b0SYuan Kang struct scatterlist *dst, int src_nents, 858643b39b0SYuan Kang bool src_chained, int dst_nents, bool dst_chained, 859a299c837SYuan Kang dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma, 860a299c837SYuan Kang int sec4_sg_bytes) 8611acebad3SYuan Kang { 862643b39b0SYuan Kang if (dst != src) { 863643b39b0SYuan Kang dma_unmap_sg_chained(dev, src, src_nents ? : 1, DMA_TO_DEVICE, 864643b39b0SYuan Kang src_chained); 865643b39b0SYuan Kang dma_unmap_sg_chained(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE, 866643b39b0SYuan Kang dst_chained); 8671acebad3SYuan Kang } else { 868643b39b0SYuan Kang dma_unmap_sg_chained(dev, src, src_nents ? : 1, 869643b39b0SYuan Kang DMA_BIDIRECTIONAL, src_chained); 8701acebad3SYuan Kang } 8711acebad3SYuan Kang 8721acebad3SYuan Kang if (iv_dma) 8731acebad3SYuan Kang dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE); 874a299c837SYuan Kang if (sec4_sg_bytes) 875a299c837SYuan Kang dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes, 8761acebad3SYuan Kang DMA_TO_DEVICE); 8771acebad3SYuan Kang } 8781acebad3SYuan Kang 8790e479300SYuan Kang static void aead_unmap(struct device *dev, 8800e479300SYuan Kang struct aead_edesc *edesc, 8810e479300SYuan Kang struct aead_request *req) 8828e8ec596SKim Phillips { 8831acebad3SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 8841acebad3SYuan Kang int ivsize = crypto_aead_ivsize(aead); 8851acebad3SYuan Kang 886643b39b0SYuan Kang dma_unmap_sg_chained(dev, req->assoc, edesc->assoc_nents, 887643b39b0SYuan Kang DMA_TO_DEVICE, edesc->assoc_chained); 8888e8ec596SKim Phillips 8891acebad3SYuan Kang caam_unmap(dev, req->src, req->dst, 890643b39b0SYuan Kang edesc->src_nents, edesc->src_chained, edesc->dst_nents, 891643b39b0SYuan Kang edesc->dst_chained, edesc->iv_dma, ivsize, 892643b39b0SYuan Kang edesc->sec4_sg_dma, edesc->sec4_sg_bytes); 8938e8ec596SKim Phillips } 8948e8ec596SKim Phillips 895acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev, 896acdca31dSYuan Kang struct ablkcipher_edesc *edesc, 897acdca31dSYuan Kang struct ablkcipher_request *req) 898acdca31dSYuan Kang { 899acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 900acdca31dSYuan Kang int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 901acdca31dSYuan Kang 902acdca31dSYuan Kang caam_unmap(dev, req->src, req->dst, 903643b39b0SYuan Kang edesc->src_nents, edesc->src_chained, edesc->dst_nents, 904643b39b0SYuan Kang edesc->dst_chained, edesc->iv_dma, ivsize, 905643b39b0SYuan Kang edesc->sec4_sg_dma, edesc->sec4_sg_bytes); 906acdca31dSYuan Kang } 907acdca31dSYuan Kang 9080e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err, 9098e8ec596SKim Phillips void *context) 9108e8ec596SKim Phillips { 9110e479300SYuan Kang struct aead_request *req = context; 9120e479300SYuan Kang struct aead_edesc *edesc; 9138e8ec596SKim Phillips #ifdef DEBUG 9140e479300SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 9158e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 9161acebad3SYuan Kang int ivsize = crypto_aead_ivsize(aead); 9178e8ec596SKim Phillips 9188e8ec596SKim Phillips dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 9198e8ec596SKim Phillips #endif 9201acebad3SYuan Kang 9210e479300SYuan Kang edesc = (struct aead_edesc *)((char *)desc - 9220e479300SYuan Kang offsetof(struct aead_edesc, hw_desc)); 9238e8ec596SKim Phillips 924fa9659cdSMarek Vasut if (err) 925fa9659cdSMarek Vasut caam_jr_strstatus(jrdev, err); 9268e8ec596SKim Phillips 9270e479300SYuan Kang aead_unmap(jrdev, edesc, req); 9288e8ec596SKim Phillips 9298e8ec596SKim Phillips #ifdef DEBUG 930514df281SAlex Porosanu print_hex_dump(KERN_ERR, "assoc @"__stringify(__LINE__)": ", 9310e479300SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->assoc), 9320e479300SYuan Kang req->assoclen , 1); 933514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dstiv @"__stringify(__LINE__)": ", 9340e479300SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src) - ivsize, 9358e8ec596SKim Phillips edesc->src_nents ? 100 : ivsize, 1); 936514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ", 9370e479300SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 9380e479300SYuan Kang edesc->src_nents ? 100 : req->cryptlen + 9398e8ec596SKim Phillips ctx->authsize + 4, 1); 9408e8ec596SKim Phillips #endif 9418e8ec596SKim Phillips 9428e8ec596SKim Phillips kfree(edesc); 9438e8ec596SKim Phillips 9440e479300SYuan Kang aead_request_complete(req, err); 9458e8ec596SKim Phillips } 9468e8ec596SKim Phillips 9470e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err, 9488e8ec596SKim Phillips void *context) 9498e8ec596SKim Phillips { 9500e479300SYuan Kang struct aead_request *req = context; 9510e479300SYuan Kang struct aead_edesc *edesc; 9528e8ec596SKim Phillips #ifdef DEBUG 9530e479300SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 9548e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 9551acebad3SYuan Kang int ivsize = crypto_aead_ivsize(aead); 9568e8ec596SKim Phillips 9578e8ec596SKim Phillips dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 9588e8ec596SKim Phillips #endif 9591acebad3SYuan Kang 9600e479300SYuan Kang edesc = (struct aead_edesc *)((char *)desc - 9610e479300SYuan Kang offsetof(struct aead_edesc, hw_desc)); 9628e8ec596SKim Phillips 9631acebad3SYuan Kang #ifdef DEBUG 964514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dstiv @"__stringify(__LINE__)": ", 9651acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, req->iv, 9661acebad3SYuan Kang ivsize, 1); 967514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ", 9681acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst), 969bbf9c893SHoria Geanta req->cryptlen - ctx->authsize, 1); 9701acebad3SYuan Kang #endif 9711acebad3SYuan Kang 972fa9659cdSMarek Vasut if (err) 973fa9659cdSMarek Vasut caam_jr_strstatus(jrdev, err); 9748e8ec596SKim Phillips 9750e479300SYuan Kang aead_unmap(jrdev, edesc, req); 9768e8ec596SKim Phillips 9778e8ec596SKim Phillips /* 9788e8ec596SKim Phillips * verify hw auth check passed else return -EBADMSG 9798e8ec596SKim Phillips */ 9808e8ec596SKim Phillips if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK) 9818e8ec596SKim Phillips err = -EBADMSG; 9828e8ec596SKim Phillips 9838e8ec596SKim Phillips #ifdef DEBUG 984514df281SAlex Porosanu print_hex_dump(KERN_ERR, "iphdrout@"__stringify(__LINE__)": ", 9858e8ec596SKim Phillips DUMP_PREFIX_ADDRESS, 16, 4, 9860e479300SYuan Kang ((char *)sg_virt(req->assoc) - sizeof(struct iphdr)), 9870e479300SYuan Kang sizeof(struct iphdr) + req->assoclen + 9880e479300SYuan Kang ((req->cryptlen > 1500) ? 1500 : req->cryptlen) + 9898e8ec596SKim Phillips ctx->authsize + 36, 1); 990a299c837SYuan Kang if (!err && edesc->sec4_sg_bytes) { 9910e479300SYuan Kang struct scatterlist *sg = sg_last(req->src, edesc->src_nents); 992514df281SAlex Porosanu print_hex_dump(KERN_ERR, "sglastout@"__stringify(__LINE__)": ", 9938e8ec596SKim Phillips DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(sg), 9948e8ec596SKim Phillips sg->length + ctx->authsize + 16, 1); 9958e8ec596SKim Phillips } 9968e8ec596SKim Phillips #endif 9971acebad3SYuan Kang 9988e8ec596SKim Phillips kfree(edesc); 9998e8ec596SKim Phillips 10000e479300SYuan Kang aead_request_complete(req, err); 10018e8ec596SKim Phillips } 10028e8ec596SKim Phillips 1003acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err, 1004acdca31dSYuan Kang void *context) 1005acdca31dSYuan Kang { 1006acdca31dSYuan Kang struct ablkcipher_request *req = context; 1007acdca31dSYuan Kang struct ablkcipher_edesc *edesc; 1008acdca31dSYuan Kang #ifdef DEBUG 1009acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 1010acdca31dSYuan Kang int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 1011acdca31dSYuan Kang 1012acdca31dSYuan Kang dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 1013acdca31dSYuan Kang #endif 1014acdca31dSYuan Kang 1015acdca31dSYuan Kang edesc = (struct ablkcipher_edesc *)((char *)desc - 1016acdca31dSYuan Kang offsetof(struct ablkcipher_edesc, hw_desc)); 1017acdca31dSYuan Kang 1018fa9659cdSMarek Vasut if (err) 1019fa9659cdSMarek Vasut caam_jr_strstatus(jrdev, err); 1020acdca31dSYuan Kang 1021acdca31dSYuan Kang #ifdef DEBUG 1022514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dstiv @"__stringify(__LINE__)": ", 1023acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, req->info, 1024acdca31dSYuan Kang edesc->src_nents > 1 ? 100 : ivsize, 1); 1025514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ", 1026acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 1027acdca31dSYuan Kang edesc->dst_nents > 1 ? 100 : req->nbytes, 1); 1028acdca31dSYuan Kang #endif 1029acdca31dSYuan Kang 1030acdca31dSYuan Kang ablkcipher_unmap(jrdev, edesc, req); 1031acdca31dSYuan Kang kfree(edesc); 1032acdca31dSYuan Kang 1033acdca31dSYuan Kang ablkcipher_request_complete(req, err); 1034acdca31dSYuan Kang } 1035acdca31dSYuan Kang 1036acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err, 1037acdca31dSYuan Kang void *context) 1038acdca31dSYuan Kang { 1039acdca31dSYuan Kang struct ablkcipher_request *req = context; 1040acdca31dSYuan Kang struct ablkcipher_edesc *edesc; 1041acdca31dSYuan Kang #ifdef DEBUG 1042acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 1043acdca31dSYuan Kang int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 1044acdca31dSYuan Kang 1045acdca31dSYuan Kang dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 1046acdca31dSYuan Kang #endif 1047acdca31dSYuan Kang 1048acdca31dSYuan Kang edesc = (struct ablkcipher_edesc *)((char *)desc - 1049acdca31dSYuan Kang offsetof(struct ablkcipher_edesc, hw_desc)); 1050fa9659cdSMarek Vasut if (err) 1051fa9659cdSMarek Vasut caam_jr_strstatus(jrdev, err); 1052acdca31dSYuan Kang 1053acdca31dSYuan Kang #ifdef DEBUG 1054514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dstiv @"__stringify(__LINE__)": ", 1055acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, req->info, 1056acdca31dSYuan Kang ivsize, 1); 1057514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ", 1058acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 1059acdca31dSYuan Kang edesc->dst_nents > 1 ? 100 : req->nbytes, 1); 1060acdca31dSYuan Kang #endif 1061acdca31dSYuan Kang 1062acdca31dSYuan Kang ablkcipher_unmap(jrdev, edesc, req); 1063acdca31dSYuan Kang kfree(edesc); 1064acdca31dSYuan Kang 1065acdca31dSYuan Kang ablkcipher_request_complete(req, err); 1066acdca31dSYuan Kang } 1067acdca31dSYuan Kang 10688e8ec596SKim Phillips /* 10691acebad3SYuan Kang * Fill in aead job descriptor 10708e8ec596SKim Phillips */ 10711acebad3SYuan Kang static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, 10721acebad3SYuan Kang struct aead_edesc *edesc, 10731acebad3SYuan Kang struct aead_request *req, 10741acebad3SYuan Kang bool all_contig, bool encrypt) 10758e8ec596SKim Phillips { 10760e479300SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 10778e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 10788e8ec596SKim Phillips int ivsize = crypto_aead_ivsize(aead); 10798e8ec596SKim Phillips int authsize = ctx->authsize; 10801acebad3SYuan Kang u32 *desc = edesc->hw_desc; 10811acebad3SYuan Kang u32 out_options = 0, in_options; 10821acebad3SYuan Kang dma_addr_t dst_dma, src_dma; 1083a299c837SYuan Kang int len, sec4_sg_index = 0; 10848e8ec596SKim Phillips 10851acebad3SYuan Kang #ifdef DEBUG 10868e8ec596SKim Phillips debug("assoclen %d cryptlen %d authsize %d\n", 10870e479300SYuan Kang req->assoclen, req->cryptlen, authsize); 1088514df281SAlex Porosanu print_hex_dump(KERN_ERR, "assoc @"__stringify(__LINE__)": ", 10890e479300SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->assoc), 10900e479300SYuan Kang req->assoclen , 1); 1091514df281SAlex Porosanu print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ", 10921acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, req->iv, 10938e8ec596SKim Phillips edesc->src_nents ? 100 : ivsize, 1); 1094514df281SAlex Porosanu print_hex_dump(KERN_ERR, "src @"__stringify(__LINE__)": ", 10950e479300SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 10961acebad3SYuan Kang edesc->src_nents ? 100 : req->cryptlen, 1); 1097514df281SAlex Porosanu print_hex_dump(KERN_ERR, "shrdesc@"__stringify(__LINE__)": ", 10988e8ec596SKim Phillips DUMP_PREFIX_ADDRESS, 16, 4, sh_desc, 10998e8ec596SKim Phillips desc_bytes(sh_desc), 1); 11008e8ec596SKim Phillips #endif 11011acebad3SYuan Kang 11021acebad3SYuan Kang len = desc_len(sh_desc); 11031acebad3SYuan Kang init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); 11041acebad3SYuan Kang 11051acebad3SYuan Kang if (all_contig) { 11061acebad3SYuan Kang src_dma = sg_dma_address(req->assoc); 11071acebad3SYuan Kang in_options = 0; 11081acebad3SYuan Kang } else { 1109a299c837SYuan Kang src_dma = edesc->sec4_sg_dma; 1110a299c837SYuan Kang sec4_sg_index += (edesc->assoc_nents ? : 1) + 1 + 11111acebad3SYuan Kang (edesc->src_nents ? : 1); 11121acebad3SYuan Kang in_options = LDST_SGF; 11131acebad3SYuan Kang } 1114bbf9c893SHoria Geanta 1115bbf9c893SHoria Geanta append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen, 1116bbf9c893SHoria Geanta in_options); 11178e8ec596SKim Phillips 11181acebad3SYuan Kang if (likely(req->src == req->dst)) { 11191acebad3SYuan Kang if (all_contig) { 11201acebad3SYuan Kang dst_dma = sg_dma_address(req->src); 11218e8ec596SKim Phillips } else { 1122a299c837SYuan Kang dst_dma = src_dma + sizeof(struct sec4_sg_entry) * 11231acebad3SYuan Kang ((edesc->assoc_nents ? : 1) + 1); 11241acebad3SYuan Kang out_options = LDST_SGF; 11258e8ec596SKim Phillips } 11268e8ec596SKim Phillips } else { 11278e8ec596SKim Phillips if (!edesc->dst_nents) { 11280e479300SYuan Kang dst_dma = sg_dma_address(req->dst); 11298e8ec596SKim Phillips } else { 1130a299c837SYuan Kang dst_dma = edesc->sec4_sg_dma + 1131a299c837SYuan Kang sec4_sg_index * 1132a299c837SYuan Kang sizeof(struct sec4_sg_entry); 11331acebad3SYuan Kang out_options = LDST_SGF; 11348e8ec596SKim Phillips } 11358e8ec596SKim Phillips } 11368e8ec596SKim Phillips if (encrypt) 1137bbf9c893SHoria Geanta append_seq_out_ptr(desc, dst_dma, req->cryptlen + authsize, 1138bbf9c893SHoria Geanta out_options); 11398e8ec596SKim Phillips else 11401acebad3SYuan Kang append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize, 11411acebad3SYuan Kang out_options); 11421acebad3SYuan Kang } 11431acebad3SYuan Kang 11441acebad3SYuan Kang /* 11451acebad3SYuan Kang * Fill in aead givencrypt job descriptor 11461acebad3SYuan Kang */ 11471acebad3SYuan Kang static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, 11481acebad3SYuan Kang struct aead_edesc *edesc, 11491acebad3SYuan Kang struct aead_request *req, 11501acebad3SYuan Kang int contig) 11511acebad3SYuan Kang { 11521acebad3SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 11531acebad3SYuan Kang struct caam_ctx *ctx = crypto_aead_ctx(aead); 11541acebad3SYuan Kang int ivsize = crypto_aead_ivsize(aead); 11551acebad3SYuan Kang int authsize = ctx->authsize; 11561acebad3SYuan Kang u32 *desc = edesc->hw_desc; 11571acebad3SYuan Kang u32 out_options = 0, in_options; 11581acebad3SYuan Kang dma_addr_t dst_dma, src_dma; 1159a299c837SYuan Kang int len, sec4_sg_index = 0; 11608e8ec596SKim Phillips 11618e8ec596SKim Phillips #ifdef DEBUG 11621acebad3SYuan Kang debug("assoclen %d cryptlen %d authsize %d\n", 11631acebad3SYuan Kang req->assoclen, req->cryptlen, authsize); 1164514df281SAlex Porosanu print_hex_dump(KERN_ERR, "assoc @"__stringify(__LINE__)": ", 11651acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->assoc), 11661acebad3SYuan Kang req->assoclen , 1); 1167514df281SAlex Porosanu print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ", 11681acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1); 1169514df281SAlex Porosanu print_hex_dump(KERN_ERR, "src @"__stringify(__LINE__)": ", 11701acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 11711acebad3SYuan Kang edesc->src_nents > 1 ? 100 : req->cryptlen, 1); 1172514df281SAlex Porosanu print_hex_dump(KERN_ERR, "shrdesc@"__stringify(__LINE__)": ", 11731acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sh_desc, 11741acebad3SYuan Kang desc_bytes(sh_desc), 1); 11758e8ec596SKim Phillips #endif 11768e8ec596SKim Phillips 11771acebad3SYuan Kang len = desc_len(sh_desc); 11781acebad3SYuan Kang init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); 11791acebad3SYuan Kang 11801acebad3SYuan Kang if (contig & GIV_SRC_CONTIG) { 11811acebad3SYuan Kang src_dma = sg_dma_address(req->assoc); 11821acebad3SYuan Kang in_options = 0; 11831acebad3SYuan Kang } else { 1184a299c837SYuan Kang src_dma = edesc->sec4_sg_dma; 1185a299c837SYuan Kang sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents; 11861acebad3SYuan Kang in_options = LDST_SGF; 11871acebad3SYuan Kang } 1188bbf9c893SHoria Geanta append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen, 1189bbf9c893SHoria Geanta in_options); 11901acebad3SYuan Kang 11911acebad3SYuan Kang if (contig & GIV_DST_CONTIG) { 11921acebad3SYuan Kang dst_dma = edesc->iv_dma; 11931acebad3SYuan Kang } else { 11941acebad3SYuan Kang if (likely(req->src == req->dst)) { 1195a299c837SYuan Kang dst_dma = src_dma + sizeof(struct sec4_sg_entry) * 11961acebad3SYuan Kang edesc->assoc_nents; 11971acebad3SYuan Kang out_options = LDST_SGF; 11981acebad3SYuan Kang } else { 1199a299c837SYuan Kang dst_dma = edesc->sec4_sg_dma + 1200a299c837SYuan Kang sec4_sg_index * 1201a299c837SYuan Kang sizeof(struct sec4_sg_entry); 12021acebad3SYuan Kang out_options = LDST_SGF; 12031acebad3SYuan Kang } 12048e8ec596SKim Phillips } 12058e8ec596SKim Phillips 1206bbf9c893SHoria Geanta append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen + authsize, 1207bbf9c893SHoria Geanta out_options); 12088e8ec596SKim Phillips } 12098e8ec596SKim Phillips 12108e8ec596SKim Phillips /* 1211acdca31dSYuan Kang * Fill in ablkcipher job descriptor 1212acdca31dSYuan Kang */ 1213acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr, 1214acdca31dSYuan Kang struct ablkcipher_edesc *edesc, 1215acdca31dSYuan Kang struct ablkcipher_request *req, 1216acdca31dSYuan Kang bool iv_contig) 1217acdca31dSYuan Kang { 1218acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 1219acdca31dSYuan Kang int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 1220acdca31dSYuan Kang u32 *desc = edesc->hw_desc; 1221acdca31dSYuan Kang u32 out_options = 0, in_options; 1222acdca31dSYuan Kang dma_addr_t dst_dma, src_dma; 1223a299c837SYuan Kang int len, sec4_sg_index = 0; 1224acdca31dSYuan Kang 1225acdca31dSYuan Kang #ifdef DEBUG 1226514df281SAlex Porosanu print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ", 1227acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, req->info, 1228acdca31dSYuan Kang ivsize, 1); 1229514df281SAlex Porosanu print_hex_dump(KERN_ERR, "src @"__stringify(__LINE__)": ", 1230acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 1231acdca31dSYuan Kang edesc->src_nents ? 100 : req->nbytes, 1); 1232acdca31dSYuan Kang #endif 1233acdca31dSYuan Kang 1234acdca31dSYuan Kang len = desc_len(sh_desc); 1235acdca31dSYuan Kang init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); 1236acdca31dSYuan Kang 1237acdca31dSYuan Kang if (iv_contig) { 1238acdca31dSYuan Kang src_dma = edesc->iv_dma; 1239acdca31dSYuan Kang in_options = 0; 1240acdca31dSYuan Kang } else { 1241a299c837SYuan Kang src_dma = edesc->sec4_sg_dma; 1242a299c837SYuan Kang sec4_sg_index += (iv_contig ? 0 : 1) + edesc->src_nents; 1243acdca31dSYuan Kang in_options = LDST_SGF; 1244acdca31dSYuan Kang } 1245acdca31dSYuan Kang append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options); 1246acdca31dSYuan Kang 1247acdca31dSYuan Kang if (likely(req->src == req->dst)) { 1248acdca31dSYuan Kang if (!edesc->src_nents && iv_contig) { 1249acdca31dSYuan Kang dst_dma = sg_dma_address(req->src); 1250acdca31dSYuan Kang } else { 1251a299c837SYuan Kang dst_dma = edesc->sec4_sg_dma + 1252a299c837SYuan Kang sizeof(struct sec4_sg_entry); 1253acdca31dSYuan Kang out_options = LDST_SGF; 1254acdca31dSYuan Kang } 1255acdca31dSYuan Kang } else { 1256acdca31dSYuan Kang if (!edesc->dst_nents) { 1257acdca31dSYuan Kang dst_dma = sg_dma_address(req->dst); 1258acdca31dSYuan Kang } else { 1259a299c837SYuan Kang dst_dma = edesc->sec4_sg_dma + 1260a299c837SYuan Kang sec4_sg_index * sizeof(struct sec4_sg_entry); 1261acdca31dSYuan Kang out_options = LDST_SGF; 1262acdca31dSYuan Kang } 1263acdca31dSYuan Kang } 1264acdca31dSYuan Kang append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options); 1265acdca31dSYuan Kang } 1266acdca31dSYuan Kang 1267acdca31dSYuan Kang /* 12681acebad3SYuan Kang * allocate and map the aead extended descriptor 12698e8ec596SKim Phillips */ 12700e479300SYuan Kang static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, 1271bbf9c893SHoria Geanta int desc_bytes, bool *all_contig_ptr, 1272bbf9c893SHoria Geanta bool encrypt) 12738e8ec596SKim Phillips { 12740e479300SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 12758e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 12768e8ec596SKim Phillips struct device *jrdev = ctx->jrdev; 12771acebad3SYuan Kang gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | 12781acebad3SYuan Kang CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; 12791acebad3SYuan Kang int assoc_nents, src_nents, dst_nents = 0; 12800e479300SYuan Kang struct aead_edesc *edesc; 12811acebad3SYuan Kang dma_addr_t iv_dma = 0; 12821acebad3SYuan Kang int sgc; 12831acebad3SYuan Kang bool all_contig = true; 1284643b39b0SYuan Kang bool assoc_chained = false, src_chained = false, dst_chained = false; 12851acebad3SYuan Kang int ivsize = crypto_aead_ivsize(aead); 1286a299c837SYuan Kang int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; 1287bbf9c893SHoria Geanta unsigned int authsize = ctx->authsize; 12888e8ec596SKim Phillips 1289643b39b0SYuan Kang assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); 12908e8ec596SKim Phillips 1291bbf9c893SHoria Geanta if (unlikely(req->dst != req->src)) { 1292bbf9c893SHoria Geanta src_nents = sg_count(req->src, req->cryptlen, &src_chained); 1293bbf9c893SHoria Geanta dst_nents = sg_count(req->dst, 1294bbf9c893SHoria Geanta req->cryptlen + 1295bbf9c893SHoria Geanta (encrypt ? authsize : (-authsize)), 1296bbf9c893SHoria Geanta &dst_chained); 1297bbf9c893SHoria Geanta } else { 1298bbf9c893SHoria Geanta src_nents = sg_count(req->src, 1299bbf9c893SHoria Geanta req->cryptlen + 1300bbf9c893SHoria Geanta (encrypt ? authsize : 0), 1301bbf9c893SHoria Geanta &src_chained); 1302bbf9c893SHoria Geanta } 13038e8ec596SKim Phillips 1304643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, 1305286233e6SHoria Geanta DMA_TO_DEVICE, assoc_chained); 13061acebad3SYuan Kang if (likely(req->src == req->dst)) { 1307643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, 1308643b39b0SYuan Kang DMA_BIDIRECTIONAL, src_chained); 13091acebad3SYuan Kang } else { 1310643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, 1311643b39b0SYuan Kang DMA_TO_DEVICE, src_chained); 1312643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1, 1313643b39b0SYuan Kang DMA_FROM_DEVICE, dst_chained); 13148e8ec596SKim Phillips } 13158e8ec596SKim Phillips 13161acebad3SYuan Kang /* Check if data are contiguous */ 13171acebad3SYuan Kang iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE); 13181acebad3SYuan Kang if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen != 13191acebad3SYuan Kang iv_dma || src_nents || iv_dma + ivsize != 13201acebad3SYuan Kang sg_dma_address(req->src)) { 13211acebad3SYuan Kang all_contig = false; 13221acebad3SYuan Kang assoc_nents = assoc_nents ? : 1; 13231acebad3SYuan Kang src_nents = src_nents ? : 1; 1324a299c837SYuan Kang sec4_sg_len = assoc_nents + 1 + src_nents; 13251acebad3SYuan Kang } 1326a299c837SYuan Kang sec4_sg_len += dst_nents; 13271acebad3SYuan Kang 1328a299c837SYuan Kang sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); 13298e8ec596SKim Phillips 13308e8ec596SKim Phillips /* allocate space for base edesc and hw desc commands, link tables */ 13310e479300SYuan Kang edesc = kmalloc(sizeof(struct aead_edesc) + desc_bytes + 1332a299c837SYuan Kang sec4_sg_bytes, GFP_DMA | flags); 13338e8ec596SKim Phillips if (!edesc) { 13348e8ec596SKim Phillips dev_err(jrdev, "could not allocate extended descriptor\n"); 13358e8ec596SKim Phillips return ERR_PTR(-ENOMEM); 13368e8ec596SKim Phillips } 13378e8ec596SKim Phillips 13388e8ec596SKim Phillips edesc->assoc_nents = assoc_nents; 1339643b39b0SYuan Kang edesc->assoc_chained = assoc_chained; 13408e8ec596SKim Phillips edesc->src_nents = src_nents; 1341643b39b0SYuan Kang edesc->src_chained = src_chained; 13428e8ec596SKim Phillips edesc->dst_nents = dst_nents; 1343643b39b0SYuan Kang edesc->dst_chained = dst_chained; 13441acebad3SYuan Kang edesc->iv_dma = iv_dma; 1345a299c837SYuan Kang edesc->sec4_sg_bytes = sec4_sg_bytes; 1346a299c837SYuan Kang edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + 13478e8ec596SKim Phillips desc_bytes; 13481acebad3SYuan Kang *all_contig_ptr = all_contig; 13491acebad3SYuan Kang 1350a299c837SYuan Kang sec4_sg_index = 0; 13511acebad3SYuan Kang if (!all_contig) { 1352a299c837SYuan Kang sg_to_sec4_sg(req->assoc, 13531acebad3SYuan Kang (assoc_nents ? : 1), 1354a299c837SYuan Kang edesc->sec4_sg + 1355a299c837SYuan Kang sec4_sg_index, 0); 1356a299c837SYuan Kang sec4_sg_index += assoc_nents ? : 1; 1357a299c837SYuan Kang dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, 13581acebad3SYuan Kang iv_dma, ivsize, 0); 1359a299c837SYuan Kang sec4_sg_index += 1; 1360a299c837SYuan Kang sg_to_sec4_sg_last(req->src, 13611acebad3SYuan Kang (src_nents ? : 1), 1362a299c837SYuan Kang edesc->sec4_sg + 1363a299c837SYuan Kang sec4_sg_index, 0); 1364a299c837SYuan Kang sec4_sg_index += src_nents ? : 1; 13651acebad3SYuan Kang } 13661acebad3SYuan Kang if (dst_nents) { 1367a299c837SYuan Kang sg_to_sec4_sg_last(req->dst, dst_nents, 1368a299c837SYuan Kang edesc->sec4_sg + sec4_sg_index, 0); 13691acebad3SYuan Kang } 13701da2be33SRuchika Gupta edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, 13711da2be33SRuchika Gupta sec4_sg_bytes, DMA_TO_DEVICE); 13728e8ec596SKim Phillips 13738e8ec596SKim Phillips return edesc; 13748e8ec596SKim Phillips } 13758e8ec596SKim Phillips 13760e479300SYuan Kang static int aead_encrypt(struct aead_request *req) 13778e8ec596SKim Phillips { 13780e479300SYuan Kang struct aead_edesc *edesc; 13798e8ec596SKim Phillips struct crypto_aead *aead = crypto_aead_reqtfm(req); 13808e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 13818e8ec596SKim Phillips struct device *jrdev = ctx->jrdev; 13821acebad3SYuan Kang bool all_contig; 13838e8ec596SKim Phillips u32 *desc; 13841acebad3SYuan Kang int ret = 0; 13851acebad3SYuan Kang 13868e8ec596SKim Phillips /* allocate extended descriptor */ 13871acebad3SYuan Kang edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN * 1388bbf9c893SHoria Geanta CAAM_CMD_SZ, &all_contig, true); 13898e8ec596SKim Phillips if (IS_ERR(edesc)) 13908e8ec596SKim Phillips return PTR_ERR(edesc); 13918e8ec596SKim Phillips 13921acebad3SYuan Kang /* Create and submit job descriptor */ 13931acebad3SYuan Kang init_aead_job(ctx->sh_desc_enc, ctx->sh_desc_enc_dma, edesc, req, 13941acebad3SYuan Kang all_contig, true); 13951acebad3SYuan Kang #ifdef DEBUG 1396514df281SAlex Porosanu print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ", 13971acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc, 13981acebad3SYuan Kang desc_bytes(edesc->hw_desc), 1); 13991acebad3SYuan Kang #endif 14001acebad3SYuan Kang 14018e8ec596SKim Phillips desc = edesc->hw_desc; 14021acebad3SYuan Kang ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req); 14031acebad3SYuan Kang if (!ret) { 14041acebad3SYuan Kang ret = -EINPROGRESS; 14051acebad3SYuan Kang } else { 14061acebad3SYuan Kang aead_unmap(jrdev, edesc, req); 14071acebad3SYuan Kang kfree(edesc); 14081acebad3SYuan Kang } 14098e8ec596SKim Phillips 14101acebad3SYuan Kang return ret; 14118e8ec596SKim Phillips } 14128e8ec596SKim Phillips 14130e479300SYuan Kang static int aead_decrypt(struct aead_request *req) 14148e8ec596SKim Phillips { 14151acebad3SYuan Kang struct aead_edesc *edesc; 14160e479300SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 14170e479300SYuan Kang struct caam_ctx *ctx = crypto_aead_ctx(aead); 14180e479300SYuan Kang struct device *jrdev = ctx->jrdev; 14191acebad3SYuan Kang bool all_contig; 14200e479300SYuan Kang u32 *desc; 14211acebad3SYuan Kang int ret = 0; 14220e479300SYuan Kang 14230e479300SYuan Kang /* allocate extended descriptor */ 14241acebad3SYuan Kang edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN * 1425bbf9c893SHoria Geanta CAAM_CMD_SZ, &all_contig, false); 14260e479300SYuan Kang if (IS_ERR(edesc)) 14270e479300SYuan Kang return PTR_ERR(edesc); 14280e479300SYuan Kang 14291acebad3SYuan Kang #ifdef DEBUG 1430514df281SAlex Porosanu print_hex_dump(KERN_ERR, "dec src@"__stringify(__LINE__)": ", 14311acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 14321acebad3SYuan Kang req->cryptlen, 1); 14331acebad3SYuan Kang #endif 14341acebad3SYuan Kang 14351acebad3SYuan Kang /* Create and submit job descriptor*/ 14361acebad3SYuan Kang init_aead_job(ctx->sh_desc_dec, 14371acebad3SYuan Kang ctx->sh_desc_dec_dma, edesc, req, all_contig, false); 14381acebad3SYuan Kang #ifdef DEBUG 1439514df281SAlex Porosanu print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ", 14401acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc, 14411acebad3SYuan Kang desc_bytes(edesc->hw_desc), 1); 14421acebad3SYuan Kang #endif 14431acebad3SYuan Kang 14440e479300SYuan Kang desc = edesc->hw_desc; 14451acebad3SYuan Kang ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req); 14461acebad3SYuan Kang if (!ret) { 14471acebad3SYuan Kang ret = -EINPROGRESS; 14481acebad3SYuan Kang } else { 14491acebad3SYuan Kang aead_unmap(jrdev, edesc, req); 14501acebad3SYuan Kang kfree(edesc); 14511acebad3SYuan Kang } 14520e479300SYuan Kang 14531acebad3SYuan Kang return ret; 14541acebad3SYuan Kang } 14550e479300SYuan Kang 14561acebad3SYuan Kang /* 14571acebad3SYuan Kang * allocate and map the aead extended descriptor for aead givencrypt 14581acebad3SYuan Kang */ 14591acebad3SYuan Kang static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request 14601acebad3SYuan Kang *greq, int desc_bytes, 14611acebad3SYuan Kang u32 *contig_ptr) 14621acebad3SYuan Kang { 14631acebad3SYuan Kang struct aead_request *req = &greq->areq; 14641acebad3SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 14651acebad3SYuan Kang struct caam_ctx *ctx = crypto_aead_ctx(aead); 14661acebad3SYuan Kang struct device *jrdev = ctx->jrdev; 14671acebad3SYuan Kang gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | 14681acebad3SYuan Kang CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; 14691acebad3SYuan Kang int assoc_nents, src_nents, dst_nents = 0; 14701acebad3SYuan Kang struct aead_edesc *edesc; 14711acebad3SYuan Kang dma_addr_t iv_dma = 0; 14721acebad3SYuan Kang int sgc; 14731acebad3SYuan Kang u32 contig = GIV_SRC_CONTIG | GIV_DST_CONTIG; 14741acebad3SYuan Kang int ivsize = crypto_aead_ivsize(aead); 1475643b39b0SYuan Kang bool assoc_chained = false, src_chained = false, dst_chained = false; 1476a299c837SYuan Kang int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; 14770e479300SYuan Kang 1478643b39b0SYuan Kang assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); 1479643b39b0SYuan Kang src_nents = sg_count(req->src, req->cryptlen, &src_chained); 14800e479300SYuan Kang 14811acebad3SYuan Kang if (unlikely(req->dst != req->src)) 1482bbf9c893SHoria Geanta dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize, 1483bbf9c893SHoria Geanta &dst_chained); 14841acebad3SYuan Kang 1485643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, 1486286233e6SHoria Geanta DMA_TO_DEVICE, assoc_chained); 14871acebad3SYuan Kang if (likely(req->src == req->dst)) { 1488643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, 1489643b39b0SYuan Kang DMA_BIDIRECTIONAL, src_chained); 14901acebad3SYuan Kang } else { 1491643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, 1492643b39b0SYuan Kang DMA_TO_DEVICE, src_chained); 1493643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1, 1494643b39b0SYuan Kang DMA_FROM_DEVICE, dst_chained); 14951acebad3SYuan Kang } 14961acebad3SYuan Kang 14971acebad3SYuan Kang /* Check if data are contiguous */ 14981acebad3SYuan Kang iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE); 14991acebad3SYuan Kang if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen != 15001acebad3SYuan Kang iv_dma || src_nents || iv_dma + ivsize != sg_dma_address(req->src)) 15011acebad3SYuan Kang contig &= ~GIV_SRC_CONTIG; 15021acebad3SYuan Kang if (dst_nents || iv_dma + ivsize != sg_dma_address(req->dst)) 15031acebad3SYuan Kang contig &= ~GIV_DST_CONTIG; 15041acebad3SYuan Kang if (unlikely(req->src != req->dst)) { 15051acebad3SYuan Kang dst_nents = dst_nents ? : 1; 1506a299c837SYuan Kang sec4_sg_len += 1; 15071acebad3SYuan Kang } 15081acebad3SYuan Kang if (!(contig & GIV_SRC_CONTIG)) { 15091acebad3SYuan Kang assoc_nents = assoc_nents ? : 1; 15101acebad3SYuan Kang src_nents = src_nents ? : 1; 1511a299c837SYuan Kang sec4_sg_len += assoc_nents + 1 + src_nents; 15121acebad3SYuan Kang if (likely(req->src == req->dst)) 15131acebad3SYuan Kang contig &= ~GIV_DST_CONTIG; 15141acebad3SYuan Kang } 1515a299c837SYuan Kang sec4_sg_len += dst_nents; 15161acebad3SYuan Kang 1517a299c837SYuan Kang sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); 15181acebad3SYuan Kang 15191acebad3SYuan Kang /* allocate space for base edesc and hw desc commands, link tables */ 15201acebad3SYuan Kang edesc = kmalloc(sizeof(struct aead_edesc) + desc_bytes + 1521a299c837SYuan Kang sec4_sg_bytes, GFP_DMA | flags); 15221acebad3SYuan Kang if (!edesc) { 15231acebad3SYuan Kang dev_err(jrdev, "could not allocate extended descriptor\n"); 15241acebad3SYuan Kang return ERR_PTR(-ENOMEM); 15251acebad3SYuan Kang } 15261acebad3SYuan Kang 15271acebad3SYuan Kang edesc->assoc_nents = assoc_nents; 1528643b39b0SYuan Kang edesc->assoc_chained = assoc_chained; 15291acebad3SYuan Kang edesc->src_nents = src_nents; 1530643b39b0SYuan Kang edesc->src_chained = src_chained; 15311acebad3SYuan Kang edesc->dst_nents = dst_nents; 1532643b39b0SYuan Kang edesc->dst_chained = dst_chained; 15331acebad3SYuan Kang edesc->iv_dma = iv_dma; 1534a299c837SYuan Kang edesc->sec4_sg_bytes = sec4_sg_bytes; 1535a299c837SYuan Kang edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + 15361acebad3SYuan Kang desc_bytes; 15371acebad3SYuan Kang *contig_ptr = contig; 15381acebad3SYuan Kang 1539a299c837SYuan Kang sec4_sg_index = 0; 15401acebad3SYuan Kang if (!(contig & GIV_SRC_CONTIG)) { 1541a299c837SYuan Kang sg_to_sec4_sg(req->assoc, assoc_nents, 1542a299c837SYuan Kang edesc->sec4_sg + 1543a299c837SYuan Kang sec4_sg_index, 0); 1544a299c837SYuan Kang sec4_sg_index += assoc_nents; 1545a299c837SYuan Kang dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, 15461acebad3SYuan Kang iv_dma, ivsize, 0); 1547a299c837SYuan Kang sec4_sg_index += 1; 1548a299c837SYuan Kang sg_to_sec4_sg_last(req->src, src_nents, 1549a299c837SYuan Kang edesc->sec4_sg + 1550a299c837SYuan Kang sec4_sg_index, 0); 1551a299c837SYuan Kang sec4_sg_index += src_nents; 15521acebad3SYuan Kang } 15531acebad3SYuan Kang if (unlikely(req->src != req->dst && !(contig & GIV_DST_CONTIG))) { 1554a299c837SYuan Kang dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, 15551acebad3SYuan Kang iv_dma, ivsize, 0); 1556a299c837SYuan Kang sec4_sg_index += 1; 1557a299c837SYuan Kang sg_to_sec4_sg_last(req->dst, dst_nents, 1558a299c837SYuan Kang edesc->sec4_sg + sec4_sg_index, 0); 15591acebad3SYuan Kang } 15601da2be33SRuchika Gupta edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, 15611da2be33SRuchika Gupta sec4_sg_bytes, DMA_TO_DEVICE); 15621acebad3SYuan Kang 15631acebad3SYuan Kang return edesc; 15640e479300SYuan Kang } 15650e479300SYuan Kang 15660e479300SYuan Kang static int aead_givencrypt(struct aead_givcrypt_request *areq) 15670e479300SYuan Kang { 15680e479300SYuan Kang struct aead_request *req = &areq->areq; 15690e479300SYuan Kang struct aead_edesc *edesc; 15700e479300SYuan Kang struct crypto_aead *aead = crypto_aead_reqtfm(req); 15718e8ec596SKim Phillips struct caam_ctx *ctx = crypto_aead_ctx(aead); 15728e8ec596SKim Phillips struct device *jrdev = ctx->jrdev; 15731acebad3SYuan Kang u32 contig; 15748e8ec596SKim Phillips u32 *desc; 15751acebad3SYuan Kang int ret = 0; 15768e8ec596SKim Phillips 15778e8ec596SKim Phillips /* allocate extended descriptor */ 15781acebad3SYuan Kang edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN * 15791acebad3SYuan Kang CAAM_CMD_SZ, &contig); 15801acebad3SYuan Kang 15818e8ec596SKim Phillips if (IS_ERR(edesc)) 15828e8ec596SKim Phillips return PTR_ERR(edesc); 15838e8ec596SKim Phillips 15841acebad3SYuan Kang #ifdef DEBUG 1585514df281SAlex Porosanu print_hex_dump(KERN_ERR, "giv src@"__stringify(__LINE__)": ", 15861acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src), 15871acebad3SYuan Kang req->cryptlen, 1); 15881acebad3SYuan Kang #endif 15891acebad3SYuan Kang 15901acebad3SYuan Kang /* Create and submit job descriptor*/ 15911acebad3SYuan Kang init_aead_giv_job(ctx->sh_desc_givenc, 15921acebad3SYuan Kang ctx->sh_desc_givenc_dma, edesc, req, contig); 15931acebad3SYuan Kang #ifdef DEBUG 1594514df281SAlex Porosanu print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ", 15951acebad3SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc, 15961acebad3SYuan Kang desc_bytes(edesc->hw_desc), 1); 15971acebad3SYuan Kang #endif 15981acebad3SYuan Kang 15998e8ec596SKim Phillips desc = edesc->hw_desc; 16001acebad3SYuan Kang ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req); 16011acebad3SYuan Kang if (!ret) { 16021acebad3SYuan Kang ret = -EINPROGRESS; 16031acebad3SYuan Kang } else { 16041acebad3SYuan Kang aead_unmap(jrdev, edesc, req); 16051acebad3SYuan Kang kfree(edesc); 16061acebad3SYuan Kang } 16078e8ec596SKim Phillips 16081acebad3SYuan Kang return ret; 16098e8ec596SKim Phillips } 16108e8ec596SKim Phillips 1611ae4a825fSHoria Geanta static int aead_null_givencrypt(struct aead_givcrypt_request *areq) 1612ae4a825fSHoria Geanta { 1613ae4a825fSHoria Geanta return aead_encrypt(&areq->areq); 1614ae4a825fSHoria Geanta } 1615ae4a825fSHoria Geanta 1616acdca31dSYuan Kang /* 1617acdca31dSYuan Kang * allocate and map the ablkcipher extended descriptor for ablkcipher 1618acdca31dSYuan Kang */ 1619acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request 1620acdca31dSYuan Kang *req, int desc_bytes, 1621acdca31dSYuan Kang bool *iv_contig_out) 1622acdca31dSYuan Kang { 1623acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 1624acdca31dSYuan Kang struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); 1625acdca31dSYuan Kang struct device *jrdev = ctx->jrdev; 1626acdca31dSYuan Kang gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | 1627acdca31dSYuan Kang CRYPTO_TFM_REQ_MAY_SLEEP)) ? 1628acdca31dSYuan Kang GFP_KERNEL : GFP_ATOMIC; 1629a299c837SYuan Kang int src_nents, dst_nents = 0, sec4_sg_bytes; 1630acdca31dSYuan Kang struct ablkcipher_edesc *edesc; 1631acdca31dSYuan Kang dma_addr_t iv_dma = 0; 1632acdca31dSYuan Kang bool iv_contig = false; 1633acdca31dSYuan Kang int sgc; 1634acdca31dSYuan Kang int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 1635643b39b0SYuan Kang bool src_chained = false, dst_chained = false; 1636a299c837SYuan Kang int sec4_sg_index; 1637acdca31dSYuan Kang 1638643b39b0SYuan Kang src_nents = sg_count(req->src, req->nbytes, &src_chained); 1639acdca31dSYuan Kang 1640643b39b0SYuan Kang if (req->dst != req->src) 1641643b39b0SYuan Kang dst_nents = sg_count(req->dst, req->nbytes, &dst_chained); 1642acdca31dSYuan Kang 1643acdca31dSYuan Kang if (likely(req->src == req->dst)) { 1644643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, 1645643b39b0SYuan Kang DMA_BIDIRECTIONAL, src_chained); 1646acdca31dSYuan Kang } else { 1647643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, 1648643b39b0SYuan Kang DMA_TO_DEVICE, src_chained); 1649643b39b0SYuan Kang sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1, 1650643b39b0SYuan Kang DMA_FROM_DEVICE, dst_chained); 1651acdca31dSYuan Kang } 1652acdca31dSYuan Kang 1653acdca31dSYuan Kang /* 1654acdca31dSYuan Kang * Check if iv can be contiguous with source and destination. 1655acdca31dSYuan Kang * If so, include it. If not, create scatterlist. 1656acdca31dSYuan Kang */ 1657acdca31dSYuan Kang iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE); 1658acdca31dSYuan Kang if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src)) 1659acdca31dSYuan Kang iv_contig = true; 1660acdca31dSYuan Kang else 1661acdca31dSYuan Kang src_nents = src_nents ? : 1; 1662a299c837SYuan Kang sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) * 1663a299c837SYuan Kang sizeof(struct sec4_sg_entry); 1664acdca31dSYuan Kang 1665acdca31dSYuan Kang /* allocate space for base edesc and hw desc commands, link tables */ 1666acdca31dSYuan Kang edesc = kmalloc(sizeof(struct ablkcipher_edesc) + desc_bytes + 1667a299c837SYuan Kang sec4_sg_bytes, GFP_DMA | flags); 1668acdca31dSYuan Kang if (!edesc) { 1669acdca31dSYuan Kang dev_err(jrdev, "could not allocate extended descriptor\n"); 1670acdca31dSYuan Kang return ERR_PTR(-ENOMEM); 1671acdca31dSYuan Kang } 1672acdca31dSYuan Kang 1673acdca31dSYuan Kang edesc->src_nents = src_nents; 1674643b39b0SYuan Kang edesc->src_chained = src_chained; 1675acdca31dSYuan Kang edesc->dst_nents = dst_nents; 1676643b39b0SYuan Kang edesc->dst_chained = dst_chained; 1677a299c837SYuan Kang edesc->sec4_sg_bytes = sec4_sg_bytes; 1678a299c837SYuan Kang edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) + 1679acdca31dSYuan Kang desc_bytes; 1680acdca31dSYuan Kang 1681a299c837SYuan Kang sec4_sg_index = 0; 1682acdca31dSYuan Kang if (!iv_contig) { 1683a299c837SYuan Kang dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0); 1684a299c837SYuan Kang sg_to_sec4_sg_last(req->src, src_nents, 1685a299c837SYuan Kang edesc->sec4_sg + 1, 0); 1686a299c837SYuan Kang sec4_sg_index += 1 + src_nents; 1687acdca31dSYuan Kang } 1688acdca31dSYuan Kang 1689643b39b0SYuan Kang if (dst_nents) { 1690a299c837SYuan Kang sg_to_sec4_sg_last(req->dst, dst_nents, 1691a299c837SYuan Kang edesc->sec4_sg + sec4_sg_index, 0); 1692acdca31dSYuan Kang } 1693acdca31dSYuan Kang 1694a299c837SYuan Kang edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, 1695a299c837SYuan Kang sec4_sg_bytes, DMA_TO_DEVICE); 1696acdca31dSYuan Kang edesc->iv_dma = iv_dma; 1697acdca31dSYuan Kang 1698acdca31dSYuan Kang #ifdef DEBUG 1699514df281SAlex Porosanu print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ", 1700a299c837SYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg, 1701a299c837SYuan Kang sec4_sg_bytes, 1); 1702acdca31dSYuan Kang #endif 1703acdca31dSYuan Kang 1704acdca31dSYuan Kang *iv_contig_out = iv_contig; 1705acdca31dSYuan Kang return edesc; 1706acdca31dSYuan Kang } 1707acdca31dSYuan Kang 1708acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req) 1709acdca31dSYuan Kang { 1710acdca31dSYuan Kang struct ablkcipher_edesc *edesc; 1711acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 1712acdca31dSYuan Kang struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); 1713acdca31dSYuan Kang struct device *jrdev = ctx->jrdev; 1714acdca31dSYuan Kang bool iv_contig; 1715acdca31dSYuan Kang u32 *desc; 1716acdca31dSYuan Kang int ret = 0; 1717acdca31dSYuan Kang 1718acdca31dSYuan Kang /* allocate extended descriptor */ 1719acdca31dSYuan Kang edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN * 1720acdca31dSYuan Kang CAAM_CMD_SZ, &iv_contig); 1721acdca31dSYuan Kang if (IS_ERR(edesc)) 1722acdca31dSYuan Kang return PTR_ERR(edesc); 1723acdca31dSYuan Kang 1724acdca31dSYuan Kang /* Create and submit job descriptor*/ 1725acdca31dSYuan Kang init_ablkcipher_job(ctx->sh_desc_enc, 1726acdca31dSYuan Kang ctx->sh_desc_enc_dma, edesc, req, iv_contig); 1727acdca31dSYuan Kang #ifdef DEBUG 1728514df281SAlex Porosanu print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ", 1729acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc, 1730acdca31dSYuan Kang desc_bytes(edesc->hw_desc), 1); 1731acdca31dSYuan Kang #endif 1732acdca31dSYuan Kang desc = edesc->hw_desc; 1733acdca31dSYuan Kang ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req); 1734acdca31dSYuan Kang 1735acdca31dSYuan Kang if (!ret) { 1736acdca31dSYuan Kang ret = -EINPROGRESS; 1737acdca31dSYuan Kang } else { 1738acdca31dSYuan Kang ablkcipher_unmap(jrdev, edesc, req); 1739acdca31dSYuan Kang kfree(edesc); 1740acdca31dSYuan Kang } 1741acdca31dSYuan Kang 1742acdca31dSYuan Kang return ret; 1743acdca31dSYuan Kang } 1744acdca31dSYuan Kang 1745acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req) 1746acdca31dSYuan Kang { 1747acdca31dSYuan Kang struct ablkcipher_edesc *edesc; 1748acdca31dSYuan Kang struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); 1749acdca31dSYuan Kang struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); 1750acdca31dSYuan Kang struct device *jrdev = ctx->jrdev; 1751acdca31dSYuan Kang bool iv_contig; 1752acdca31dSYuan Kang u32 *desc; 1753acdca31dSYuan Kang int ret = 0; 1754acdca31dSYuan Kang 1755acdca31dSYuan Kang /* allocate extended descriptor */ 1756acdca31dSYuan Kang edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN * 1757acdca31dSYuan Kang CAAM_CMD_SZ, &iv_contig); 1758acdca31dSYuan Kang if (IS_ERR(edesc)) 1759acdca31dSYuan Kang return PTR_ERR(edesc); 1760acdca31dSYuan Kang 1761acdca31dSYuan Kang /* Create and submit job descriptor*/ 1762acdca31dSYuan Kang init_ablkcipher_job(ctx->sh_desc_dec, 1763acdca31dSYuan Kang ctx->sh_desc_dec_dma, edesc, req, iv_contig); 1764acdca31dSYuan Kang desc = edesc->hw_desc; 1765acdca31dSYuan Kang #ifdef DEBUG 1766514df281SAlex Porosanu print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ", 1767acdca31dSYuan Kang DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc, 1768acdca31dSYuan Kang desc_bytes(edesc->hw_desc), 1); 1769acdca31dSYuan Kang #endif 1770acdca31dSYuan Kang 1771acdca31dSYuan Kang ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req); 1772acdca31dSYuan Kang if (!ret) { 1773acdca31dSYuan Kang ret = -EINPROGRESS; 1774acdca31dSYuan Kang } else { 1775acdca31dSYuan Kang ablkcipher_unmap(jrdev, edesc, req); 1776acdca31dSYuan Kang kfree(edesc); 1777acdca31dSYuan Kang } 1778acdca31dSYuan Kang 1779acdca31dSYuan Kang return ret; 1780acdca31dSYuan Kang } 1781acdca31dSYuan Kang 1782885e9e2fSYuan Kang #define template_aead template_u.aead 1783acdca31dSYuan Kang #define template_ablkcipher template_u.ablkcipher 17848e8ec596SKim Phillips struct caam_alg_template { 17858e8ec596SKim Phillips char name[CRYPTO_MAX_ALG_NAME]; 17868e8ec596SKim Phillips char driver_name[CRYPTO_MAX_ALG_NAME]; 17878e8ec596SKim Phillips unsigned int blocksize; 1788885e9e2fSYuan Kang u32 type; 1789885e9e2fSYuan Kang union { 1790885e9e2fSYuan Kang struct ablkcipher_alg ablkcipher; 17918e8ec596SKim Phillips struct aead_alg aead; 1792885e9e2fSYuan Kang struct blkcipher_alg blkcipher; 1793885e9e2fSYuan Kang struct cipher_alg cipher; 1794885e9e2fSYuan Kang struct compress_alg compress; 1795885e9e2fSYuan Kang struct rng_alg rng; 1796885e9e2fSYuan Kang } template_u; 17978e8ec596SKim Phillips u32 class1_alg_type; 17988e8ec596SKim Phillips u32 class2_alg_type; 17998e8ec596SKim Phillips u32 alg_op; 18008e8ec596SKim Phillips }; 18018e8ec596SKim Phillips 18028e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = { 1803246bbedbSHoria Geanta /* single-pass ipsec_esp descriptor */ 18048e8ec596SKim Phillips { 1805ae4a825fSHoria Geanta .name = "authenc(hmac(md5),ecb(cipher_null))", 1806ae4a825fSHoria Geanta .driver_name = "authenc-hmac-md5-ecb-cipher_null-caam", 1807ae4a825fSHoria Geanta .blocksize = NULL_BLOCK_SIZE, 1808ae4a825fSHoria Geanta .type = CRYPTO_ALG_TYPE_AEAD, 1809ae4a825fSHoria Geanta .template_aead = { 1810ae4a825fSHoria Geanta .setkey = aead_setkey, 1811ae4a825fSHoria Geanta .setauthsize = aead_setauthsize, 1812ae4a825fSHoria Geanta .encrypt = aead_encrypt, 1813ae4a825fSHoria Geanta .decrypt = aead_decrypt, 1814ae4a825fSHoria Geanta .givencrypt = aead_null_givencrypt, 1815ae4a825fSHoria Geanta .geniv = "<built-in>", 1816ae4a825fSHoria Geanta .ivsize = NULL_IV_SIZE, 1817ae4a825fSHoria Geanta .maxauthsize = MD5_DIGEST_SIZE, 1818ae4a825fSHoria Geanta }, 1819ae4a825fSHoria Geanta .class1_alg_type = 0, 1820ae4a825fSHoria Geanta .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP, 1821ae4a825fSHoria Geanta .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC, 1822ae4a825fSHoria Geanta }, 1823ae4a825fSHoria Geanta { 1824ae4a825fSHoria Geanta .name = "authenc(hmac(sha1),ecb(cipher_null))", 1825ae4a825fSHoria Geanta .driver_name = "authenc-hmac-sha1-ecb-cipher_null-caam", 1826ae4a825fSHoria Geanta .blocksize = NULL_BLOCK_SIZE, 1827ae4a825fSHoria Geanta .type = CRYPTO_ALG_TYPE_AEAD, 1828ae4a825fSHoria Geanta .template_aead = { 1829ae4a825fSHoria Geanta .setkey = aead_setkey, 1830ae4a825fSHoria Geanta .setauthsize = aead_setauthsize, 1831ae4a825fSHoria Geanta .encrypt = aead_encrypt, 1832ae4a825fSHoria Geanta .decrypt = aead_decrypt, 1833ae4a825fSHoria Geanta .givencrypt = aead_null_givencrypt, 1834ae4a825fSHoria Geanta .geniv = "<built-in>", 1835ae4a825fSHoria Geanta .ivsize = NULL_IV_SIZE, 1836ae4a825fSHoria Geanta .maxauthsize = SHA1_DIGEST_SIZE, 1837ae4a825fSHoria Geanta }, 1838ae4a825fSHoria Geanta .class1_alg_type = 0, 1839ae4a825fSHoria Geanta .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, 1840ae4a825fSHoria Geanta .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, 1841ae4a825fSHoria Geanta }, 1842ae4a825fSHoria Geanta { 1843ae4a825fSHoria Geanta .name = "authenc(hmac(sha224),ecb(cipher_null))", 1844ae4a825fSHoria Geanta .driver_name = "authenc-hmac-sha224-ecb-cipher_null-caam", 1845ae4a825fSHoria Geanta .blocksize = NULL_BLOCK_SIZE, 1846ae4a825fSHoria Geanta .type = CRYPTO_ALG_TYPE_AEAD, 1847ae4a825fSHoria Geanta .template_aead = { 1848ae4a825fSHoria Geanta .setkey = aead_setkey, 1849ae4a825fSHoria Geanta .setauthsize = aead_setauthsize, 1850ae4a825fSHoria Geanta .encrypt = aead_encrypt, 1851ae4a825fSHoria Geanta .decrypt = aead_decrypt, 1852ae4a825fSHoria Geanta .givencrypt = aead_null_givencrypt, 1853ae4a825fSHoria Geanta .geniv = "<built-in>", 1854ae4a825fSHoria Geanta .ivsize = NULL_IV_SIZE, 1855ae4a825fSHoria Geanta .maxauthsize = SHA224_DIGEST_SIZE, 1856ae4a825fSHoria Geanta }, 1857ae4a825fSHoria Geanta .class1_alg_type = 0, 1858ae4a825fSHoria Geanta .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 1859ae4a825fSHoria Geanta OP_ALG_AAI_HMAC_PRECOMP, 1860ae4a825fSHoria Geanta .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, 1861ae4a825fSHoria Geanta }, 1862ae4a825fSHoria Geanta { 1863ae4a825fSHoria Geanta .name = "authenc(hmac(sha256),ecb(cipher_null))", 1864ae4a825fSHoria Geanta .driver_name = "authenc-hmac-sha256-ecb-cipher_null-caam", 1865ae4a825fSHoria Geanta .blocksize = NULL_BLOCK_SIZE, 1866ae4a825fSHoria Geanta .type = CRYPTO_ALG_TYPE_AEAD, 1867ae4a825fSHoria Geanta .template_aead = { 1868ae4a825fSHoria Geanta .setkey = aead_setkey, 1869ae4a825fSHoria Geanta .setauthsize = aead_setauthsize, 1870ae4a825fSHoria Geanta .encrypt = aead_encrypt, 1871ae4a825fSHoria Geanta .decrypt = aead_decrypt, 1872ae4a825fSHoria Geanta .givencrypt = aead_null_givencrypt, 1873ae4a825fSHoria Geanta .geniv = "<built-in>", 1874ae4a825fSHoria Geanta .ivsize = NULL_IV_SIZE, 1875ae4a825fSHoria Geanta .maxauthsize = SHA256_DIGEST_SIZE, 1876ae4a825fSHoria Geanta }, 1877ae4a825fSHoria Geanta .class1_alg_type = 0, 1878ae4a825fSHoria Geanta .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 1879ae4a825fSHoria Geanta OP_ALG_AAI_HMAC_PRECOMP, 1880ae4a825fSHoria Geanta .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, 1881ae4a825fSHoria Geanta }, 1882ae4a825fSHoria Geanta { 1883ae4a825fSHoria Geanta .name = "authenc(hmac(sha384),ecb(cipher_null))", 1884ae4a825fSHoria Geanta .driver_name = "authenc-hmac-sha384-ecb-cipher_null-caam", 1885ae4a825fSHoria Geanta .blocksize = NULL_BLOCK_SIZE, 1886ae4a825fSHoria Geanta .type = CRYPTO_ALG_TYPE_AEAD, 1887ae4a825fSHoria Geanta .template_aead = { 1888ae4a825fSHoria Geanta .setkey = aead_setkey, 1889ae4a825fSHoria Geanta .setauthsize = aead_setauthsize, 1890ae4a825fSHoria Geanta .encrypt = aead_encrypt, 1891ae4a825fSHoria Geanta .decrypt = aead_decrypt, 1892ae4a825fSHoria Geanta .givencrypt = aead_null_givencrypt, 1893ae4a825fSHoria Geanta .geniv = "<built-in>", 1894ae4a825fSHoria Geanta .ivsize = NULL_IV_SIZE, 1895ae4a825fSHoria Geanta .maxauthsize = SHA384_DIGEST_SIZE, 1896ae4a825fSHoria Geanta }, 1897ae4a825fSHoria Geanta .class1_alg_type = 0, 1898ae4a825fSHoria Geanta .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 1899ae4a825fSHoria Geanta OP_ALG_AAI_HMAC_PRECOMP, 1900ae4a825fSHoria Geanta .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, 1901ae4a825fSHoria Geanta }, 1902ae4a825fSHoria Geanta { 1903ae4a825fSHoria Geanta .name = "authenc(hmac(sha512),ecb(cipher_null))", 1904ae4a825fSHoria Geanta .driver_name = "authenc-hmac-sha512-ecb-cipher_null-caam", 1905ae4a825fSHoria Geanta .blocksize = NULL_BLOCK_SIZE, 1906ae4a825fSHoria Geanta .type = CRYPTO_ALG_TYPE_AEAD, 1907ae4a825fSHoria Geanta .template_aead = { 1908ae4a825fSHoria Geanta .setkey = aead_setkey, 1909ae4a825fSHoria Geanta .setauthsize = aead_setauthsize, 1910ae4a825fSHoria Geanta .encrypt = aead_encrypt, 1911ae4a825fSHoria Geanta .decrypt = aead_decrypt, 1912ae4a825fSHoria Geanta .givencrypt = aead_null_givencrypt, 1913ae4a825fSHoria Geanta .geniv = "<built-in>", 1914ae4a825fSHoria Geanta .ivsize = NULL_IV_SIZE, 1915ae4a825fSHoria Geanta .maxauthsize = SHA512_DIGEST_SIZE, 1916ae4a825fSHoria Geanta }, 1917ae4a825fSHoria Geanta .class1_alg_type = 0, 1918ae4a825fSHoria Geanta .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 1919ae4a825fSHoria Geanta OP_ALG_AAI_HMAC_PRECOMP, 1920ae4a825fSHoria Geanta .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, 1921ae4a825fSHoria Geanta }, 1922ae4a825fSHoria Geanta { 19238b4d43a4SKim Phillips .name = "authenc(hmac(md5),cbc(aes))", 19248b4d43a4SKim Phillips .driver_name = "authenc-hmac-md5-cbc-aes-caam", 19258b4d43a4SKim Phillips .blocksize = AES_BLOCK_SIZE, 19268b4d43a4SKim Phillips .type = CRYPTO_ALG_TYPE_AEAD, 19278b4d43a4SKim Phillips .template_aead = { 19288b4d43a4SKim Phillips .setkey = aead_setkey, 19298b4d43a4SKim Phillips .setauthsize = aead_setauthsize, 19308b4d43a4SKim Phillips .encrypt = aead_encrypt, 19318b4d43a4SKim Phillips .decrypt = aead_decrypt, 19328b4d43a4SKim Phillips .givencrypt = aead_givencrypt, 19338b4d43a4SKim Phillips .geniv = "<built-in>", 19348b4d43a4SKim Phillips .ivsize = AES_BLOCK_SIZE, 19358b4d43a4SKim Phillips .maxauthsize = MD5_DIGEST_SIZE, 19368b4d43a4SKim Phillips }, 19378b4d43a4SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 19388b4d43a4SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP, 19398b4d43a4SKim Phillips .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC, 19408b4d43a4SKim Phillips }, 19418b4d43a4SKim Phillips { 19428e8ec596SKim Phillips .name = "authenc(hmac(sha1),cbc(aes))", 19438e8ec596SKim Phillips .driver_name = "authenc-hmac-sha1-cbc-aes-caam", 19448e8ec596SKim Phillips .blocksize = AES_BLOCK_SIZE, 1945885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 1946885e9e2fSYuan Kang .template_aead = { 19470e479300SYuan Kang .setkey = aead_setkey, 19480e479300SYuan Kang .setauthsize = aead_setauthsize, 19490e479300SYuan Kang .encrypt = aead_encrypt, 19500e479300SYuan Kang .decrypt = aead_decrypt, 19510e479300SYuan Kang .givencrypt = aead_givencrypt, 19528e8ec596SKim Phillips .geniv = "<built-in>", 19538e8ec596SKim Phillips .ivsize = AES_BLOCK_SIZE, 19548e8ec596SKim Phillips .maxauthsize = SHA1_DIGEST_SIZE, 19558e8ec596SKim Phillips }, 19568e8ec596SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 19578e8ec596SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, 19588e8ec596SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, 19598e8ec596SKim Phillips }, 19608e8ec596SKim Phillips { 1961e863f9ccSHemant Agrawal .name = "authenc(hmac(sha224),cbc(aes))", 1962e863f9ccSHemant Agrawal .driver_name = "authenc-hmac-sha224-cbc-aes-caam", 1963e863f9ccSHemant Agrawal .blocksize = AES_BLOCK_SIZE, 1964cb7d5662SVakul Garg .type = CRYPTO_ALG_TYPE_AEAD, 1965e863f9ccSHemant Agrawal .template_aead = { 1966e863f9ccSHemant Agrawal .setkey = aead_setkey, 1967e863f9ccSHemant Agrawal .setauthsize = aead_setauthsize, 1968e863f9ccSHemant Agrawal .encrypt = aead_encrypt, 1969e863f9ccSHemant Agrawal .decrypt = aead_decrypt, 1970e863f9ccSHemant Agrawal .givencrypt = aead_givencrypt, 1971e863f9ccSHemant Agrawal .geniv = "<built-in>", 1972e863f9ccSHemant Agrawal .ivsize = AES_BLOCK_SIZE, 1973e863f9ccSHemant Agrawal .maxauthsize = SHA224_DIGEST_SIZE, 1974e863f9ccSHemant Agrawal }, 1975e863f9ccSHemant Agrawal .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 1976e863f9ccSHemant Agrawal .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 1977e863f9ccSHemant Agrawal OP_ALG_AAI_HMAC_PRECOMP, 1978e863f9ccSHemant Agrawal .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, 1979e863f9ccSHemant Agrawal }, 1980e863f9ccSHemant Agrawal { 19818e8ec596SKim Phillips .name = "authenc(hmac(sha256),cbc(aes))", 19828e8ec596SKim Phillips .driver_name = "authenc-hmac-sha256-cbc-aes-caam", 19838e8ec596SKim Phillips .blocksize = AES_BLOCK_SIZE, 1984885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 1985885e9e2fSYuan Kang .template_aead = { 19860e479300SYuan Kang .setkey = aead_setkey, 19870e479300SYuan Kang .setauthsize = aead_setauthsize, 19880e479300SYuan Kang .encrypt = aead_encrypt, 19890e479300SYuan Kang .decrypt = aead_decrypt, 19900e479300SYuan Kang .givencrypt = aead_givencrypt, 19918e8ec596SKim Phillips .geniv = "<built-in>", 19928e8ec596SKim Phillips .ivsize = AES_BLOCK_SIZE, 19938e8ec596SKim Phillips .maxauthsize = SHA256_DIGEST_SIZE, 19948e8ec596SKim Phillips }, 19958e8ec596SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 19968e8ec596SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 19978e8ec596SKim Phillips OP_ALG_AAI_HMAC_PRECOMP, 19988e8ec596SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, 19998e8ec596SKim Phillips }, 20008e8ec596SKim Phillips { 2001e863f9ccSHemant Agrawal .name = "authenc(hmac(sha384),cbc(aes))", 2002e863f9ccSHemant Agrawal .driver_name = "authenc-hmac-sha384-cbc-aes-caam", 2003e863f9ccSHemant Agrawal .blocksize = AES_BLOCK_SIZE, 2004cb7d5662SVakul Garg .type = CRYPTO_ALG_TYPE_AEAD, 2005e863f9ccSHemant Agrawal .template_aead = { 2006e863f9ccSHemant Agrawal .setkey = aead_setkey, 2007e863f9ccSHemant Agrawal .setauthsize = aead_setauthsize, 2008e863f9ccSHemant Agrawal .encrypt = aead_encrypt, 2009e863f9ccSHemant Agrawal .decrypt = aead_decrypt, 2010e863f9ccSHemant Agrawal .givencrypt = aead_givencrypt, 2011e863f9ccSHemant Agrawal .geniv = "<built-in>", 2012e863f9ccSHemant Agrawal .ivsize = AES_BLOCK_SIZE, 2013e863f9ccSHemant Agrawal .maxauthsize = SHA384_DIGEST_SIZE, 2014e863f9ccSHemant Agrawal }, 2015e863f9ccSHemant Agrawal .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 2016e863f9ccSHemant Agrawal .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 2017e863f9ccSHemant Agrawal OP_ALG_AAI_HMAC_PRECOMP, 2018e863f9ccSHemant Agrawal .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, 2019e863f9ccSHemant Agrawal }, 2020e863f9ccSHemant Agrawal 2021e863f9ccSHemant Agrawal { 20224427b1b4SKim Phillips .name = "authenc(hmac(sha512),cbc(aes))", 20234427b1b4SKim Phillips .driver_name = "authenc-hmac-sha512-cbc-aes-caam", 20244427b1b4SKim Phillips .blocksize = AES_BLOCK_SIZE, 2025885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2026885e9e2fSYuan Kang .template_aead = { 20270e479300SYuan Kang .setkey = aead_setkey, 20280e479300SYuan Kang .setauthsize = aead_setauthsize, 20290e479300SYuan Kang .encrypt = aead_encrypt, 20300e479300SYuan Kang .decrypt = aead_decrypt, 20310e479300SYuan Kang .givencrypt = aead_givencrypt, 20324427b1b4SKim Phillips .geniv = "<built-in>", 20334427b1b4SKim Phillips .ivsize = AES_BLOCK_SIZE, 20344427b1b4SKim Phillips .maxauthsize = SHA512_DIGEST_SIZE, 20354427b1b4SKim Phillips }, 20364427b1b4SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 20374427b1b4SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 20384427b1b4SKim Phillips OP_ALG_AAI_HMAC_PRECOMP, 20394427b1b4SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, 20404427b1b4SKim Phillips }, 20414427b1b4SKim Phillips { 20428b4d43a4SKim Phillips .name = "authenc(hmac(md5),cbc(des3_ede))", 20438b4d43a4SKim Phillips .driver_name = "authenc-hmac-md5-cbc-des3_ede-caam", 20448b4d43a4SKim Phillips .blocksize = DES3_EDE_BLOCK_SIZE, 20458b4d43a4SKim Phillips .type = CRYPTO_ALG_TYPE_AEAD, 20468b4d43a4SKim Phillips .template_aead = { 20478b4d43a4SKim Phillips .setkey = aead_setkey, 20488b4d43a4SKim Phillips .setauthsize = aead_setauthsize, 20498b4d43a4SKim Phillips .encrypt = aead_encrypt, 20508b4d43a4SKim Phillips .decrypt = aead_decrypt, 20518b4d43a4SKim Phillips .givencrypt = aead_givencrypt, 20528b4d43a4SKim Phillips .geniv = "<built-in>", 20538b4d43a4SKim Phillips .ivsize = DES3_EDE_BLOCK_SIZE, 20548b4d43a4SKim Phillips .maxauthsize = MD5_DIGEST_SIZE, 20558b4d43a4SKim Phillips }, 20568b4d43a4SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 20578b4d43a4SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP, 20588b4d43a4SKim Phillips .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC, 20598b4d43a4SKim Phillips }, 20608b4d43a4SKim Phillips { 20618e8ec596SKim Phillips .name = "authenc(hmac(sha1),cbc(des3_ede))", 20628e8ec596SKim Phillips .driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam", 20638e8ec596SKim Phillips .blocksize = DES3_EDE_BLOCK_SIZE, 2064885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2065885e9e2fSYuan Kang .template_aead = { 20660e479300SYuan Kang .setkey = aead_setkey, 20670e479300SYuan Kang .setauthsize = aead_setauthsize, 20680e479300SYuan Kang .encrypt = aead_encrypt, 20690e479300SYuan Kang .decrypt = aead_decrypt, 20700e479300SYuan Kang .givencrypt = aead_givencrypt, 20718e8ec596SKim Phillips .geniv = "<built-in>", 20728e8ec596SKim Phillips .ivsize = DES3_EDE_BLOCK_SIZE, 20738e8ec596SKim Phillips .maxauthsize = SHA1_DIGEST_SIZE, 20748e8ec596SKim Phillips }, 20758e8ec596SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 20768e8ec596SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, 20778e8ec596SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, 20788e8ec596SKim Phillips }, 20798e8ec596SKim Phillips { 2080e863f9ccSHemant Agrawal .name = "authenc(hmac(sha224),cbc(des3_ede))", 2081e863f9ccSHemant Agrawal .driver_name = "authenc-hmac-sha224-cbc-des3_ede-caam", 2082e863f9ccSHemant Agrawal .blocksize = DES3_EDE_BLOCK_SIZE, 2083cb7d5662SVakul Garg .type = CRYPTO_ALG_TYPE_AEAD, 2084e863f9ccSHemant Agrawal .template_aead = { 2085e863f9ccSHemant Agrawal .setkey = aead_setkey, 2086e863f9ccSHemant Agrawal .setauthsize = aead_setauthsize, 2087e863f9ccSHemant Agrawal .encrypt = aead_encrypt, 2088e863f9ccSHemant Agrawal .decrypt = aead_decrypt, 2089e863f9ccSHemant Agrawal .givencrypt = aead_givencrypt, 2090e863f9ccSHemant Agrawal .geniv = "<built-in>", 2091e863f9ccSHemant Agrawal .ivsize = DES3_EDE_BLOCK_SIZE, 2092e863f9ccSHemant Agrawal .maxauthsize = SHA224_DIGEST_SIZE, 2093e863f9ccSHemant Agrawal }, 2094e863f9ccSHemant Agrawal .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 2095e863f9ccSHemant Agrawal .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 2096e863f9ccSHemant Agrawal OP_ALG_AAI_HMAC_PRECOMP, 2097e863f9ccSHemant Agrawal .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, 2098e863f9ccSHemant Agrawal }, 2099e863f9ccSHemant Agrawal { 21008e8ec596SKim Phillips .name = "authenc(hmac(sha256),cbc(des3_ede))", 21018e8ec596SKim Phillips .driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam", 21028e8ec596SKim Phillips .blocksize = DES3_EDE_BLOCK_SIZE, 2103885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2104885e9e2fSYuan Kang .template_aead = { 21050e479300SYuan Kang .setkey = aead_setkey, 21060e479300SYuan Kang .setauthsize = aead_setauthsize, 21070e479300SYuan Kang .encrypt = aead_encrypt, 21080e479300SYuan Kang .decrypt = aead_decrypt, 21090e479300SYuan Kang .givencrypt = aead_givencrypt, 21108e8ec596SKim Phillips .geniv = "<built-in>", 21118e8ec596SKim Phillips .ivsize = DES3_EDE_BLOCK_SIZE, 21128e8ec596SKim Phillips .maxauthsize = SHA256_DIGEST_SIZE, 21138e8ec596SKim Phillips }, 21148e8ec596SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 21158e8ec596SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 21168e8ec596SKim Phillips OP_ALG_AAI_HMAC_PRECOMP, 21178e8ec596SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, 21188e8ec596SKim Phillips }, 21198e8ec596SKim Phillips { 2120e863f9ccSHemant Agrawal .name = "authenc(hmac(sha384),cbc(des3_ede))", 2121e863f9ccSHemant Agrawal .driver_name = "authenc-hmac-sha384-cbc-des3_ede-caam", 2122e863f9ccSHemant Agrawal .blocksize = DES3_EDE_BLOCK_SIZE, 2123cb7d5662SVakul Garg .type = CRYPTO_ALG_TYPE_AEAD, 2124e863f9ccSHemant Agrawal .template_aead = { 2125e863f9ccSHemant Agrawal .setkey = aead_setkey, 2126e863f9ccSHemant Agrawal .setauthsize = aead_setauthsize, 2127e863f9ccSHemant Agrawal .encrypt = aead_encrypt, 2128e863f9ccSHemant Agrawal .decrypt = aead_decrypt, 2129e863f9ccSHemant Agrawal .givencrypt = aead_givencrypt, 2130e863f9ccSHemant Agrawal .geniv = "<built-in>", 2131e863f9ccSHemant Agrawal .ivsize = DES3_EDE_BLOCK_SIZE, 2132e863f9ccSHemant Agrawal .maxauthsize = SHA384_DIGEST_SIZE, 2133e863f9ccSHemant Agrawal }, 2134e863f9ccSHemant Agrawal .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 2135e863f9ccSHemant Agrawal .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 2136e863f9ccSHemant Agrawal OP_ALG_AAI_HMAC_PRECOMP, 2137e863f9ccSHemant Agrawal .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, 2138e863f9ccSHemant Agrawal }, 2139e863f9ccSHemant Agrawal { 21404427b1b4SKim Phillips .name = "authenc(hmac(sha512),cbc(des3_ede))", 21414427b1b4SKim Phillips .driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam", 21424427b1b4SKim Phillips .blocksize = DES3_EDE_BLOCK_SIZE, 2143885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2144885e9e2fSYuan Kang .template_aead = { 21450e479300SYuan Kang .setkey = aead_setkey, 21460e479300SYuan Kang .setauthsize = aead_setauthsize, 21470e479300SYuan Kang .encrypt = aead_encrypt, 21480e479300SYuan Kang .decrypt = aead_decrypt, 21490e479300SYuan Kang .givencrypt = aead_givencrypt, 21504427b1b4SKim Phillips .geniv = "<built-in>", 21514427b1b4SKim Phillips .ivsize = DES3_EDE_BLOCK_SIZE, 21524427b1b4SKim Phillips .maxauthsize = SHA512_DIGEST_SIZE, 21534427b1b4SKim Phillips }, 21544427b1b4SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 21554427b1b4SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 21564427b1b4SKim Phillips OP_ALG_AAI_HMAC_PRECOMP, 21574427b1b4SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, 21584427b1b4SKim Phillips }, 21594427b1b4SKim Phillips { 21608b4d43a4SKim Phillips .name = "authenc(hmac(md5),cbc(des))", 21618b4d43a4SKim Phillips .driver_name = "authenc-hmac-md5-cbc-des-caam", 21628b4d43a4SKim Phillips .blocksize = DES_BLOCK_SIZE, 21638b4d43a4SKim Phillips .type = CRYPTO_ALG_TYPE_AEAD, 21648b4d43a4SKim Phillips .template_aead = { 21658b4d43a4SKim Phillips .setkey = aead_setkey, 21668b4d43a4SKim Phillips .setauthsize = aead_setauthsize, 21678b4d43a4SKim Phillips .encrypt = aead_encrypt, 21688b4d43a4SKim Phillips .decrypt = aead_decrypt, 21698b4d43a4SKim Phillips .givencrypt = aead_givencrypt, 21708b4d43a4SKim Phillips .geniv = "<built-in>", 21718b4d43a4SKim Phillips .ivsize = DES_BLOCK_SIZE, 21728b4d43a4SKim Phillips .maxauthsize = MD5_DIGEST_SIZE, 21738b4d43a4SKim Phillips }, 21748b4d43a4SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 21758b4d43a4SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP, 21768b4d43a4SKim Phillips .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC, 21778b4d43a4SKim Phillips }, 21788b4d43a4SKim Phillips { 21798e8ec596SKim Phillips .name = "authenc(hmac(sha1),cbc(des))", 21808e8ec596SKim Phillips .driver_name = "authenc-hmac-sha1-cbc-des-caam", 21818e8ec596SKim Phillips .blocksize = DES_BLOCK_SIZE, 2182885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2183885e9e2fSYuan Kang .template_aead = { 21840e479300SYuan Kang .setkey = aead_setkey, 21850e479300SYuan Kang .setauthsize = aead_setauthsize, 21860e479300SYuan Kang .encrypt = aead_encrypt, 21870e479300SYuan Kang .decrypt = aead_decrypt, 21880e479300SYuan Kang .givencrypt = aead_givencrypt, 21898e8ec596SKim Phillips .geniv = "<built-in>", 21908e8ec596SKim Phillips .ivsize = DES_BLOCK_SIZE, 21918e8ec596SKim Phillips .maxauthsize = SHA1_DIGEST_SIZE, 21928e8ec596SKim Phillips }, 21938e8ec596SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 21948e8ec596SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, 21958e8ec596SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, 21968e8ec596SKim Phillips }, 21978e8ec596SKim Phillips { 2198e863f9ccSHemant Agrawal .name = "authenc(hmac(sha224),cbc(des))", 2199e863f9ccSHemant Agrawal .driver_name = "authenc-hmac-sha224-cbc-des-caam", 2200e863f9ccSHemant Agrawal .blocksize = DES_BLOCK_SIZE, 2201cb7d5662SVakul Garg .type = CRYPTO_ALG_TYPE_AEAD, 2202e863f9ccSHemant Agrawal .template_aead = { 2203e863f9ccSHemant Agrawal .setkey = aead_setkey, 2204e863f9ccSHemant Agrawal .setauthsize = aead_setauthsize, 2205e863f9ccSHemant Agrawal .encrypt = aead_encrypt, 2206e863f9ccSHemant Agrawal .decrypt = aead_decrypt, 2207e863f9ccSHemant Agrawal .givencrypt = aead_givencrypt, 2208e863f9ccSHemant Agrawal .geniv = "<built-in>", 2209e863f9ccSHemant Agrawal .ivsize = DES_BLOCK_SIZE, 2210e863f9ccSHemant Agrawal .maxauthsize = SHA224_DIGEST_SIZE, 2211e863f9ccSHemant Agrawal }, 2212e863f9ccSHemant Agrawal .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 2213e863f9ccSHemant Agrawal .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 2214e863f9ccSHemant Agrawal OP_ALG_AAI_HMAC_PRECOMP, 2215e863f9ccSHemant Agrawal .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, 2216e863f9ccSHemant Agrawal }, 2217e863f9ccSHemant Agrawal { 22188e8ec596SKim Phillips .name = "authenc(hmac(sha256),cbc(des))", 22198e8ec596SKim Phillips .driver_name = "authenc-hmac-sha256-cbc-des-caam", 22208e8ec596SKim Phillips .blocksize = DES_BLOCK_SIZE, 2221885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2222885e9e2fSYuan Kang .template_aead = { 22230e479300SYuan Kang .setkey = aead_setkey, 22240e479300SYuan Kang .setauthsize = aead_setauthsize, 22250e479300SYuan Kang .encrypt = aead_encrypt, 22260e479300SYuan Kang .decrypt = aead_decrypt, 22270e479300SYuan Kang .givencrypt = aead_givencrypt, 22288e8ec596SKim Phillips .geniv = "<built-in>", 22298e8ec596SKim Phillips .ivsize = DES_BLOCK_SIZE, 22308e8ec596SKim Phillips .maxauthsize = SHA256_DIGEST_SIZE, 22318e8ec596SKim Phillips }, 22328e8ec596SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 22338e8ec596SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 22348e8ec596SKim Phillips OP_ALG_AAI_HMAC_PRECOMP, 22358e8ec596SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, 22368e8ec596SKim Phillips }, 22374427b1b4SKim Phillips { 2238e863f9ccSHemant Agrawal .name = "authenc(hmac(sha384),cbc(des))", 2239e863f9ccSHemant Agrawal .driver_name = "authenc-hmac-sha384-cbc-des-caam", 2240e863f9ccSHemant Agrawal .blocksize = DES_BLOCK_SIZE, 2241cb7d5662SVakul Garg .type = CRYPTO_ALG_TYPE_AEAD, 2242e863f9ccSHemant Agrawal .template_aead = { 2243e863f9ccSHemant Agrawal .setkey = aead_setkey, 2244e863f9ccSHemant Agrawal .setauthsize = aead_setauthsize, 2245e863f9ccSHemant Agrawal .encrypt = aead_encrypt, 2246e863f9ccSHemant Agrawal .decrypt = aead_decrypt, 2247e863f9ccSHemant Agrawal .givencrypt = aead_givencrypt, 2248e863f9ccSHemant Agrawal .geniv = "<built-in>", 2249e863f9ccSHemant Agrawal .ivsize = DES_BLOCK_SIZE, 2250e863f9ccSHemant Agrawal .maxauthsize = SHA384_DIGEST_SIZE, 2251e863f9ccSHemant Agrawal }, 2252e863f9ccSHemant Agrawal .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 2253e863f9ccSHemant Agrawal .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 2254e863f9ccSHemant Agrawal OP_ALG_AAI_HMAC_PRECOMP, 2255e863f9ccSHemant Agrawal .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, 2256e863f9ccSHemant Agrawal }, 2257e863f9ccSHemant Agrawal { 22584427b1b4SKim Phillips .name = "authenc(hmac(sha512),cbc(des))", 22594427b1b4SKim Phillips .driver_name = "authenc-hmac-sha512-cbc-des-caam", 22604427b1b4SKim Phillips .blocksize = DES_BLOCK_SIZE, 2261885e9e2fSYuan Kang .type = CRYPTO_ALG_TYPE_AEAD, 2262885e9e2fSYuan Kang .template_aead = { 22630e479300SYuan Kang .setkey = aead_setkey, 22640e479300SYuan Kang .setauthsize = aead_setauthsize, 22650e479300SYuan Kang .encrypt = aead_encrypt, 22660e479300SYuan Kang .decrypt = aead_decrypt, 22670e479300SYuan Kang .givencrypt = aead_givencrypt, 22684427b1b4SKim Phillips .geniv = "<built-in>", 22694427b1b4SKim Phillips .ivsize = DES_BLOCK_SIZE, 22704427b1b4SKim Phillips .maxauthsize = SHA512_DIGEST_SIZE, 22714427b1b4SKim Phillips }, 22724427b1b4SKim Phillips .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 22734427b1b4SKim Phillips .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 22744427b1b4SKim Phillips OP_ALG_AAI_HMAC_PRECOMP, 22754427b1b4SKim Phillips .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, 22764427b1b4SKim Phillips }, 2277acdca31dSYuan Kang /* ablkcipher descriptor */ 2278acdca31dSYuan Kang { 2279acdca31dSYuan Kang .name = "cbc(aes)", 2280acdca31dSYuan Kang .driver_name = "cbc-aes-caam", 2281acdca31dSYuan Kang .blocksize = AES_BLOCK_SIZE, 2282acdca31dSYuan Kang .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 2283acdca31dSYuan Kang .template_ablkcipher = { 2284acdca31dSYuan Kang .setkey = ablkcipher_setkey, 2285acdca31dSYuan Kang .encrypt = ablkcipher_encrypt, 2286acdca31dSYuan Kang .decrypt = ablkcipher_decrypt, 2287acdca31dSYuan Kang .geniv = "eseqiv", 2288acdca31dSYuan Kang .min_keysize = AES_MIN_KEY_SIZE, 2289acdca31dSYuan Kang .max_keysize = AES_MAX_KEY_SIZE, 2290acdca31dSYuan Kang .ivsize = AES_BLOCK_SIZE, 2291acdca31dSYuan Kang }, 2292acdca31dSYuan Kang .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 2293acdca31dSYuan Kang }, 2294acdca31dSYuan Kang { 2295acdca31dSYuan Kang .name = "cbc(des3_ede)", 2296acdca31dSYuan Kang .driver_name = "cbc-3des-caam", 2297acdca31dSYuan Kang .blocksize = DES3_EDE_BLOCK_SIZE, 2298acdca31dSYuan Kang .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 2299acdca31dSYuan Kang .template_ablkcipher = { 2300acdca31dSYuan Kang .setkey = ablkcipher_setkey, 2301acdca31dSYuan Kang .encrypt = ablkcipher_encrypt, 2302acdca31dSYuan Kang .decrypt = ablkcipher_decrypt, 2303acdca31dSYuan Kang .geniv = "eseqiv", 2304acdca31dSYuan Kang .min_keysize = DES3_EDE_KEY_SIZE, 2305acdca31dSYuan Kang .max_keysize = DES3_EDE_KEY_SIZE, 2306acdca31dSYuan Kang .ivsize = DES3_EDE_BLOCK_SIZE, 2307acdca31dSYuan Kang }, 2308acdca31dSYuan Kang .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 2309acdca31dSYuan Kang }, 2310acdca31dSYuan Kang { 2311acdca31dSYuan Kang .name = "cbc(des)", 2312acdca31dSYuan Kang .driver_name = "cbc-des-caam", 2313acdca31dSYuan Kang .blocksize = DES_BLOCK_SIZE, 2314acdca31dSYuan Kang .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 2315acdca31dSYuan Kang .template_ablkcipher = { 2316acdca31dSYuan Kang .setkey = ablkcipher_setkey, 2317acdca31dSYuan Kang .encrypt = ablkcipher_encrypt, 2318acdca31dSYuan Kang .decrypt = ablkcipher_decrypt, 2319acdca31dSYuan Kang .geniv = "eseqiv", 2320acdca31dSYuan Kang .min_keysize = DES_KEY_SIZE, 2321acdca31dSYuan Kang .max_keysize = DES_KEY_SIZE, 2322acdca31dSYuan Kang .ivsize = DES_BLOCK_SIZE, 2323acdca31dSYuan Kang }, 2324acdca31dSYuan Kang .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 2325acdca31dSYuan Kang } 23268e8ec596SKim Phillips }; 23278e8ec596SKim Phillips 23288e8ec596SKim Phillips struct caam_crypto_alg { 23298e8ec596SKim Phillips struct list_head entry; 23308e8ec596SKim Phillips int class1_alg_type; 23318e8ec596SKim Phillips int class2_alg_type; 23328e8ec596SKim Phillips int alg_op; 23338e8ec596SKim Phillips struct crypto_alg crypto_alg; 23348e8ec596SKim Phillips }; 23358e8ec596SKim Phillips 23368e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm) 23378e8ec596SKim Phillips { 23388e8ec596SKim Phillips struct crypto_alg *alg = tfm->__crt_alg; 23398e8ec596SKim Phillips struct caam_crypto_alg *caam_alg = 23408e8ec596SKim Phillips container_of(alg, struct caam_crypto_alg, crypto_alg); 23418e8ec596SKim Phillips struct caam_ctx *ctx = crypto_tfm_ctx(tfm); 23428e8ec596SKim Phillips 2343cfc6f11bSRuchika Gupta ctx->jrdev = caam_jr_alloc(); 2344cfc6f11bSRuchika Gupta if (IS_ERR(ctx->jrdev)) { 2345cfc6f11bSRuchika Gupta pr_err("Job Ring Device allocation for transform failed\n"); 2346cfc6f11bSRuchika Gupta return PTR_ERR(ctx->jrdev); 2347cfc6f11bSRuchika Gupta } 23488e8ec596SKim Phillips 23498e8ec596SKim Phillips /* copy descriptor header template value */ 23508e8ec596SKim Phillips ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type; 23518e8ec596SKim Phillips ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam_alg->class2_alg_type; 23528e8ec596SKim Phillips ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_alg->alg_op; 23538e8ec596SKim Phillips 23548e8ec596SKim Phillips return 0; 23558e8ec596SKim Phillips } 23568e8ec596SKim Phillips 23578e8ec596SKim Phillips static void caam_cra_exit(struct crypto_tfm *tfm) 23588e8ec596SKim Phillips { 23598e8ec596SKim Phillips struct caam_ctx *ctx = crypto_tfm_ctx(tfm); 23608e8ec596SKim Phillips 23611acebad3SYuan Kang if (ctx->sh_desc_enc_dma && 23621acebad3SYuan Kang !dma_mapping_error(ctx->jrdev, ctx->sh_desc_enc_dma)) 23631acebad3SYuan Kang dma_unmap_single(ctx->jrdev, ctx->sh_desc_enc_dma, 23641acebad3SYuan Kang desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE); 23651acebad3SYuan Kang if (ctx->sh_desc_dec_dma && 23661acebad3SYuan Kang !dma_mapping_error(ctx->jrdev, ctx->sh_desc_dec_dma)) 23671acebad3SYuan Kang dma_unmap_single(ctx->jrdev, ctx->sh_desc_dec_dma, 23681acebad3SYuan Kang desc_bytes(ctx->sh_desc_dec), DMA_TO_DEVICE); 23691acebad3SYuan Kang if (ctx->sh_desc_givenc_dma && 23701acebad3SYuan Kang !dma_mapping_error(ctx->jrdev, ctx->sh_desc_givenc_dma)) 23711acebad3SYuan Kang dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma, 23721acebad3SYuan Kang desc_bytes(ctx->sh_desc_givenc), 23734427b1b4SKim Phillips DMA_TO_DEVICE); 2374ec31eed7SHoria Geanta if (ctx->key_dma && 2375ec31eed7SHoria Geanta !dma_mapping_error(ctx->jrdev, ctx->key_dma)) 2376ec31eed7SHoria Geanta dma_unmap_single(ctx->jrdev, ctx->key_dma, 2377ec31eed7SHoria Geanta ctx->enckeylen + ctx->split_key_pad_len, 2378ec31eed7SHoria Geanta DMA_TO_DEVICE); 2379cfc6f11bSRuchika Gupta 2380cfc6f11bSRuchika Gupta caam_jr_free(ctx->jrdev); 23818e8ec596SKim Phillips } 23828e8ec596SKim Phillips 23838e8ec596SKim Phillips static void __exit caam_algapi_exit(void) 23848e8ec596SKim Phillips { 23858e8ec596SKim Phillips 23868e8ec596SKim Phillips struct caam_crypto_alg *t_alg, *n; 23878e8ec596SKim Phillips 2388cfc6f11bSRuchika Gupta if (!alg_list.next) 23898e8ec596SKim Phillips return; 23908e8ec596SKim Phillips 2391cfc6f11bSRuchika Gupta list_for_each_entry_safe(t_alg, n, &alg_list, entry) { 23928e8ec596SKim Phillips crypto_unregister_alg(&t_alg->crypto_alg); 23938e8ec596SKim Phillips list_del(&t_alg->entry); 23948e8ec596SKim Phillips kfree(t_alg); 23958e8ec596SKim Phillips } 23968e8ec596SKim Phillips } 23978e8ec596SKim Phillips 2398cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template 23998e8ec596SKim Phillips *template) 24008e8ec596SKim Phillips { 24018e8ec596SKim Phillips struct caam_crypto_alg *t_alg; 24028e8ec596SKim Phillips struct crypto_alg *alg; 24038e8ec596SKim Phillips 24048e8ec596SKim Phillips t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL); 24058e8ec596SKim Phillips if (!t_alg) { 2406cfc6f11bSRuchika Gupta pr_err("failed to allocate t_alg\n"); 24078e8ec596SKim Phillips return ERR_PTR(-ENOMEM); 24088e8ec596SKim Phillips } 24098e8ec596SKim Phillips 24108e8ec596SKim Phillips alg = &t_alg->crypto_alg; 24118e8ec596SKim Phillips 24128e8ec596SKim Phillips snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); 24138e8ec596SKim Phillips snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", 24148e8ec596SKim Phillips template->driver_name); 24158e8ec596SKim Phillips alg->cra_module = THIS_MODULE; 24168e8ec596SKim Phillips alg->cra_init = caam_cra_init; 24178e8ec596SKim Phillips alg->cra_exit = caam_cra_exit; 24188e8ec596SKim Phillips alg->cra_priority = CAAM_CRA_PRIORITY; 24198e8ec596SKim Phillips alg->cra_blocksize = template->blocksize; 24208e8ec596SKim Phillips alg->cra_alignmask = 0; 24218e8ec596SKim Phillips alg->cra_ctxsize = sizeof(struct caam_ctx); 2422d912bb76SNikos Mavrogiannopoulos alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | 2423d912bb76SNikos Mavrogiannopoulos template->type; 2424885e9e2fSYuan Kang switch (template->type) { 2425acdca31dSYuan Kang case CRYPTO_ALG_TYPE_ABLKCIPHER: 2426acdca31dSYuan Kang alg->cra_type = &crypto_ablkcipher_type; 2427acdca31dSYuan Kang alg->cra_ablkcipher = template->template_ablkcipher; 2428acdca31dSYuan Kang break; 2429885e9e2fSYuan Kang case CRYPTO_ALG_TYPE_AEAD: 2430885e9e2fSYuan Kang alg->cra_type = &crypto_aead_type; 2431885e9e2fSYuan Kang alg->cra_aead = template->template_aead; 2432885e9e2fSYuan Kang break; 2433885e9e2fSYuan Kang } 24348e8ec596SKim Phillips 24358e8ec596SKim Phillips t_alg->class1_alg_type = template->class1_alg_type; 24368e8ec596SKim Phillips t_alg->class2_alg_type = template->class2_alg_type; 24378e8ec596SKim Phillips t_alg->alg_op = template->alg_op; 24388e8ec596SKim Phillips 24398e8ec596SKim Phillips return t_alg; 24408e8ec596SKim Phillips } 24418e8ec596SKim Phillips 24428e8ec596SKim Phillips static int __init caam_algapi_init(void) 24438e8ec596SKim Phillips { 244435af6403SRuchika Gupta struct device_node *dev_node; 244535af6403SRuchika Gupta struct platform_device *pdev; 244635af6403SRuchika Gupta struct device *ctrldev; 244735af6403SRuchika Gupta void *priv; 24488e8ec596SKim Phillips int i = 0, err = 0; 24498e8ec596SKim Phillips 245035af6403SRuchika Gupta dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); 245135af6403SRuchika Gupta if (!dev_node) { 245235af6403SRuchika Gupta dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); 245335af6403SRuchika Gupta if (!dev_node) 245435af6403SRuchika Gupta return -ENODEV; 245535af6403SRuchika Gupta } 245635af6403SRuchika Gupta 245735af6403SRuchika Gupta pdev = of_find_device_by_node(dev_node); 245835af6403SRuchika Gupta if (!pdev) { 245935af6403SRuchika Gupta of_node_put(dev_node); 246035af6403SRuchika Gupta return -ENODEV; 246135af6403SRuchika Gupta } 246235af6403SRuchika Gupta 246335af6403SRuchika Gupta ctrldev = &pdev->dev; 246435af6403SRuchika Gupta priv = dev_get_drvdata(ctrldev); 246535af6403SRuchika Gupta of_node_put(dev_node); 246635af6403SRuchika Gupta 246735af6403SRuchika Gupta /* 246835af6403SRuchika Gupta * If priv is NULL, it's probably because the caam driver wasn't 246935af6403SRuchika Gupta * properly initialized (e.g. RNG4 init failed). Thus, bail out here. 247035af6403SRuchika Gupta */ 247135af6403SRuchika Gupta if (!priv) 247235af6403SRuchika Gupta return -ENODEV; 247335af6403SRuchika Gupta 247435af6403SRuchika Gupta 2475cfc6f11bSRuchika Gupta INIT_LIST_HEAD(&alg_list); 24768e8ec596SKim Phillips 24778e8ec596SKim Phillips /* register crypto algorithms the device supports */ 24788e8ec596SKim Phillips for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { 24798e8ec596SKim Phillips /* TODO: check if h/w supports alg */ 24808e8ec596SKim Phillips struct caam_crypto_alg *t_alg; 24818e8ec596SKim Phillips 2482cfc6f11bSRuchika Gupta t_alg = caam_alg_alloc(&driver_algs[i]); 24838e8ec596SKim Phillips if (IS_ERR(t_alg)) { 24848e8ec596SKim Phillips err = PTR_ERR(t_alg); 2485cfc6f11bSRuchika Gupta pr_warn("%s alg allocation failed\n", 2486cdc712d8SDan Carpenter driver_algs[i].driver_name); 24878e8ec596SKim Phillips continue; 24888e8ec596SKim Phillips } 24898e8ec596SKim Phillips 24908e8ec596SKim Phillips err = crypto_register_alg(&t_alg->crypto_alg); 24918e8ec596SKim Phillips if (err) { 2492cfc6f11bSRuchika Gupta pr_warn("%s alg registration failed\n", 24938e8ec596SKim Phillips t_alg->crypto_alg.cra_driver_name); 24948e8ec596SKim Phillips kfree(t_alg); 2495246bbedbSHoria Geanta } else 2496cfc6f11bSRuchika Gupta list_add_tail(&t_alg->entry, &alg_list); 24978e8ec596SKim Phillips } 2498cfc6f11bSRuchika Gupta if (!list_empty(&alg_list)) 2499cfc6f11bSRuchika Gupta pr_info("caam algorithms registered in /proc/crypto\n"); 25008e8ec596SKim Phillips 25018e8ec596SKim Phillips return err; 25028e8ec596SKim Phillips } 25038e8ec596SKim Phillips 25048e8ec596SKim Phillips module_init(caam_algapi_init); 25058e8ec596SKim Phillips module_exit(caam_algapi_exit); 25068e8ec596SKim Phillips 25078e8ec596SKim Phillips MODULE_LICENSE("GPL"); 25088e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API"); 25098e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC"); 2510