1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* 3 * Shared descriptors for ahash algorithms 4 * 5 * Copyright 2017-2019 NXP 6 */ 7 8 #include "compat.h" 9 #include "desc_constr.h" 10 #include "caamhash_desc.h" 11 12 /** 13 * cnstr_shdsc_ahash - ahash shared descriptor 14 * @desc: pointer to buffer used for descriptor construction 15 * @adata: pointer to authentication transform definitions. 16 * A split key is required for SEC Era < 6; the size of the split key 17 * is specified in this case. 18 * Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224, 19 * SHA256, SHA384, SHA512}. 20 * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} 21 * @digestsize: algorithm's digest size 22 * @ctx_len: size of Context Register 23 * @import_ctx: true if previous Context Register needs to be restored 24 * must be true for ahash update and final 25 * must be false for for ahash first and digest 26 * @era: SEC Era 27 */ 28 void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state, 29 int digestsize, int ctx_len, bool import_ctx, int era) 30 { 31 u32 op = adata->algtype; 32 33 init_sh_desc(desc, HDR_SHARE_SERIAL); 34 35 /* Append key if it has been set; ahash update excluded */ 36 if (state != OP_ALG_AS_UPDATE && adata->keylen) { 37 u32 *skip_key_load; 38 39 /* Skip key loading if already shared */ 40 skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 41 JUMP_COND_SHRD); 42 43 if (era < 6) 44 append_key_as_imm(desc, adata->key_virt, 45 adata->keylen_pad, 46 adata->keylen, CLASS_2 | 47 KEY_DEST_MDHA_SPLIT | KEY_ENC); 48 else 49 append_proto_dkp(desc, adata); 50 51 set_jump_tgt_here(desc, skip_key_load); 52 53 op |= OP_ALG_AAI_HMAC_PRECOMP; 54 } 55 56 /* If needed, import context from software */ 57 if (import_ctx) 58 append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB | 59 LDST_SRCDST_BYTE_CONTEXT); 60 61 /* Class 2 operation */ 62 append_operation(desc, op | state | OP_ALG_ENCRYPT); 63 64 /* 65 * Load from buf and/or src and write to req->result or state->context 66 * Calculate remaining bytes to read 67 */ 68 append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 69 /* Read remaining bytes */ 70 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 | 71 FIFOLD_TYPE_MSG | KEY_VLF); 72 /* Store class2 context bytes */ 73 append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | 74 LDST_SRCDST_BYTE_CONTEXT); 75 } 76 EXPORT_SYMBOL(cnstr_shdsc_ahash); 77 78 /** 79 * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based 80 * hash algorithms 81 * @desc: pointer to buffer used for descriptor construction 82 * @adata: pointer to authentication transform definitions. 83 * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} 84 * @digestsize: algorithm's digest size 85 * @ctx_len: size of Context Register 86 * @key_dma: I/O Virtual Address of the key 87 */ 88 void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state, 89 int digestsize, int ctx_len, dma_addr_t key_dma) 90 { 91 u32 *skip_key_load; 92 93 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); 94 95 /* Skip loading of key, context if already shared */ 96 skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD); 97 98 if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) { 99 append_key_as_imm(desc, adata->key_virt, adata->keylen, 100 adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); 101 } else { /* UPDATE, FINALIZE */ 102 if (is_xcbc_aes(adata->algtype)) 103 /* Load K1 */ 104 append_key(desc, adata->key_dma, adata->keylen, 105 CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC); 106 else /* CMAC */ 107 append_key_as_imm(desc, adata->key_virt, adata->keylen, 108 adata->keylen, CLASS_1 | 109 KEY_DEST_CLASS_REG); 110 /* Restore context */ 111 append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB | 112 LDST_SRCDST_BYTE_CONTEXT); 113 } 114 115 set_jump_tgt_here(desc, skip_key_load); 116 117 /* Class 1 operation */ 118 append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT); 119 120 /* 121 * Load from buf and/or src and write to req->result or state->context 122 * Calculate remaining bytes to read 123 */ 124 append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 125 126 /* Read remaining bytes */ 127 append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 | 128 FIFOLD_TYPE_MSG | FIFOLDST_VLF); 129 130 /* 131 * Save context: 132 * - xcbc: partial hash, keys K2 and K3 133 * - cmac: partial hash, constant L = E(K,0) 134 */ 135 append_seq_store(desc, digestsize, LDST_CLASS_1_CCB | 136 LDST_SRCDST_BYTE_CONTEXT); 137 if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT) 138 /* Save K1 */ 139 append_fifo_store(desc, key_dma, adata->keylen, 140 LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK); 141 } 142 EXPORT_SYMBOL(cnstr_shdsc_sk_hash); 143 144 MODULE_LICENSE("Dual BSD/GPL"); 145 MODULE_DESCRIPTION("FSL CAAM ahash descriptors support"); 146 MODULE_AUTHOR("NXP Semiconductors"); 147