mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.6 KiB
145 lines
4.6 KiB
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) |
|
/* |
|
* Shared descriptors for ahash algorithms |
|
* |
|
* Copyright 2017-2019 NXP |
|
*/ |
|
|
|
#include "compat.h" |
|
#include "desc_constr.h" |
|
#include "caamhash_desc.h" |
|
|
|
/** |
|
* cnstr_shdsc_ahash - ahash shared descriptor |
|
* @desc: pointer to buffer used for descriptor construction |
|
* @adata: pointer to authentication transform definitions. |
|
* A split key is required for SEC Era < 6; the size of the split key |
|
* is specified in this case. |
|
* Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224, |
|
* SHA256, SHA384, SHA512}. |
|
* @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} |
|
* @digestsize: algorithm's digest size |
|
* @ctx_len: size of Context Register |
|
* @import_ctx: true if previous Context Register needs to be restored |
|
* must be true for ahash update and final |
|
* must be false for for ahash first and digest |
|
* @era: SEC Era |
|
*/ |
|
void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state, |
|
int digestsize, int ctx_len, bool import_ctx, int era) |
|
{ |
|
u32 op = adata->algtype; |
|
|
|
init_sh_desc(desc, HDR_SHARE_SERIAL); |
|
|
|
/* Append key if it has been set; ahash update excluded */ |
|
if (state != OP_ALG_AS_UPDATE && adata->keylen) { |
|
u32 *skip_key_load; |
|
|
|
/* Skip key loading if already shared */ |
|
skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | |
|
JUMP_COND_SHRD); |
|
|
|
if (era < 6) |
|
append_key_as_imm(desc, adata->key_virt, |
|
adata->keylen_pad, |
|
adata->keylen, CLASS_2 | |
|
KEY_DEST_MDHA_SPLIT | KEY_ENC); |
|
else |
|
append_proto_dkp(desc, adata); |
|
|
|
set_jump_tgt_here(desc, skip_key_load); |
|
|
|
op |= OP_ALG_AAI_HMAC_PRECOMP; |
|
} |
|
|
|
/* If needed, import context from software */ |
|
if (import_ctx) |
|
append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB | |
|
LDST_SRCDST_BYTE_CONTEXT); |
|
|
|
/* Class 2 operation */ |
|
append_operation(desc, op | state | OP_ALG_ENCRYPT); |
|
|
|
/* |
|
* Load from buf and/or src and write to req->result or state->context |
|
* Calculate remaining bytes to read |
|
*/ |
|
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); |
|
/* Read remaining bytes */ |
|
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 | |
|
FIFOLD_TYPE_MSG | KEY_VLF); |
|
/* Store class2 context bytes */ |
|
append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | |
|
LDST_SRCDST_BYTE_CONTEXT); |
|
} |
|
EXPORT_SYMBOL(cnstr_shdsc_ahash); |
|
|
|
/** |
|
* cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based |
|
* hash algorithms |
|
* @desc: pointer to buffer used for descriptor construction |
|
* @adata: pointer to authentication transform definitions. |
|
* @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE} |
|
* @digestsize: algorithm's digest size |
|
* @ctx_len: size of Context Register |
|
*/ |
|
void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state, |
|
int digestsize, int ctx_len) |
|
{ |
|
u32 *skip_key_load; |
|
|
|
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); |
|
|
|
/* Skip loading of key, context if already shared */ |
|
skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD); |
|
|
|
if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) { |
|
append_key_as_imm(desc, adata->key_virt, adata->keylen, |
|
adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); |
|
} else { /* UPDATE, FINALIZE */ |
|
if (is_xcbc_aes(adata->algtype)) |
|
/* Load K1 */ |
|
append_key(desc, adata->key_dma, adata->keylen, |
|
CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC); |
|
else /* CMAC */ |
|
append_key_as_imm(desc, adata->key_virt, adata->keylen, |
|
adata->keylen, CLASS_1 | |
|
KEY_DEST_CLASS_REG); |
|
/* Restore context */ |
|
append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB | |
|
LDST_SRCDST_BYTE_CONTEXT); |
|
} |
|
|
|
set_jump_tgt_here(desc, skip_key_load); |
|
|
|
/* Class 1 operation */ |
|
append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT); |
|
|
|
/* |
|
* Load from buf and/or src and write to req->result or state->context |
|
* Calculate remaining bytes to read |
|
*/ |
|
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); |
|
|
|
/* Read remaining bytes */ |
|
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 | |
|
FIFOLD_TYPE_MSG | FIFOLDST_VLF); |
|
|
|
/* |
|
* Save context: |
|
* - xcbc: partial hash, keys K2 and K3 |
|
* - cmac: partial hash, constant L = E(K,0) |
|
*/ |
|
append_seq_store(desc, digestsize, LDST_CLASS_1_CCB | |
|
LDST_SRCDST_BYTE_CONTEXT); |
|
if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT) |
|
/* Save K1 */ |
|
append_fifo_store(desc, adata->key_dma, adata->keylen, |
|
LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK); |
|
} |
|
EXPORT_SYMBOL(cnstr_shdsc_sk_hash); |
|
|
|
MODULE_LICENSE("Dual BSD/GPL"); |
|
MODULE_DESCRIPTION("FSL CAAM ahash descriptors support"); |
|
MODULE_AUTHOR("NXP Semiconductors");
|
|
|