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, data: adata->key_virt,
45 data_len: adata->keylen_pad,
46 len: 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, jump_cmd: 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, len: ctx_len, LDST_CLASS_2_CCB |
59 LDST_SRCDST_BYTE_CONTEXT);
60
61 /* Class 2 operation */
62 append_operation(desc, options: 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, len: 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
71 FIFOLD_TYPE_MSG | KEY_VLF);
72 /* Store class2 context bytes */
73 append_seq_store(desc, len: 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, data: adata->key_virt, data_len: adata->keylen,
99 len: adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
100 } else { /* UPDATE, FINALIZE */
101 if (is_xcbc_aes(algtype: adata->algtype))
102 /* Load K1 */
103 append_key(desc, ptr: adata->key_dma, len: adata->keylen,
104 CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
105 else /* CMAC */
106 append_key_as_imm(desc, data: adata->key_virt, data_len: adata->keylen,
107 len: adata->keylen, CLASS_1 |
108 KEY_DEST_CLASS_REG);
109 /* Restore context */
110 append_seq_load(desc, len: ctx_len, LDST_CLASS_1_CCB |
111 LDST_SRCDST_BYTE_CONTEXT);
112 }
113
114 set_jump_tgt_here(desc, jump_cmd: skip_key_load);
115
116 /* Class 1 operation */
117 append_operation(desc, options: 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, len: 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, len: digestsize, LDST_CLASS_1_CCB |
135 LDST_SRCDST_BYTE_CONTEXT);
136 if (is_xcbc_aes(algtype: adata->algtype) && state == OP_ALG_AS_INIT)
137 /* Save K1 */
138 append_fifo_store(desc, ptr: adata->key_dma, len: 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");
146

source code of linux/drivers/crypto/caam/caamhash_desc.c