Linux Audio

Check our new training course

Loading...
  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 ahash first and digest
 26 * @era: SEC Era
 27 */
 28void 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}
 76EXPORT_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 */
 87void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
 88			 int digestsize, int ctx_len)
 89{
 90	u32 *skip_key_load;
 91
 92	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
 93
 94	/* Skip loading of key, context if already shared */
 95	skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
 96
 97	if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
 98		append_key_as_imm(desc, adata->key_virt, adata->keylen,
 99				  adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
100	} else { /* UPDATE, FINALIZE */
101		if (is_xcbc_aes(adata->algtype))
102			/* Load K1 */
103			append_key(desc, adata->key_dma, adata->keylen,
104				   CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
105		else /* CMAC */
106			append_key_as_imm(desc, adata->key_virt, adata->keylen,
107					  adata->keylen, CLASS_1 |
108					  KEY_DEST_CLASS_REG);
109		/* Restore context */
110		append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
111				LDST_SRCDST_BYTE_CONTEXT);
112	}
113
114	set_jump_tgt_here(desc, skip_key_load);
115
116	/* Class 1 operation */
117	append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
118
119	/*
120	 * Load from buf and/or src and write to req->result or state->context
121	 * Calculate remaining bytes to read
122	 */
123	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
124
125	/* Read remaining bytes */
126	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
127			     FIFOLD_TYPE_MSG | FIFOLDST_VLF);
128
129	/*
130	 * Save context:
131	 * - xcbc: partial hash, keys K2 and K3
132	 * - cmac: partial hash, constant L = E(K,0)
133	 */
134	append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
135			 LDST_SRCDST_BYTE_CONTEXT);
136	if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
137		/* Save K1 */
138		append_fifo_store(desc, adata->key_dma, adata->keylen,
139				  LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
140}
141EXPORT_SYMBOL(cnstr_shdsc_sk_hash);
142
143MODULE_LICENSE("Dual BSD/GPL");
144MODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
145MODULE_AUTHOR("NXP Semiconductors");