1*dc23c448SJorge Ramirez-Ortiz // SPDX-License-Identifier: BSD-2-Clause
2*dc23c448SJorge Ramirez-Ortiz /*
3*dc23c448SJorge Ramirez-Ortiz * Copyright (C) Foundries Ltd. 2022.
4*dc23c448SJorge Ramirez-Ortiz * Author: Jorge Ramirez <jorge@foundries.io>
5*dc23c448SJorge Ramirez-Ortiz */
6*dc23c448SJorge Ramirez-Ortiz
7*dc23c448SJorge Ramirez-Ortiz #include <assert.h>
8*dc23c448SJorge Ramirez-Ortiz #include <crypto/crypto.h>
9*dc23c448SJorge Ramirez-Ortiz #include <crypto/crypto_impl.h>
10*dc23c448SJorge Ramirez-Ortiz #include <crypto/internal_aes-gcm.h>
11*dc23c448SJorge Ramirez-Ortiz #include <drvcrypt.h>
12*dc23c448SJorge Ramirez-Ortiz #include <drvcrypt_authenc.h>
13*dc23c448SJorge Ramirez-Ortiz #include <initcall.h>
14*dc23c448SJorge Ramirez-Ortiz #include <ipi.h>
15*dc23c448SJorge Ramirez-Ortiz #include <kernel/boot.h>
16*dc23c448SJorge Ramirez-Ortiz #include <kernel/dt.h>
17*dc23c448SJorge Ramirez-Ortiz #include <kernel/panic.h>
18*dc23c448SJorge Ramirez-Ortiz #include <kernel/spinlock.h>
19*dc23c448SJorge Ramirez-Ortiz #include <libfdt.h>
20*dc23c448SJorge Ramirez-Ortiz #include <mm/core_memprot.h>
21*dc23c448SJorge Ramirez-Ortiz #include <stdlib.h>
22*dc23c448SJorge Ramirez-Ortiz #include <string.h>
23*dc23c448SJorge Ramirez-Ortiz #include <string_ext.h>
24*dc23c448SJorge Ramirez-Ortiz #include <tee_api_types.h>
25*dc23c448SJorge Ramirez-Ortiz #include <tee/cache.h>
26*dc23c448SJorge Ramirez-Ortiz #include <utee_defines.h>
27*dc23c448SJorge Ramirez-Ortiz #include <util.h>
28*dc23c448SJorge Ramirez-Ortiz
29*dc23c448SJorge Ramirez-Ortiz /*
30*dc23c448SJorge Ramirez-Ortiz * This driver does not queue/pad non-aligned data.
31*dc23c448SJorge Ramirez-Ortiz *
32*dc23c448SJorge Ramirez-Ortiz * Allow debug information for future PLM work: if the PLM can not implement
33*dc23c448SJorge Ramirez-Ortiz * the required changes, we might be able to do it in OP-TEE.
34*dc23c448SJorge Ramirez-Ortiz */
35*dc23c448SJorge Ramirez-Ortiz #define DEBUG_VERSAL_AES 0
36*dc23c448SJorge Ramirez-Ortiz
37*dc23c448SJorge Ramirez-Ortiz #define GCM_TAG_LEN 16
38*dc23c448SJorge Ramirez-Ortiz
39*dc23c448SJorge Ramirez-Ortiz #define XSECURE_AES_KEY_SIZE_128 0 /* Key Length = 32 bytes = 256 bits */
40*dc23c448SJorge Ramirez-Ortiz #define XSECURE_AES_KEY_SIZE_256 2 /* Key Length = 16 bytes = 128 bits */
41*dc23c448SJorge Ramirez-Ortiz
42*dc23c448SJorge Ramirez-Ortiz #define XSECURE_ENCRYPT 0
43*dc23c448SJorge Ramirez-Ortiz #define XSECURE_DECRYPT 1
44*dc23c448SJorge Ramirez-Ortiz
45*dc23c448SJorge Ramirez-Ortiz enum versal_aes_err {
46*dc23c448SJorge Ramirez-Ortiz AES_GCM_TAG_MISMATCH = 0x40,
47*dc23c448SJorge Ramirez-Ortiz AES_KEY_CLEAR_ERROR,
48*dc23c448SJorge Ramirez-Ortiz AES_DPA_CM_NOT_SUPPORTED,
49*dc23c448SJorge Ramirez-Ortiz AES_KAT_WRITE_KEY_FAILED_ERROR,
50*dc23c448SJorge Ramirez-Ortiz AES_KAT_DECRYPT_INIT_FAILED_ERROR,
51*dc23c448SJorge Ramirez-Ortiz AES_KAT_GCM_TAG_MISMATCH_ERROR,
52*dc23c448SJorge Ramirez-Ortiz AES_KAT_DATA_MISMATCH_ERROR,
53*dc23c448SJorge Ramirez-Ortiz AES_KAT_FAILED_ERROR,
54*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_WRITE_KEY_FAILED_ERROR,
55*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_KEYLOAD_FAILED_ERROR,
56*dc23c448SJorge Ramirez-Ortiz AESDPACM_SSS_CFG_FAILED_ERROR,
57*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_FAILED_ERROR,
58*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_CHECK1_FAILED_ERROR,
59*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_CHECK2_FAILED_ERROR,
60*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_CHECK3_FAILED_ERROR,
61*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_CHECK4_FAILED_ERROR,
62*dc23c448SJorge Ramirez-Ortiz AESDPACM_KAT_CHECK5_FAILED_ERROR,
63*dc23c448SJorge Ramirez-Ortiz AES_INVALID_PARAM,
64*dc23c448SJorge Ramirez-Ortiz AESKAT_INVALID_PARAM,
65*dc23c448SJorge Ramirez-Ortiz AES_STATE_MISMATCH_ERROR,
66*dc23c448SJorge Ramirez-Ortiz AES_DEVICE_KEY_NOT_ALLOWED,
67*dc23c448SJorge Ramirez-Ortiz };
68*dc23c448SJorge Ramirez-Ortiz
69*dc23c448SJorge Ramirez-Ortiz #define VERSAL_AES_ERROR(m) { . error = (m), .name = TO_STR(m) }
70*dc23c448SJorge Ramirez-Ortiz
versal_aes_error(uint8_t err)71*dc23c448SJorge Ramirez-Ortiz static const char *versal_aes_error(uint8_t err)
72*dc23c448SJorge Ramirez-Ortiz {
73*dc23c448SJorge Ramirez-Ortiz const struct {
74*dc23c448SJorge Ramirez-Ortiz enum versal_aes_err error;
75*dc23c448SJorge Ramirez-Ortiz const char *name;
76*dc23c448SJorge Ramirez-Ortiz } elist[] = {
77*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_GCM_TAG_MISMATCH),
78*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_KEY_CLEAR_ERROR),
79*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_DPA_CM_NOT_SUPPORTED),
80*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_KAT_WRITE_KEY_FAILED_ERROR),
81*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_KAT_DECRYPT_INIT_FAILED_ERROR),
82*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_KAT_GCM_TAG_MISMATCH_ERROR),
83*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_KAT_DATA_MISMATCH_ERROR),
84*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_KAT_FAILED_ERROR),
85*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_WRITE_KEY_FAILED_ERROR),
86*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_KEYLOAD_FAILED_ERROR),
87*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_SSS_CFG_FAILED_ERROR),
88*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_FAILED_ERROR),
89*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_CHECK1_FAILED_ERROR),
90*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_CHECK2_FAILED_ERROR),
91*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_CHECK3_FAILED_ERROR),
92*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_CHECK4_FAILED_ERROR),
93*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESDPACM_KAT_CHECK5_FAILED_ERROR),
94*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_INVALID_PARAM),
95*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AESKAT_INVALID_PARAM),
96*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_STATE_MISMATCH_ERROR),
97*dc23c448SJorge Ramirez-Ortiz VERSAL_AES_ERROR(AES_DEVICE_KEY_NOT_ALLOWED),
98*dc23c448SJorge Ramirez-Ortiz };
99*dc23c448SJorge Ramirez-Ortiz
100*dc23c448SJorge Ramirez-Ortiz if (err >= AES_GCM_TAG_MISMATCH && err <= AES_DEVICE_KEY_NOT_ALLOWED) {
101*dc23c448SJorge Ramirez-Ortiz if (elist[err - AES_GCM_TAG_MISMATCH].name)
102*dc23c448SJorge Ramirez-Ortiz return elist[err - AES_GCM_TAG_MISMATCH].name;
103*dc23c448SJorge Ramirez-Ortiz
104*dc23c448SJorge Ramirez-Ortiz return "Invalid";
105*dc23c448SJorge Ramirez-Ortiz }
106*dc23c448SJorge Ramirez-Ortiz
107*dc23c448SJorge Ramirez-Ortiz return "Unknown";
108*dc23c448SJorge Ramirez-Ortiz }
109*dc23c448SJorge Ramirez-Ortiz
110*dc23c448SJorge Ramirez-Ortiz enum aes_key_src {
111*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_BBRAM_KEY = 0, /* BBRAM Key */
112*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_BBRAM_RED_KEY, /* BBRAM Red Key */
113*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_BH_KEY, /* BH Key */
114*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_BH_RED_KEY, /* BH Red Key */
115*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EFUSE_KEY, /* eFUSE Key */
116*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EFUSE_RED_KEY, /* eFUSE Red Key */
117*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EFUSE_USER_KEY_0, /* eFUSE User Key 0 */
118*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EFUSE_USER_KEY_1, /* eFUSE User Key 1 */
119*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EFUSE_USER_RED_KEY_0, /* eFUSE User Red Key 0 */
120*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EFUSE_USER_RED_KEY_1, /* eFUSE User Red Key 1 */
121*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_KUP_KEY, /* KUP key */
122*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_PUF_KEY, /* PUF key */
123*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_0, /* User Key 0 */
124*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_1, /* User Key 1 */
125*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_2, /* User Key 2 */
126*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_3, /* User Key 3 */
127*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_4, /* User Key 4 */
128*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_5, /* User Key 5 */
129*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_6, /* User Key 6 */
130*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_USER_KEY_7, /* User Key 7 */
131*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_EXPANDED_KEYS, /* Expanded keys */
132*dc23c448SJorge Ramirez-Ortiz XSECURE_AES_ALL_KEYS, /* AES All keys */
133*dc23c448SJorge Ramirez-Ortiz };
134*dc23c448SJorge Ramirez-Ortiz
135*dc23c448SJorge Ramirez-Ortiz struct versal_payload {
136*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem input_cmd;
137*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem src;
138*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem dst;
139*dc23c448SJorge Ramirez-Ortiz bool encrypt;
140*dc23c448SJorge Ramirez-Ortiz };
141*dc23c448SJorge Ramirez-Ortiz
142*dc23c448SJorge Ramirez-Ortiz struct versal_aad {
143*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem mem;
144*dc23c448SJorge Ramirez-Ortiz };
145*dc23c448SJorge Ramirez-Ortiz
146*dc23c448SJorge Ramirez-Ortiz struct versal_node {
147*dc23c448SJorge Ramirez-Ortiz struct versal_payload payload;
148*dc23c448SJorge Ramirez-Ortiz struct versal_aad aad;
149*dc23c448SJorge Ramirez-Ortiz bool is_aad;
150*dc23c448SJorge Ramirez-Ortiz STAILQ_ENTRY(versal_node) link;
151*dc23c448SJorge Ramirez-Ortiz };
152*dc23c448SJorge Ramirez-Ortiz
153*dc23c448SJorge Ramirez-Ortiz struct versal_init {
154*dc23c448SJorge Ramirez-Ortiz uint32_t key_len;
155*dc23c448SJorge Ramirez-Ortiz uint32_t operation;
156*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem key;
157*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem nonce;
158*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem init_buf;
159*dc23c448SJorge Ramirez-Ortiz };
160*dc23c448SJorge Ramirez-Ortiz
161*dc23c448SJorge Ramirez-Ortiz struct versal_ae_ctx {
162*dc23c448SJorge Ramirez-Ortiz struct crypto_authenc_ctx a_ctx;
163*dc23c448SJorge Ramirez-Ortiz };
164*dc23c448SJorge Ramirez-Ortiz
165*dc23c448SJorge Ramirez-Ortiz struct versal_context_node {
166*dc23c448SJorge Ramirez-Ortiz struct versal_ae_ctx *ctx;
167*dc23c448SJorge Ramirez-Ortiz STAILQ_ENTRY(versal_context_node) link;
168*dc23c448SJorge Ramirez-Ortiz };
169*dc23c448SJorge Ramirez-Ortiz
170*dc23c448SJorge Ramirez-Ortiz enum engine_state {
171*dc23c448SJorge Ramirez-Ortiz READY = 1, INIT = 2, FINALIZED = 3,
172*dc23c448SJorge Ramirez-Ortiz };
173*dc23c448SJorge Ramirez-Ortiz
174*dc23c448SJorge Ramirez-Ortiz static struct mutex engine_lock = MUTEX_INITIALIZER;
175*dc23c448SJorge Ramirez-Ortiz
176*dc23c448SJorge Ramirez-Ortiz static struct versal_engine {
177*dc23c448SJorge Ramirez-Ortiz enum aes_key_src key_src;
178*dc23c448SJorge Ramirez-Ortiz enum engine_state state;
179*dc23c448SJorge Ramirez-Ortiz struct versal_init init;
180*dc23c448SJorge Ramirez-Ortiz struct refcount refc;
181*dc23c448SJorge Ramirez-Ortiz struct mutex *lock; /* protect the HW instance */
182*dc23c448SJorge Ramirez-Ortiz STAILQ_HEAD(authenc_context_list, versal_context_node) context_list;
183*dc23c448SJorge Ramirez-Ortiz STAILQ_HEAD(authenc_replay_list, versal_node) replay_list;
184*dc23c448SJorge Ramirez-Ortiz } engine = {
185*dc23c448SJorge Ramirez-Ortiz .key_src = XSECURE_AES_USER_KEY_0,
186*dc23c448SJorge Ramirez-Ortiz .lock = &engine_lock,
187*dc23c448SJorge Ramirez-Ortiz };
188*dc23c448SJorge Ramirez-Ortiz
to_versal_ctx(struct crypto_authenc_ctx * ctx)189*dc23c448SJorge Ramirez-Ortiz static struct versal_ae_ctx *to_versal_ctx(struct crypto_authenc_ctx *ctx)
190*dc23c448SJorge Ramirez-Ortiz {
191*dc23c448SJorge Ramirez-Ortiz assert(ctx);
192*dc23c448SJorge Ramirez-Ortiz
193*dc23c448SJorge Ramirez-Ortiz return container_of(ctx, struct versal_ae_ctx, a_ctx);
194*dc23c448SJorge Ramirez-Ortiz }
195*dc23c448SJorge Ramirez-Ortiz
replay_init(void)196*dc23c448SJorge Ramirez-Ortiz static TEE_Result replay_init(void)
197*dc23c448SJorge Ramirez-Ortiz {
198*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
199*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
200*dc23c448SJorge Ramirez-Ortiz
201*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_INIT, &arg, &err)) {
202*dc23c448SJorge Ramirez-Ortiz EMSG("AES_INIT error");
203*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
204*dc23c448SJorge Ramirez-Ortiz }
205*dc23c448SJorge Ramirez-Ortiz
206*dc23c448SJorge Ramirez-Ortiz arg.data[arg.dlen++] = engine.init.key_len;
207*dc23c448SJorge Ramirez-Ortiz arg.data[arg.dlen++] = engine.key_src;
208*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = engine.init.key;
209*dc23c448SJorge Ramirez-Ortiz
210*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_WRITE_KEY, &arg, &err)) {
211*dc23c448SJorge Ramirez-Ortiz EMSG("AES_WRITE_KEY error");
212*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
213*dc23c448SJorge Ramirez-Ortiz }
214*dc23c448SJorge Ramirez-Ortiz
215*dc23c448SJorge Ramirez-Ortiz memset(&arg, 0, sizeof(arg));
216*dc23c448SJorge Ramirez-Ortiz
217*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = engine.init.init_buf;
218*dc23c448SJorge Ramirez-Ortiz arg.ibuf[1].mem = engine.init.nonce;
219*dc23c448SJorge Ramirez-Ortiz arg.ibuf[1].only_cache = true;
220*dc23c448SJorge Ramirez-Ortiz
221*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_OP_INIT, &arg, &err)) {
222*dc23c448SJorge Ramirez-Ortiz EMSG("AES_OP_INIT error");
223*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
224*dc23c448SJorge Ramirez-Ortiz }
225*dc23c448SJorge Ramirez-Ortiz
226*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
227*dc23c448SJorge Ramirez-Ortiz }
228*dc23c448SJorge Ramirez-Ortiz
replay_aad(struct versal_aad * p)229*dc23c448SJorge Ramirez-Ortiz static TEE_Result replay_aad(struct versal_aad *p)
230*dc23c448SJorge Ramirez-Ortiz {
231*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
232*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
233*dc23c448SJorge Ramirez-Ortiz
234*dc23c448SJorge Ramirez-Ortiz arg.data[arg.dlen++] = p->mem.len % 16 ? p->mem.alloc_len : p->mem.len;
235*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = p->mem;
236*dc23c448SJorge Ramirez-Ortiz
237*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_UPDATE_AAD, &arg, &err)) {
238*dc23c448SJorge Ramirez-Ortiz EMSG("AES_UPDATE_AAD error: %s", versal_aes_error(err));
239*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
240*dc23c448SJorge Ramirez-Ortiz }
241*dc23c448SJorge Ramirez-Ortiz
242*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
243*dc23c448SJorge Ramirez-Ortiz }
244*dc23c448SJorge Ramirez-Ortiz
replay_payload(struct versal_payload * p)245*dc23c448SJorge Ramirez-Ortiz static TEE_Result replay_payload(struct versal_payload *p)
246*dc23c448SJorge Ramirez-Ortiz {
247*dc23c448SJorge Ramirez-Ortiz enum versal_crypto_api id = VERSAL_AES_DECRYPT_UPDATE;
248*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
249*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
250*dc23c448SJorge Ramirez-Ortiz
251*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = p->input_cmd;
252*dc23c448SJorge Ramirez-Ortiz arg.ibuf[1].mem = p->dst;
253*dc23c448SJorge Ramirez-Ortiz arg.ibuf[2].mem = p->src;
254*dc23c448SJorge Ramirez-Ortiz
255*dc23c448SJorge Ramirez-Ortiz if (p->encrypt)
256*dc23c448SJorge Ramirez-Ortiz id = VERSAL_AES_ENCRYPT_UPDATE;
257*dc23c448SJorge Ramirez-Ortiz
258*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(id, &arg, &err)) {
259*dc23c448SJorge Ramirez-Ortiz EMSG("AES_UPDATE_PAYLOAD error: %s", versal_aes_error(err));
260*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
261*dc23c448SJorge Ramirez-Ortiz }
262*dc23c448SJorge Ramirez-Ortiz
263*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
264*dc23c448SJorge Ramirez-Ortiz }
265*dc23c448SJorge Ramirez-Ortiz
do_replay(void)266*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_replay(void)
267*dc23c448SJorge Ramirez-Ortiz {
268*dc23c448SJorge Ramirez-Ortiz struct versal_node *node = NULL;
269*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
270*dc23c448SJorge Ramirez-Ortiz
271*dc23c448SJorge Ramirez-Ortiz ret = replay_init();
272*dc23c448SJorge Ramirez-Ortiz if (ret)
273*dc23c448SJorge Ramirez-Ortiz return ret;
274*dc23c448SJorge Ramirez-Ortiz
275*dc23c448SJorge Ramirez-Ortiz STAILQ_FOREACH(node, &engine.replay_list, link) {
276*dc23c448SJorge Ramirez-Ortiz if (node->is_aad) {
277*dc23c448SJorge Ramirez-Ortiz ret = replay_aad(&node->aad);
278*dc23c448SJorge Ramirez-Ortiz if (ret)
279*dc23c448SJorge Ramirez-Ortiz return ret;
280*dc23c448SJorge Ramirez-Ortiz } else {
281*dc23c448SJorge Ramirez-Ortiz ret = replay_payload(&node->payload);
282*dc23c448SJorge Ramirez-Ortiz if (ret)
283*dc23c448SJorge Ramirez-Ortiz return ret;
284*dc23c448SJorge Ramirez-Ortiz }
285*dc23c448SJorge Ramirez-Ortiz }
286*dc23c448SJorge Ramirez-Ortiz
287*dc23c448SJorge Ramirez-Ortiz /* Engine has been init */
288*dc23c448SJorge Ramirez-Ortiz engine.state = INIT;
289*dc23c448SJorge Ramirez-Ortiz
290*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
291*dc23c448SJorge Ramirez-Ortiz }
292*dc23c448SJorge Ramirez-Ortiz
engine_in_use(void)293*dc23c448SJorge Ramirez-Ortiz static bool engine_in_use(void)
294*dc23c448SJorge Ramirez-Ortiz {
295*dc23c448SJorge Ramirez-Ortiz if (STAILQ_EMPTY(&engine.context_list))
296*dc23c448SJorge Ramirez-Ortiz return false;
297*dc23c448SJorge Ramirez-Ortiz
298*dc23c448SJorge Ramirez-Ortiz return true;
299*dc23c448SJorge Ramirez-Ortiz }
300*dc23c448SJorge Ramirez-Ortiz
context_allowed(struct crypto_authenc_ctx * ctx)301*dc23c448SJorge Ramirez-Ortiz static bool context_allowed(struct crypto_authenc_ctx *ctx)
302*dc23c448SJorge Ramirez-Ortiz {
303*dc23c448SJorge Ramirez-Ortiz struct versal_context_node *node = NULL;
304*dc23c448SJorge Ramirez-Ortiz
305*dc23c448SJorge Ramirez-Ortiz STAILQ_FOREACH(node, &engine.context_list, link) {
306*dc23c448SJorge Ramirez-Ortiz if (node->ctx == to_versal_ctx(ctx))
307*dc23c448SJorge Ramirez-Ortiz return true;
308*dc23c448SJorge Ramirez-Ortiz }
309*dc23c448SJorge Ramirez-Ortiz
310*dc23c448SJorge Ramirez-Ortiz return false;
311*dc23c448SJorge Ramirez-Ortiz }
312*dc23c448SJorge Ramirez-Ortiz
do_init(struct drvcrypt_authenc_init * dinit)313*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_init(struct drvcrypt_authenc_init *dinit)
314*dc23c448SJorge Ramirez-Ortiz {
315*dc23c448SJorge Ramirez-Ortiz uint32_t key_len = XSECURE_AES_KEY_SIZE_128;
316*dc23c448SJorge Ramirez-Ortiz struct versal_context_node *node = NULL;
317*dc23c448SJorge Ramirez-Ortiz struct versal_aes_init *init = NULL;
318*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem init_buf = { };
319*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem key = { };
320*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem nonce = { };
321*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
322*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
323*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
324*dc23c448SJorge Ramirez-Ortiz
325*dc23c448SJorge Ramirez-Ortiz if (engine_in_use()) {
326*dc23c448SJorge Ramirez-Ortiz EMSG("Versal: AES-GCM Engine busy");
327*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
328*dc23c448SJorge Ramirez-Ortiz }
329*dc23c448SJorge Ramirez-Ortiz
330*dc23c448SJorge Ramirez-Ortiz if (dinit->key.length != 32 && dinit->key.length != 16)
331*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BAD_PARAMETERS;
332*dc23c448SJorge Ramirez-Ortiz
333*dc23c448SJorge Ramirez-Ortiz if (dinit->key.length == 32)
334*dc23c448SJorge Ramirez-Ortiz key_len = XSECURE_AES_KEY_SIZE_256;
335*dc23c448SJorge Ramirez-Ortiz
336*dc23c448SJorge Ramirez-Ortiz if (engine.state != READY)
337*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BAD_STATE;
338*dc23c448SJorge Ramirez-Ortiz
339*dc23c448SJorge Ramirez-Ortiz /* Initialize the AES engine */
340*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_INIT, &arg, &err)) {
341*dc23c448SJorge Ramirez-Ortiz EMSG("AES_INIT error: %s", versal_aes_error(err));
342*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
343*dc23c448SJorge Ramirez-Ortiz }
344*dc23c448SJorge Ramirez-Ortiz
345*dc23c448SJorge Ramirez-Ortiz /* Write the key */
346*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(dinit->key.length, dinit->key.data, &key);
347*dc23c448SJorge Ramirez-Ortiz
348*dc23c448SJorge Ramirez-Ortiz arg.data[arg.dlen++] = key_len;
349*dc23c448SJorge Ramirez-Ortiz arg.data[arg.dlen++] = engine.key_src;
350*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = key;
351*dc23c448SJorge Ramirez-Ortiz
352*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_WRITE_KEY, &arg, &err)) {
353*dc23c448SJorge Ramirez-Ortiz EMSG("AES_WRITE_KEY error: %s", versal_aes_error(err));
354*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_GENERIC;
355*dc23c448SJorge Ramirez-Ortiz goto error;
356*dc23c448SJorge Ramirez-Ortiz }
357*dc23c448SJorge Ramirez-Ortiz
358*dc23c448SJorge Ramirez-Ortiz memset(&arg, 0, sizeof(arg));
359*dc23c448SJorge Ramirez-Ortiz
360*dc23c448SJorge Ramirez-Ortiz /* Send the initialization structure */
361*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(sizeof(*init), NULL, &init_buf);
362*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(dinit->nonce.length, dinit->nonce.data, &nonce);
363*dc23c448SJorge Ramirez-Ortiz
364*dc23c448SJorge Ramirez-Ortiz init = init_buf.buf;
365*dc23c448SJorge Ramirez-Ortiz init->iv_addr = virt_to_phys(nonce.buf);
366*dc23c448SJorge Ramirez-Ortiz init->operation = dinit->encrypt ? XSECURE_ENCRYPT : XSECURE_DECRYPT;
367*dc23c448SJorge Ramirez-Ortiz init->key_src = engine.key_src;
368*dc23c448SJorge Ramirez-Ortiz init->key_len = key_len;
369*dc23c448SJorge Ramirez-Ortiz
370*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = init_buf;
371*dc23c448SJorge Ramirez-Ortiz arg.ibuf[1].mem = nonce;
372*dc23c448SJorge Ramirez-Ortiz arg.ibuf[1].only_cache = true;
373*dc23c448SJorge Ramirez-Ortiz
374*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_OP_INIT, &arg, &err)) {
375*dc23c448SJorge Ramirez-Ortiz EMSG("AES_OP_INIT error: %s", versal_aes_error(err));
376*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_GENERIC;
377*dc23c448SJorge Ramirez-Ortiz goto error;
378*dc23c448SJorge Ramirez-Ortiz }
379*dc23c448SJorge Ramirez-Ortiz
380*dc23c448SJorge Ramirez-Ortiz node = calloc(1, sizeof(*node));
381*dc23c448SJorge Ramirez-Ortiz if (!node) {
382*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_OUT_OF_MEMORY;
383*dc23c448SJorge Ramirez-Ortiz goto error;
384*dc23c448SJorge Ramirez-Ortiz }
385*dc23c448SJorge Ramirez-Ortiz
386*dc23c448SJorge Ramirez-Ortiz /* Save key context */
387*dc23c448SJorge Ramirez-Ortiz engine.init.operation = dinit->encrypt ?
388*dc23c448SJorge Ramirez-Ortiz XSECURE_ENCRYPT : XSECURE_DECRYPT;
389*dc23c448SJorge Ramirez-Ortiz engine.init.key_len = key_len;
390*dc23c448SJorge Ramirez-Ortiz engine.init.init_buf = init_buf;
391*dc23c448SJorge Ramirez-Ortiz engine.init.nonce = nonce;
392*dc23c448SJorge Ramirez-Ortiz engine.init.key = key;
393*dc23c448SJorge Ramirez-Ortiz
394*dc23c448SJorge Ramirez-Ortiz /* Active context */
395*dc23c448SJorge Ramirez-Ortiz node->ctx = to_versal_ctx(dinit->ctx);
396*dc23c448SJorge Ramirez-Ortiz STAILQ_INSERT_TAIL(&engine.context_list, node, link);
397*dc23c448SJorge Ramirez-Ortiz
398*dc23c448SJorge Ramirez-Ortiz /* Engine has been init*/
399*dc23c448SJorge Ramirez-Ortiz engine.state = INIT;
400*dc23c448SJorge Ramirez-Ortiz
401*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
402*dc23c448SJorge Ramirez-Ortiz error:
403*dc23c448SJorge Ramirez-Ortiz free(key.buf);
404*dc23c448SJorge Ramirez-Ortiz free(init_buf.buf);
405*dc23c448SJorge Ramirez-Ortiz free(nonce.buf);
406*dc23c448SJorge Ramirez-Ortiz
407*dc23c448SJorge Ramirez-Ortiz return ret;
408*dc23c448SJorge Ramirez-Ortiz }
409*dc23c448SJorge Ramirez-Ortiz
do_update_aad(struct drvcrypt_authenc_update_aad * dupdate)410*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_update_aad(struct drvcrypt_authenc_update_aad *dupdate)
411*dc23c448SJorge Ramirez-Ortiz {
412*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
413*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem p = { };
414*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
415*dc23c448SJorge Ramirez-Ortiz struct versal_node *node = NULL;
416*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
417*dc23c448SJorge Ramirez-Ortiz
418*dc23c448SJorge Ramirez-Ortiz /* This context has not been inited */
419*dc23c448SJorge Ramirez-Ortiz if (!context_allowed(dupdate->ctx))
420*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
421*dc23c448SJorge Ramirez-Ortiz
422*dc23c448SJorge Ramirez-Ortiz /* There is a copy of the context: don't allow updates, only finalize */
423*dc23c448SJorge Ramirez-Ortiz if (refcount_val(&engine.refc) > 1)
424*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
425*dc23c448SJorge Ramirez-Ortiz
426*dc23c448SJorge Ramirez-Ortiz /* There was a copy of the context and it was finalized, then replay */
427*dc23c448SJorge Ramirez-Ortiz if (engine.state == FINALIZED)
428*dc23c448SJorge Ramirez-Ortiz do_replay();
429*dc23c448SJorge Ramirez-Ortiz
430*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(dupdate->aad.length, dupdate->aad.data, &p);
431*dc23c448SJorge Ramirez-Ortiz
432*dc23c448SJorge Ramirez-Ortiz arg.data[arg.dlen++] = p.len % 16 ? p.alloc_len : p.len;
433*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = p;
434*dc23c448SJorge Ramirez-Ortiz
435*dc23c448SJorge Ramirez-Ortiz #if DEBUG_VERSAL_AES
436*dc23c448SJorge Ramirez-Ortiz IMSG("versal: aad length - requested: %zu, sent to plm: %"PRIu32,
437*dc23c448SJorge Ramirez-Ortiz dupdate->aad.length, arg.data[0]);
438*dc23c448SJorge Ramirez-Ortiz #endif
439*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_UPDATE_AAD, &arg, &err)) {
440*dc23c448SJorge Ramirez-Ortiz EMSG("AES_UPDATE_AAD error: %s", versal_aes_error(err));
441*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_GENERIC;
442*dc23c448SJorge Ramirez-Ortiz goto error;
443*dc23c448SJorge Ramirez-Ortiz }
444*dc23c448SJorge Ramirez-Ortiz
445*dc23c448SJorge Ramirez-Ortiz node = calloc(1, sizeof(*node));
446*dc23c448SJorge Ramirez-Ortiz if (!node) {
447*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_OUT_OF_MEMORY;
448*dc23c448SJorge Ramirez-Ortiz goto error;
449*dc23c448SJorge Ramirez-Ortiz }
450*dc23c448SJorge Ramirez-Ortiz
451*dc23c448SJorge Ramirez-Ortiz /* Save the context */
452*dc23c448SJorge Ramirez-Ortiz node->aad.mem = p;
453*dc23c448SJorge Ramirez-Ortiz node->is_aad = true;
454*dc23c448SJorge Ramirez-Ortiz STAILQ_INSERT_TAIL(&engine.replay_list, node, link);
455*dc23c448SJorge Ramirez-Ortiz
456*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
457*dc23c448SJorge Ramirez-Ortiz error:
458*dc23c448SJorge Ramirez-Ortiz free(p.buf);
459*dc23c448SJorge Ramirez-Ortiz return ret;
460*dc23c448SJorge Ramirez-Ortiz }
461*dc23c448SJorge Ramirez-Ortiz
462*dc23c448SJorge Ramirez-Ortiz static TEE_Result
update_payload(struct drvcrypt_authenc_update_payload * dupdate,bool is_last)463*dc23c448SJorge Ramirez-Ortiz update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last)
464*dc23c448SJorge Ramirez-Ortiz {
465*dc23c448SJorge Ramirez-Ortiz enum versal_crypto_api id = VERSAL_AES_DECRYPT_UPDATE;
466*dc23c448SJorge Ramirez-Ortiz struct versal_aes_input_param *input = NULL;
467*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem input_cmd = { };
468*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem p = { };
469*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem q = { };
470*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
471*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
472*dc23c448SJorge Ramirez-Ortiz struct versal_node *node = NULL;
473*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
474*dc23c448SJorge Ramirez-Ortiz
475*dc23c448SJorge Ramirez-Ortiz if (!context_allowed(dupdate->ctx))
476*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
477*dc23c448SJorge Ramirez-Ortiz
478*dc23c448SJorge Ramirez-Ortiz if (!dupdate->src.length || dupdate->src.length % 4) {
479*dc23c448SJorge Ramirez-Ortiz EMSG("Versal AES payload length not word aligned (len = %zu)",
480*dc23c448SJorge Ramirez-Ortiz dupdate->src.length);
481*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BAD_PARAMETERS;
482*dc23c448SJorge Ramirez-Ortiz }
483*dc23c448SJorge Ramirez-Ortiz
484*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(dupdate->src.length, dupdate->src.data, &p);
485*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(dupdate->dst.length, NULL, &q);
486*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(sizeof(*input), NULL, &input_cmd);
487*dc23c448SJorge Ramirez-Ortiz
488*dc23c448SJorge Ramirez-Ortiz input = input_cmd.buf;
489*dc23c448SJorge Ramirez-Ortiz input->input_addr = virt_to_phys(p.buf);
490*dc23c448SJorge Ramirez-Ortiz input->input_len = p.len % 16 ? p.alloc_len : p.len;
491*dc23c448SJorge Ramirez-Ortiz input->is_last = is_last;
492*dc23c448SJorge Ramirez-Ortiz
493*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = input_cmd;
494*dc23c448SJorge Ramirez-Ortiz arg.ibuf[1].mem = q;
495*dc23c448SJorge Ramirez-Ortiz arg.ibuf[2].mem = p;
496*dc23c448SJorge Ramirez-Ortiz
497*dc23c448SJorge Ramirez-Ortiz if (dupdate->encrypt)
498*dc23c448SJorge Ramirez-Ortiz id = VERSAL_AES_ENCRYPT_UPDATE;
499*dc23c448SJorge Ramirez-Ortiz
500*dc23c448SJorge Ramirez-Ortiz #if DEBUG_VERSAL_AES
501*dc23c448SJorge Ramirez-Ortiz IMSG("versal: payload length - requested %zu, sent to plm: %"PRIu32,
502*dc23c448SJorge Ramirez-Ortiz dupdate->src.length, input->input_len);
503*dc23c448SJorge Ramirez-Ortiz IMSG("versal: destination length - %zu ", dupdate->dst.length);
504*dc23c448SJorge Ramirez-Ortiz #endif
505*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(id, &arg, &err)) {
506*dc23c448SJorge Ramirez-Ortiz EMSG("AES_UPDATE_PAYLOAD error: %s", versal_aes_error(err));
507*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_GENERIC;
508*dc23c448SJorge Ramirez-Ortiz goto out;
509*dc23c448SJorge Ramirez-Ortiz }
510*dc23c448SJorge Ramirez-Ortiz
511*dc23c448SJorge Ramirez-Ortiz if (dupdate->dst.data)
512*dc23c448SJorge Ramirez-Ortiz memcpy(dupdate->dst.data, q.buf, dupdate->dst.length);
513*dc23c448SJorge Ramirez-Ortiz
514*dc23c448SJorge Ramirez-Ortiz if (!is_last) {
515*dc23c448SJorge Ramirez-Ortiz node = calloc(1, sizeof(*node));
516*dc23c448SJorge Ramirez-Ortiz if (!node) {
517*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_OUT_OF_MEMORY;
518*dc23c448SJorge Ramirez-Ortiz goto out;
519*dc23c448SJorge Ramirez-Ortiz }
520*dc23c448SJorge Ramirez-Ortiz
521*dc23c448SJorge Ramirez-Ortiz node->is_aad = false;
522*dc23c448SJorge Ramirez-Ortiz node->payload.dst = q;
523*dc23c448SJorge Ramirez-Ortiz node->payload.src = p;
524*dc23c448SJorge Ramirez-Ortiz node->payload.input_cmd = input_cmd;
525*dc23c448SJorge Ramirez-Ortiz node->payload.encrypt = dupdate->encrypt;
526*dc23c448SJorge Ramirez-Ortiz STAILQ_INSERT_TAIL(&engine.replay_list, node, link);
527*dc23c448SJorge Ramirez-Ortiz
528*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
529*dc23c448SJorge Ramirez-Ortiz }
530*dc23c448SJorge Ramirez-Ortiz out:
531*dc23c448SJorge Ramirez-Ortiz free(p.buf);
532*dc23c448SJorge Ramirez-Ortiz free(q.buf);
533*dc23c448SJorge Ramirez-Ortiz free(input_cmd.buf);
534*dc23c448SJorge Ramirez-Ortiz
535*dc23c448SJorge Ramirez-Ortiz return ret;
536*dc23c448SJorge Ramirez-Ortiz }
537*dc23c448SJorge Ramirez-Ortiz
do_update_payload(struct drvcrypt_authenc_update_payload * p)538*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_update_payload(struct drvcrypt_authenc_update_payload *p)
539*dc23c448SJorge Ramirez-Ortiz {
540*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
541*dc23c448SJorge Ramirez-Ortiz
542*dc23c448SJorge Ramirez-Ortiz if (!context_allowed(p->ctx))
543*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
544*dc23c448SJorge Ramirez-Ortiz
545*dc23c448SJorge Ramirez-Ortiz /*
546*dc23c448SJorge Ramirez-Ortiz * If there is a copy, we don't allow updates until one of the copies
547*dc23c448SJorge Ramirez-Ortiz * has been deleted
548*dc23c448SJorge Ramirez-Ortiz */
549*dc23c448SJorge Ramirez-Ortiz if (refcount_val(&engine.refc) > 1)
550*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
551*dc23c448SJorge Ramirez-Ortiz
552*dc23c448SJorge Ramirez-Ortiz /*
553*dc23c448SJorge Ramirez-Ortiz * If there was a copy and it was finalized, we need to replay before
554*dc23c448SJorge Ramirez-Ortiz * we can update; do not clear the list so the state can be copied
555*dc23c448SJorge Ramirez-Ortiz */
556*dc23c448SJorge Ramirez-Ortiz if (engine.state == FINALIZED) {
557*dc23c448SJorge Ramirez-Ortiz ret = do_replay();
558*dc23c448SJorge Ramirez-Ortiz if (ret)
559*dc23c448SJorge Ramirez-Ortiz return ret;
560*dc23c448SJorge Ramirez-Ortiz }
561*dc23c448SJorge Ramirez-Ortiz
562*dc23c448SJorge Ramirez-Ortiz return update_payload(p, false);
563*dc23c448SJorge Ramirez-Ortiz }
564*dc23c448SJorge Ramirez-Ortiz
do_enc_final(struct drvcrypt_authenc_final * dfinal)565*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_enc_final(struct drvcrypt_authenc_final *dfinal)
566*dc23c448SJorge Ramirez-Ortiz {
567*dc23c448SJorge Ramirez-Ortiz struct drvcrypt_authenc_update_payload last = { };
568*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
569*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem p = { };
570*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
571*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
572*dc23c448SJorge Ramirez-Ortiz
573*dc23c448SJorge Ramirez-Ortiz if (!context_allowed(dfinal->ctx))
574*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
575*dc23c448SJorge Ramirez-Ortiz
576*dc23c448SJorge Ramirez-Ortiz if (engine.state == FINALIZED) {
577*dc23c448SJorge Ramirez-Ortiz DMSG("Operation was already finalized");
578*dc23c448SJorge Ramirez-Ortiz ret = do_replay();
579*dc23c448SJorge Ramirez-Ortiz if (ret)
580*dc23c448SJorge Ramirez-Ortiz return ret;
581*dc23c448SJorge Ramirez-Ortiz }
582*dc23c448SJorge Ramirez-Ortiz
583*dc23c448SJorge Ramirez-Ortiz if (engine.state != INIT)
584*dc23c448SJorge Ramirez-Ortiz panic();
585*dc23c448SJorge Ramirez-Ortiz
586*dc23c448SJorge Ramirez-Ortiz last.ctx = dfinal->ctx;
587*dc23c448SJorge Ramirez-Ortiz last.dst = dfinal->dst;
588*dc23c448SJorge Ramirez-Ortiz last.encrypt = true;
589*dc23c448SJorge Ramirez-Ortiz last.src = dfinal->src;
590*dc23c448SJorge Ramirez-Ortiz
591*dc23c448SJorge Ramirez-Ortiz ret = update_payload(&last, true);
592*dc23c448SJorge Ramirez-Ortiz if (ret)
593*dc23c448SJorge Ramirez-Ortiz return ret;
594*dc23c448SJorge Ramirez-Ortiz
595*dc23c448SJorge Ramirez-Ortiz memcpy(dfinal->dst.data, last.dst.data, dfinal->dst.length);
596*dc23c448SJorge Ramirez-Ortiz
597*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(GCM_TAG_LEN, NULL, &p);
598*dc23c448SJorge Ramirez-Ortiz
599*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = p;
600*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_ENCRYPT_FINAL, &arg, &err)) {
601*dc23c448SJorge Ramirez-Ortiz EMSG("AES_ENCRYPT_FINAL error: %s", versal_aes_error(err));
602*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_GENERIC;
603*dc23c448SJorge Ramirez-Ortiz goto out;
604*dc23c448SJorge Ramirez-Ortiz }
605*dc23c448SJorge Ramirez-Ortiz
606*dc23c448SJorge Ramirez-Ortiz memcpy(dfinal->tag.data, p.buf, GCM_TAG_LEN);
607*dc23c448SJorge Ramirez-Ortiz dfinal->tag.length = GCM_TAG_LEN;
608*dc23c448SJorge Ramirez-Ortiz out:
609*dc23c448SJorge Ramirez-Ortiz free(p.buf);
610*dc23c448SJorge Ramirez-Ortiz
611*dc23c448SJorge Ramirez-Ortiz if (refcount_val(&engine.refc) > 1)
612*dc23c448SJorge Ramirez-Ortiz engine.state = FINALIZED;
613*dc23c448SJorge Ramirez-Ortiz else
614*dc23c448SJorge Ramirez-Ortiz engine.state = READY;
615*dc23c448SJorge Ramirez-Ortiz
616*dc23c448SJorge Ramirez-Ortiz return ret;
617*dc23c448SJorge Ramirez-Ortiz }
618*dc23c448SJorge Ramirez-Ortiz
do_dec_final(struct drvcrypt_authenc_final * dfinal)619*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_dec_final(struct drvcrypt_authenc_final *dfinal)
620*dc23c448SJorge Ramirez-Ortiz {
621*dc23c448SJorge Ramirez-Ortiz struct drvcrypt_authenc_update_payload last = { };
622*dc23c448SJorge Ramirez-Ortiz struct versal_cmd_args arg = { };
623*dc23c448SJorge Ramirez-Ortiz struct versal_mbox_mem p = { };
624*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
625*dc23c448SJorge Ramirez-Ortiz uint32_t err = 0;
626*dc23c448SJorge Ramirez-Ortiz
627*dc23c448SJorge Ramirez-Ortiz if (!context_allowed(dfinal->ctx))
628*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_BUSY;
629*dc23c448SJorge Ramirez-Ortiz
630*dc23c448SJorge Ramirez-Ortiz if (engine.state == FINALIZED) {
631*dc23c448SJorge Ramirez-Ortiz DMSG("Operation was already finalized");
632*dc23c448SJorge Ramirez-Ortiz ret = do_replay();
633*dc23c448SJorge Ramirez-Ortiz if (ret)
634*dc23c448SJorge Ramirez-Ortiz return ret;
635*dc23c448SJorge Ramirez-Ortiz }
636*dc23c448SJorge Ramirez-Ortiz
637*dc23c448SJorge Ramirez-Ortiz if (engine.state != INIT)
638*dc23c448SJorge Ramirez-Ortiz panic();
639*dc23c448SJorge Ramirez-Ortiz
640*dc23c448SJorge Ramirez-Ortiz last.encrypt = false;
641*dc23c448SJorge Ramirez-Ortiz last.ctx = dfinal->ctx;
642*dc23c448SJorge Ramirez-Ortiz last.dst = dfinal->dst;
643*dc23c448SJorge Ramirez-Ortiz last.src = dfinal->src;
644*dc23c448SJorge Ramirez-Ortiz
645*dc23c448SJorge Ramirez-Ortiz ret = update_payload(&last, true);
646*dc23c448SJorge Ramirez-Ortiz if (ret)
647*dc23c448SJorge Ramirez-Ortiz return ret;
648*dc23c448SJorge Ramirez-Ortiz
649*dc23c448SJorge Ramirez-Ortiz versal_mbox_alloc(dfinal->tag.length, dfinal->tag.data, &p);
650*dc23c448SJorge Ramirez-Ortiz arg.ibuf[0].mem = p;
651*dc23c448SJorge Ramirez-Ortiz
652*dc23c448SJorge Ramirez-Ortiz if (versal_crypto_request(VERSAL_AES_DECRYPT_FINAL, &arg, &err)) {
653*dc23c448SJorge Ramirez-Ortiz EMSG("AES_DECRYPT_FINAL error: %s", versal_aes_error(err));
654*dc23c448SJorge Ramirez-Ortiz ret = TEE_ERROR_GENERIC;
655*dc23c448SJorge Ramirez-Ortiz goto out;
656*dc23c448SJorge Ramirez-Ortiz }
657*dc23c448SJorge Ramirez-Ortiz
658*dc23c448SJorge Ramirez-Ortiz memcpy(dfinal->dst.data, last.dst.data, dfinal->dst.length);
659*dc23c448SJorge Ramirez-Ortiz memcpy(dfinal->tag.data, p.buf, GCM_TAG_LEN);
660*dc23c448SJorge Ramirez-Ortiz dfinal->tag.length = GCM_TAG_LEN;
661*dc23c448SJorge Ramirez-Ortiz out:
662*dc23c448SJorge Ramirez-Ortiz free(p.buf);
663*dc23c448SJorge Ramirez-Ortiz
664*dc23c448SJorge Ramirez-Ortiz if (refcount_val(&engine.refc) > 1)
665*dc23c448SJorge Ramirez-Ortiz engine.state = FINALIZED;
666*dc23c448SJorge Ramirez-Ortiz else
667*dc23c448SJorge Ramirez-Ortiz engine.state = READY;
668*dc23c448SJorge Ramirez-Ortiz
669*dc23c448SJorge Ramirez-Ortiz return ret;
670*dc23c448SJorge Ramirez-Ortiz }
671*dc23c448SJorge Ramirez-Ortiz
do_final(void * ctx __unused)672*dc23c448SJorge Ramirez-Ortiz static void do_final(void *ctx __unused)
673*dc23c448SJorge Ramirez-Ortiz {
674*dc23c448SJorge Ramirez-Ortiz }
675*dc23c448SJorge Ramirez-Ortiz
do_free(void * ctx)676*dc23c448SJorge Ramirez-Ortiz static void do_free(void *ctx)
677*dc23c448SJorge Ramirez-Ortiz {
678*dc23c448SJorge Ramirez-Ortiz struct versal_ae_ctx *c = to_versal_ctx(ctx);
679*dc23c448SJorge Ramirez-Ortiz struct versal_node *next = NULL;
680*dc23c448SJorge Ramirez-Ortiz struct versal_node *node = NULL;
681*dc23c448SJorge Ramirez-Ortiz struct versal_context_node *ctx_next = NULL;
682*dc23c448SJorge Ramirez-Ortiz struct versal_context_node *ctx_node = NULL;
683*dc23c448SJorge Ramirez-Ortiz bool release = false;
684*dc23c448SJorge Ramirez-Ortiz
685*dc23c448SJorge Ramirez-Ortiz if (refcount_dec(&engine.refc)) {
686*dc23c448SJorge Ramirez-Ortiz /* this is a final release */
687*dc23c448SJorge Ramirez-Ortiz release = true;
688*dc23c448SJorge Ramirez-Ortiz refcount_set(&engine.refc, 1);
689*dc23c448SJorge Ramirez-Ortiz engine.state = READY;
690*dc23c448SJorge Ramirez-Ortiz free(engine.init.init_buf.buf);
691*dc23c448SJorge Ramirez-Ortiz free(engine.init.nonce.buf);
692*dc23c448SJorge Ramirez-Ortiz free(engine.init.key.buf);
693*dc23c448SJorge Ramirez-Ortiz memset(&engine.init, 0, sizeof(engine.init));
694*dc23c448SJorge Ramirez-Ortiz STAILQ_FOREACH_SAFE(node, &engine.replay_list, link, next) {
695*dc23c448SJorge Ramirez-Ortiz STAILQ_REMOVE(&engine.replay_list, node,
696*dc23c448SJorge Ramirez-Ortiz versal_node, link);
697*dc23c448SJorge Ramirez-Ortiz if (node->is_aad) {
698*dc23c448SJorge Ramirez-Ortiz free(node->aad.mem.buf);
699*dc23c448SJorge Ramirez-Ortiz } else {
700*dc23c448SJorge Ramirez-Ortiz free(node->payload.dst.buf);
701*dc23c448SJorge Ramirez-Ortiz free(node->payload.src.buf);
702*dc23c448SJorge Ramirez-Ortiz free(node->payload.input_cmd.buf);
703*dc23c448SJorge Ramirez-Ortiz }
704*dc23c448SJorge Ramirez-Ortiz free(node);
705*dc23c448SJorge Ramirez-Ortiz }
706*dc23c448SJorge Ramirez-Ortiz }
707*dc23c448SJorge Ramirez-Ortiz
708*dc23c448SJorge Ramirez-Ortiz STAILQ_FOREACH_SAFE(ctx_node, &engine.context_list, link, ctx_next) {
709*dc23c448SJorge Ramirez-Ortiz if (c == ctx_node->ctx) {
710*dc23c448SJorge Ramirez-Ortiz STAILQ_REMOVE(&engine.context_list, ctx_node,
711*dc23c448SJorge Ramirez-Ortiz versal_context_node, link);
712*dc23c448SJorge Ramirez-Ortiz free(ctx_node);
713*dc23c448SJorge Ramirez-Ortiz }
714*dc23c448SJorge Ramirez-Ortiz }
715*dc23c448SJorge Ramirez-Ortiz
716*dc23c448SJorge Ramirez-Ortiz if (release && engine_in_use())
717*dc23c448SJorge Ramirez-Ortiz panic();
718*dc23c448SJorge Ramirez-Ortiz
719*dc23c448SJorge Ramirez-Ortiz free(c);
720*dc23c448SJorge Ramirez-Ortiz }
721*dc23c448SJorge Ramirez-Ortiz
do_copy_state(void * dst_ctx,void * src_ctx)722*dc23c448SJorge Ramirez-Ortiz static void do_copy_state(void *dst_ctx, void *src_ctx)
723*dc23c448SJorge Ramirez-Ortiz {
724*dc23c448SJorge Ramirez-Ortiz struct versal_context_node *node = NULL;
725*dc23c448SJorge Ramirez-Ortiz
726*dc23c448SJorge Ramirez-Ortiz STAILQ_FOREACH(node, &engine.context_list, link) {
727*dc23c448SJorge Ramirez-Ortiz if (node->ctx != to_versal_ctx(src_ctx))
728*dc23c448SJorge Ramirez-Ortiz continue;
729*dc23c448SJorge Ramirez-Ortiz /*
730*dc23c448SJorge Ramirez-Ortiz * The running context has been copied: from now on we can only
731*dc23c448SJorge Ramirez-Ortiz * finalize any of the contexts until there is only one active
732*dc23c448SJorge Ramirez-Ortiz * again.
733*dc23c448SJorge Ramirez-Ortiz */
734*dc23c448SJorge Ramirez-Ortiz node = calloc(1, sizeof(*node));
735*dc23c448SJorge Ramirez-Ortiz if (!node)
736*dc23c448SJorge Ramirez-Ortiz panic();
737*dc23c448SJorge Ramirez-Ortiz
738*dc23c448SJorge Ramirez-Ortiz node->ctx = to_versal_ctx(dst_ctx);
739*dc23c448SJorge Ramirez-Ortiz STAILQ_INSERT_TAIL(&engine.context_list, node, link);
740*dc23c448SJorge Ramirez-Ortiz
741*dc23c448SJorge Ramirez-Ortiz /* number of active contexts */
742*dc23c448SJorge Ramirez-Ortiz refcount_inc(&engine.refc);
743*dc23c448SJorge Ramirez-Ortiz
744*dc23c448SJorge Ramirez-Ortiz return;
745*dc23c448SJorge Ramirez-Ortiz }
746*dc23c448SJorge Ramirez-Ortiz
747*dc23c448SJorge Ramirez-Ortiz panic();
748*dc23c448SJorge Ramirez-Ortiz }
749*dc23c448SJorge Ramirez-Ortiz
do_allocate(void ** ctx,uint32_t algo)750*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_allocate(void **ctx, uint32_t algo)
751*dc23c448SJorge Ramirez-Ortiz {
752*dc23c448SJorge Ramirez-Ortiz struct versal_ae_ctx *c = NULL;
753*dc23c448SJorge Ramirez-Ortiz
754*dc23c448SJorge Ramirez-Ortiz if (algo != TEE_ALG_AES_GCM)
755*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_NOT_IMPLEMENTED;
756*dc23c448SJorge Ramirez-Ortiz
757*dc23c448SJorge Ramirez-Ortiz c = calloc(1, sizeof(*c));
758*dc23c448SJorge Ramirez-Ortiz if (!c)
759*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_OUT_OF_MEMORY;
760*dc23c448SJorge Ramirez-Ortiz
761*dc23c448SJorge Ramirez-Ortiz *ctx = &c->a_ctx;
762*dc23c448SJorge Ramirez-Ortiz
763*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
764*dc23c448SJorge Ramirez-Ortiz }
765*dc23c448SJorge Ramirez-Ortiz
766*dc23c448SJorge Ramirez-Ortiz static TEE_Result
do_update_payload_locked(struct drvcrypt_authenc_update_payload * p)767*dc23c448SJorge Ramirez-Ortiz do_update_payload_locked(struct drvcrypt_authenc_update_payload *p)
768*dc23c448SJorge Ramirez-Ortiz {
769*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
770*dc23c448SJorge Ramirez-Ortiz
771*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
772*dc23c448SJorge Ramirez-Ortiz ret = do_update_payload(p);
773*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
774*dc23c448SJorge Ramirez-Ortiz return ret;
775*dc23c448SJorge Ramirez-Ortiz }
776*dc23c448SJorge Ramirez-Ortiz
777*dc23c448SJorge Ramirez-Ortiz static TEE_Result
do_update_aad_locked(struct drvcrypt_authenc_update_aad * p)778*dc23c448SJorge Ramirez-Ortiz do_update_aad_locked(struct drvcrypt_authenc_update_aad *p)
779*dc23c448SJorge Ramirez-Ortiz {
780*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
781*dc23c448SJorge Ramirez-Ortiz
782*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
783*dc23c448SJorge Ramirez-Ortiz ret = do_update_aad(p);
784*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
785*dc23c448SJorge Ramirez-Ortiz return ret;
786*dc23c448SJorge Ramirez-Ortiz }
787*dc23c448SJorge Ramirez-Ortiz
do_copy_state_locked(void * dst,void * src)788*dc23c448SJorge Ramirez-Ortiz static void do_copy_state_locked(void *dst, void *src)
789*dc23c448SJorge Ramirez-Ortiz {
790*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
791*dc23c448SJorge Ramirez-Ortiz do_copy_state(dst, src);
792*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
793*dc23c448SJorge Ramirez-Ortiz }
794*dc23c448SJorge Ramirez-Ortiz
do_enc_final_locked(struct drvcrypt_authenc_final * p)795*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_enc_final_locked(struct drvcrypt_authenc_final *p)
796*dc23c448SJorge Ramirez-Ortiz {
797*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
798*dc23c448SJorge Ramirez-Ortiz
799*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
800*dc23c448SJorge Ramirez-Ortiz ret = do_enc_final(p);
801*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
802*dc23c448SJorge Ramirez-Ortiz return ret;
803*dc23c448SJorge Ramirez-Ortiz }
804*dc23c448SJorge Ramirez-Ortiz
do_dec_final_locked(struct drvcrypt_authenc_final * p)805*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_dec_final_locked(struct drvcrypt_authenc_final *p)
806*dc23c448SJorge Ramirez-Ortiz {
807*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
808*dc23c448SJorge Ramirez-Ortiz
809*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
810*dc23c448SJorge Ramirez-Ortiz ret = do_dec_final(p);
811*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
812*dc23c448SJorge Ramirez-Ortiz return ret;
813*dc23c448SJorge Ramirez-Ortiz }
814*dc23c448SJorge Ramirez-Ortiz
do_free_locked(void * p)815*dc23c448SJorge Ramirez-Ortiz static void do_free_locked(void *p)
816*dc23c448SJorge Ramirez-Ortiz {
817*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
818*dc23c448SJorge Ramirez-Ortiz do_free(p);
819*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
820*dc23c448SJorge Ramirez-Ortiz }
821*dc23c448SJorge Ramirez-Ortiz
do_init_locked(struct drvcrypt_authenc_init * p)822*dc23c448SJorge Ramirez-Ortiz static TEE_Result do_init_locked(struct drvcrypt_authenc_init *p)
823*dc23c448SJorge Ramirez-Ortiz {
824*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
825*dc23c448SJorge Ramirez-Ortiz
826*dc23c448SJorge Ramirez-Ortiz mutex_lock(engine.lock);
827*dc23c448SJorge Ramirez-Ortiz ret = do_init(p);
828*dc23c448SJorge Ramirez-Ortiz mutex_unlock(engine.lock);
829*dc23c448SJorge Ramirez-Ortiz return ret;
830*dc23c448SJorge Ramirez-Ortiz }
831*dc23c448SJorge Ramirez-Ortiz
832*dc23c448SJorge Ramirez-Ortiz static struct drvcrypt_authenc versal_authenc = {
833*dc23c448SJorge Ramirez-Ortiz .update_payload = do_update_payload_locked,
834*dc23c448SJorge Ramirez-Ortiz .update_aad = do_update_aad_locked,
835*dc23c448SJorge Ramirez-Ortiz .copy_state = do_copy_state_locked,
836*dc23c448SJorge Ramirez-Ortiz .enc_final = do_enc_final_locked,
837*dc23c448SJorge Ramirez-Ortiz .dec_final = do_dec_final_locked,
838*dc23c448SJorge Ramirez-Ortiz .free_ctx = do_free_locked,
839*dc23c448SJorge Ramirez-Ortiz .alloc_ctx = do_allocate,
840*dc23c448SJorge Ramirez-Ortiz .init = do_init_locked,
841*dc23c448SJorge Ramirez-Ortiz .final = do_final,
842*dc23c448SJorge Ramirez-Ortiz };
843*dc23c448SJorge Ramirez-Ortiz
enable_secure_status(void)844*dc23c448SJorge Ramirez-Ortiz static TEE_Result enable_secure_status(void)
845*dc23c448SJorge Ramirez-Ortiz {
846*dc23c448SJorge Ramirez-Ortiz /* Once Linux has support, we need to reserve the device */
847*dc23c448SJorge Ramirez-Ortiz return TEE_SUCCESS;
848*dc23c448SJorge Ramirez-Ortiz }
849*dc23c448SJorge Ramirez-Ortiz
versal_register_authenc(void)850*dc23c448SJorge Ramirez-Ortiz static TEE_Result versal_register_authenc(void)
851*dc23c448SJorge Ramirez-Ortiz {
852*dc23c448SJorge Ramirez-Ortiz TEE_Result ret = TEE_SUCCESS;
853*dc23c448SJorge Ramirez-Ortiz
854*dc23c448SJorge Ramirez-Ortiz ret = drvcrypt_register_authenc(&versal_authenc);
855*dc23c448SJorge Ramirez-Ortiz if (ret)
856*dc23c448SJorge Ramirez-Ortiz return ret;
857*dc23c448SJorge Ramirez-Ortiz
858*dc23c448SJorge Ramirez-Ortiz if (engine.key_src < XSECURE_AES_USER_KEY_0 ||
859*dc23c448SJorge Ramirez-Ortiz engine.key_src > XSECURE_AES_USER_KEY_7)
860*dc23c448SJorge Ramirez-Ortiz return TEE_ERROR_GENERIC;
861*dc23c448SJorge Ramirez-Ortiz
862*dc23c448SJorge Ramirez-Ortiz engine.state = READY;
863*dc23c448SJorge Ramirez-Ortiz STAILQ_INIT(&engine.replay_list);
864*dc23c448SJorge Ramirez-Ortiz STAILQ_INIT(&engine.context_list);
865*dc23c448SJorge Ramirez-Ortiz refcount_set(&engine.refc, 1);
866*dc23c448SJorge Ramirez-Ortiz
867*dc23c448SJorge Ramirez-Ortiz return enable_secure_status();
868*dc23c448SJorge Ramirez-Ortiz }
869*dc23c448SJorge Ramirez-Ortiz
870*dc23c448SJorge Ramirez-Ortiz driver_init_late(versal_register_authenc);
871