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 | */ |
28 | void 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 | } |
76 | EXPORT_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 | */ |
87 | void 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 | } |
141 | EXPORT_SYMBOL(cnstr_shdsc_sk_hash); |
142 | |
143 | MODULE_LICENSE("Dual BSD/GPL" ); |
144 | MODULE_DESCRIPTION("FSL CAAM ahash descriptors support" ); |
145 | MODULE_AUTHOR("NXP Semiconductors" ); |
146 | |