18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Shared descriptors for ahash algorithms 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2017-2019 NXP 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "compat.h" 98c2ecf20Sopenharmony_ci#include "desc_constr.h" 108c2ecf20Sopenharmony_ci#include "caamhash_desc.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/** 138c2ecf20Sopenharmony_ci * cnstr_shdsc_ahash - ahash shared descriptor 148c2ecf20Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction 158c2ecf20Sopenharmony_ci * @adata: pointer to authentication transform definitions. 168c2ecf20Sopenharmony_ci * A split key is required for SEC Era < 6; the size of the split key 178c2ecf20Sopenharmony_ci * is specified in this case. 188c2ecf20Sopenharmony_ci * Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224, 198c2ecf20Sopenharmony_ci * SHA256, SHA384, SHA512}. 208c2ecf20Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} 218c2ecf20Sopenharmony_ci * @digestsize: algorithm's digest size 228c2ecf20Sopenharmony_ci * @ctx_len: size of Context Register 238c2ecf20Sopenharmony_ci * @import_ctx: true if previous Context Register needs to be restored 248c2ecf20Sopenharmony_ci * must be true for ahash update and final 258c2ecf20Sopenharmony_ci * must be false for for ahash first and digest 268c2ecf20Sopenharmony_ci * @era: SEC Era 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_civoid cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state, 298c2ecf20Sopenharmony_ci int digestsize, int ctx_len, bool import_ctx, int era) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci u32 op = adata->algtype; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci init_sh_desc(desc, HDR_SHARE_SERIAL); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci /* Append key if it has been set; ahash update excluded */ 368c2ecf20Sopenharmony_ci if (state != OP_ALG_AS_UPDATE && adata->keylen) { 378c2ecf20Sopenharmony_ci u32 *skip_key_load; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci /* Skip key loading if already shared */ 408c2ecf20Sopenharmony_ci skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 418c2ecf20Sopenharmony_ci JUMP_COND_SHRD); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci if (era < 6) 448c2ecf20Sopenharmony_ci append_key_as_imm(desc, adata->key_virt, 458c2ecf20Sopenharmony_ci adata->keylen_pad, 468c2ecf20Sopenharmony_ci adata->keylen, CLASS_2 | 478c2ecf20Sopenharmony_ci KEY_DEST_MDHA_SPLIT | KEY_ENC); 488c2ecf20Sopenharmony_ci else 498c2ecf20Sopenharmony_ci append_proto_dkp(desc, adata); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci set_jump_tgt_here(desc, skip_key_load); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci op |= OP_ALG_AAI_HMAC_PRECOMP; 548c2ecf20Sopenharmony_ci } 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci /* If needed, import context from software */ 578c2ecf20Sopenharmony_ci if (import_ctx) 588c2ecf20Sopenharmony_ci append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB | 598c2ecf20Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* Class 2 operation */ 628c2ecf20Sopenharmony_ci append_operation(desc, op | state | OP_ALG_ENCRYPT); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* 658c2ecf20Sopenharmony_ci * Load from buf and/or src and write to req->result or state->context 668c2ecf20Sopenharmony_ci * Calculate remaining bytes to read 678c2ecf20Sopenharmony_ci */ 688c2ecf20Sopenharmony_ci append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 698c2ecf20Sopenharmony_ci /* Read remaining bytes */ 708c2ecf20Sopenharmony_ci append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 | 718c2ecf20Sopenharmony_ci FIFOLD_TYPE_MSG | KEY_VLF); 728c2ecf20Sopenharmony_ci /* Store class2 context bytes */ 738c2ecf20Sopenharmony_ci append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | 748c2ecf20Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_ahash); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/** 798c2ecf20Sopenharmony_ci * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based 808c2ecf20Sopenharmony_ci * hash algorithms 818c2ecf20Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction 828c2ecf20Sopenharmony_ci * @adata: pointer to authentication transform definitions. 838c2ecf20Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} 848c2ecf20Sopenharmony_ci * @digestsize: algorithm's digest size 858c2ecf20Sopenharmony_ci * @ctx_len: size of Context Register 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_civoid cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state, 888c2ecf20Sopenharmony_ci int digestsize, int ctx_len) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci u32 *skip_key_load; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci /* Skip loading of key, context if already shared */ 958c2ecf20Sopenharmony_ci skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) { 988c2ecf20Sopenharmony_ci append_key_as_imm(desc, adata->key_virt, adata->keylen, 998c2ecf20Sopenharmony_ci adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); 1008c2ecf20Sopenharmony_ci } else { /* UPDATE, FINALIZE */ 1018c2ecf20Sopenharmony_ci if (is_xcbc_aes(adata->algtype)) 1028c2ecf20Sopenharmony_ci /* Load K1 */ 1038c2ecf20Sopenharmony_ci append_key(desc, adata->key_dma, adata->keylen, 1048c2ecf20Sopenharmony_ci CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC); 1058c2ecf20Sopenharmony_ci else /* CMAC */ 1068c2ecf20Sopenharmony_ci append_key_as_imm(desc, adata->key_virt, adata->keylen, 1078c2ecf20Sopenharmony_ci adata->keylen, CLASS_1 | 1088c2ecf20Sopenharmony_ci KEY_DEST_CLASS_REG); 1098c2ecf20Sopenharmony_ci /* Restore context */ 1108c2ecf20Sopenharmony_ci append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB | 1118c2ecf20Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci set_jump_tgt_here(desc, skip_key_load); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* Class 1 operation */ 1178c2ecf20Sopenharmony_ci append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* 1208c2ecf20Sopenharmony_ci * Load from buf and/or src and write to req->result or state->context 1218c2ecf20Sopenharmony_ci * Calculate remaining bytes to read 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_ci append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* Read remaining bytes */ 1268c2ecf20Sopenharmony_ci append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 | 1278c2ecf20Sopenharmony_ci FIFOLD_TYPE_MSG | FIFOLDST_VLF); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci /* 1308c2ecf20Sopenharmony_ci * Save context: 1318c2ecf20Sopenharmony_ci * - xcbc: partial hash, keys K2 and K3 1328c2ecf20Sopenharmony_ci * - cmac: partial hash, constant L = E(K,0) 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci append_seq_store(desc, digestsize, LDST_CLASS_1_CCB | 1358c2ecf20Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 1368c2ecf20Sopenharmony_ci if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT) 1378c2ecf20Sopenharmony_ci /* Save K1 */ 1388c2ecf20Sopenharmony_ci append_fifo_store(desc, adata->key_dma, adata->keylen, 1398c2ecf20Sopenharmony_ci LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK); 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_sk_hash); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 1448c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("FSL CAAM ahash descriptors support"); 1458c2ecf20Sopenharmony_ciMODULE_AUTHOR("NXP Semiconductors"); 146