162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Shared descriptors for ahash algorithms 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2017-2019 NXP 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "compat.h" 962306a36Sopenharmony_ci#include "desc_constr.h" 1062306a36Sopenharmony_ci#include "caamhash_desc.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/** 1362306a36Sopenharmony_ci * cnstr_shdsc_ahash - ahash shared descriptor 1462306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction 1562306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions. 1662306a36Sopenharmony_ci * A split key is required for SEC Era < 6; the size of the split key 1762306a36Sopenharmony_ci * is specified in this case. 1862306a36Sopenharmony_ci * Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224, 1962306a36Sopenharmony_ci * SHA256, SHA384, SHA512}. 2062306a36Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} 2162306a36Sopenharmony_ci * @digestsize: algorithm's digest size 2262306a36Sopenharmony_ci * @ctx_len: size of Context Register 2362306a36Sopenharmony_ci * @import_ctx: true if previous Context Register needs to be restored 2462306a36Sopenharmony_ci * must be true for ahash update and final 2562306a36Sopenharmony_ci * must be false for ahash first and digest 2662306a36Sopenharmony_ci * @era: SEC Era 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_civoid cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state, 2962306a36Sopenharmony_ci int digestsize, int ctx_len, bool import_ctx, int era) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci u32 op = adata->algtype; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci init_sh_desc(desc, HDR_SHARE_SERIAL); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* Append key if it has been set; ahash update excluded */ 3662306a36Sopenharmony_ci if (state != OP_ALG_AS_UPDATE && adata->keylen) { 3762306a36Sopenharmony_ci u32 *skip_key_load; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci /* Skip key loading if already shared */ 4062306a36Sopenharmony_ci skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 4162306a36Sopenharmony_ci JUMP_COND_SHRD); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci if (era < 6) 4462306a36Sopenharmony_ci append_key_as_imm(desc, adata->key_virt, 4562306a36Sopenharmony_ci adata->keylen_pad, 4662306a36Sopenharmony_ci adata->keylen, CLASS_2 | 4762306a36Sopenharmony_ci KEY_DEST_MDHA_SPLIT | KEY_ENC); 4862306a36Sopenharmony_ci else 4962306a36Sopenharmony_ci append_proto_dkp(desc, adata); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci set_jump_tgt_here(desc, skip_key_load); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci op |= OP_ALG_AAI_HMAC_PRECOMP; 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* If needed, import context from software */ 5762306a36Sopenharmony_ci if (import_ctx) 5862306a36Sopenharmony_ci append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB | 5962306a36Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* Class 2 operation */ 6262306a36Sopenharmony_ci append_operation(desc, op | state | OP_ALG_ENCRYPT); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci /* 6562306a36Sopenharmony_ci * Load from buf and/or src and write to req->result or state->context 6662306a36Sopenharmony_ci * Calculate remaining bytes to read 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_ci append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 6962306a36Sopenharmony_ci /* Read remaining bytes */ 7062306a36Sopenharmony_ci append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 | 7162306a36Sopenharmony_ci FIFOLD_TYPE_MSG | KEY_VLF); 7262306a36Sopenharmony_ci /* Store class2 context bytes */ 7362306a36Sopenharmony_ci append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | 7462306a36Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_ahash); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/** 7962306a36Sopenharmony_ci * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based 8062306a36Sopenharmony_ci * hash algorithms 8162306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction 8262306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions. 8362306a36Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} 8462306a36Sopenharmony_ci * @digestsize: algorithm's digest size 8562306a36Sopenharmony_ci * @ctx_len: size of Context Register 8662306a36Sopenharmony_ci */ 8762306a36Sopenharmony_civoid cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state, 8862306a36Sopenharmony_ci int digestsize, int ctx_len) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci u32 *skip_key_load; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* Skip loading of key, context if already shared */ 9562306a36Sopenharmony_ci skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) { 9862306a36Sopenharmony_ci append_key_as_imm(desc, adata->key_virt, adata->keylen, 9962306a36Sopenharmony_ci adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); 10062306a36Sopenharmony_ci } else { /* UPDATE, FINALIZE */ 10162306a36Sopenharmony_ci if (is_xcbc_aes(adata->algtype)) 10262306a36Sopenharmony_ci /* Load K1 */ 10362306a36Sopenharmony_ci append_key(desc, adata->key_dma, adata->keylen, 10462306a36Sopenharmony_ci CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC); 10562306a36Sopenharmony_ci else /* CMAC */ 10662306a36Sopenharmony_ci append_key_as_imm(desc, adata->key_virt, adata->keylen, 10762306a36Sopenharmony_ci adata->keylen, CLASS_1 | 10862306a36Sopenharmony_ci KEY_DEST_CLASS_REG); 10962306a36Sopenharmony_ci /* Restore context */ 11062306a36Sopenharmony_ci append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB | 11162306a36Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci set_jump_tgt_here(desc, skip_key_load); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci /* Class 1 operation */ 11762306a36Sopenharmony_ci append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT); 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci /* 12062306a36Sopenharmony_ci * Load from buf and/or src and write to req->result or state->context 12162306a36Sopenharmony_ci * Calculate remaining bytes to read 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_ci append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci /* Read remaining bytes */ 12662306a36Sopenharmony_ci append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 | 12762306a36Sopenharmony_ci FIFOLD_TYPE_MSG | FIFOLDST_VLF); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci /* 13062306a36Sopenharmony_ci * Save context: 13162306a36Sopenharmony_ci * - xcbc: partial hash, keys K2 and K3 13262306a36Sopenharmony_ci * - cmac: partial hash, constant L = E(K,0) 13362306a36Sopenharmony_ci */ 13462306a36Sopenharmony_ci append_seq_store(desc, digestsize, LDST_CLASS_1_CCB | 13562306a36Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 13662306a36Sopenharmony_ci if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT) 13762306a36Sopenharmony_ci /* Save K1 */ 13862306a36Sopenharmony_ci append_fifo_store(desc, adata->key_dma, adata->keylen, 13962306a36Sopenharmony_ci LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK); 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_sk_hash); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 14462306a36Sopenharmony_ciMODULE_DESCRIPTION("FSL CAAM ahash descriptors support"); 14562306a36Sopenharmony_ciMODULE_AUTHOR("NXP Semiconductors"); 146