xref: /optee_os/core/drivers/crypto/versal/ecc_mbox.c (revision ffeec8ba461e8218c2b82d92315186213516e740)
1*ffeec8baSJoachim Foerster // SPDX-License-Identifier: BSD-2-Clause
2*ffeec8baSJoachim Foerster /*
3*ffeec8baSJoachim Foerster  * Copyright (C) Foundries Ltd. 2022.
4*ffeec8baSJoachim Foerster  * Author: Jorge Ramirez <jorge@foundries.io>
5*ffeec8baSJoachim Foerster  */
6*ffeec8baSJoachim Foerster 
7*ffeec8baSJoachim Foerster #include <crypto/crypto_impl.h>
8*ffeec8baSJoachim Foerster #include <drvcrypt.h>
9*ffeec8baSJoachim Foerster #include <drvcrypt_acipher.h>
10*ffeec8baSJoachim Foerster #include <ecc.h>
11*ffeec8baSJoachim Foerster #include <ipi.h>
12*ffeec8baSJoachim Foerster #include <mm/core_memprot.h>
13*ffeec8baSJoachim Foerster #include <kernel/panic.h>
14*ffeec8baSJoachim Foerster #include <string.h>
15*ffeec8baSJoachim Foerster #include <tee/cache.h>
16*ffeec8baSJoachim Foerster #include <tee/tee_cryp_utl.h>
17*ffeec8baSJoachim Foerster #include <util.h>
18*ffeec8baSJoachim Foerster 
19*ffeec8baSJoachim Foerster /* AMD/Xilinx Versal's Known Answer Tests */
20*ffeec8baSJoachim Foerster #define XSECURE_ECC_PRIME	0
21*ffeec8baSJoachim Foerster #define XSECURE_ECC_BINARY	1
22*ffeec8baSJoachim Foerster 
23*ffeec8baSJoachim Foerster enum versal_ecc_err {
24*ffeec8baSJoachim Foerster 	KAT_KEY_NOTVALID_ERROR = 0xC0,
25*ffeec8baSJoachim Foerster 	KAT_FAILED_ERROR,
26*ffeec8baSJoachim Foerster 	NON_SUPPORTED_CURVE,
27*ffeec8baSJoachim Foerster 	KEY_ZERO,
28*ffeec8baSJoachim Foerster 	KEY_WRONG_ORDER,
29*ffeec8baSJoachim Foerster 	KEY_NOT_ON_CURVE,
30*ffeec8baSJoachim Foerster 	BAD_SIGN,
31*ffeec8baSJoachim Foerster 	GEN_SIGN_INCORRECT_HASH_LEN,
32*ffeec8baSJoachim Foerster 	VER_SIGN_INCORRECT_HASH_LEN,
33*ffeec8baSJoachim Foerster 	GEN_SIGN_BAD_RAND_NUM,
34*ffeec8baSJoachim Foerster 	GEN_KEY_ERR,
35*ffeec8baSJoachim Foerster 	INVALID_PARAM,
36*ffeec8baSJoachim Foerster 	VER_SIGN_R_ZERO,
37*ffeec8baSJoachim Foerster 	VER_SIGN_S_ZERO,
38*ffeec8baSJoachim Foerster 	VER_SIGN_R_ORDER_ERROR,
39*ffeec8baSJoachim Foerster 	VER_SIGN_S_ORDER_ERROR,
40*ffeec8baSJoachim Foerster 	KAT_INVLD_CRV_ERROR,
41*ffeec8baSJoachim Foerster };
42*ffeec8baSJoachim Foerster 
43*ffeec8baSJoachim Foerster #define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) }
44*ffeec8baSJoachim Foerster 
45*ffeec8baSJoachim Foerster static const char *versal_ecc_error(uint8_t err)
46*ffeec8baSJoachim Foerster {
47*ffeec8baSJoachim Foerster 	struct {
48*ffeec8baSJoachim Foerster 		enum versal_ecc_err error;
49*ffeec8baSJoachim Foerster 		const char *name;
50*ffeec8baSJoachim Foerster 	} elist[] = {
51*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR),
52*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(KAT_FAILED_ERROR),
53*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE),
54*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(KEY_ZERO),
55*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(KEY_WRONG_ORDER),
56*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE),
57*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(BAD_SIGN),
58*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN),
59*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN),
60*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM),
61*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(GEN_KEY_ERR),
62*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(INVALID_PARAM),
63*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(VER_SIGN_R_ZERO),
64*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(VER_SIGN_S_ZERO),
65*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR),
66*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR),
67*ffeec8baSJoachim Foerster 		VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR),
68*ffeec8baSJoachim Foerster 	};
69*ffeec8baSJoachim Foerster 
70*ffeec8baSJoachim Foerster 	if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) {
71*ffeec8baSJoachim Foerster 		if (elist[err - KAT_KEY_NOTVALID_ERROR].name)
72*ffeec8baSJoachim Foerster 			return elist[err - KAT_KEY_NOTVALID_ERROR].name;
73*ffeec8baSJoachim Foerster 
74*ffeec8baSJoachim Foerster 		return "Invalid";
75*ffeec8baSJoachim Foerster 	}
76*ffeec8baSJoachim Foerster 
77*ffeec8baSJoachim Foerster 	return "Unknown";
78*ffeec8baSJoachim Foerster }
79*ffeec8baSJoachim Foerster 
80*ffeec8baSJoachim Foerster static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits)
81*ffeec8baSJoachim Foerster {
82*ffeec8baSJoachim Foerster 	switch (curve) {
83*ffeec8baSJoachim Foerster 	case TEE_ECC_CURVE_NIST_P256:
84*ffeec8baSJoachim Foerster 		*bits = 256;
85*ffeec8baSJoachim Foerster 		*bytes = 32;
86*ffeec8baSJoachim Foerster 		break;
87*ffeec8baSJoachim Foerster 	case TEE_ECC_CURVE_NIST_P384:
88*ffeec8baSJoachim Foerster 		*bits = 384;
89*ffeec8baSJoachim Foerster 		*bytes = 48;
90*ffeec8baSJoachim Foerster 		break;
91*ffeec8baSJoachim Foerster 	case TEE_ECC_CURVE_NIST_P521:
92*ffeec8baSJoachim Foerster 		*bits = 521;
93*ffeec8baSJoachim Foerster 		*bytes = 66;
94*ffeec8baSJoachim Foerster 		break;
95*ffeec8baSJoachim Foerster 	default:
96*ffeec8baSJoachim Foerster 		return TEE_ERROR_NOT_SUPPORTED;
97*ffeec8baSJoachim Foerster 	}
98*ffeec8baSJoachim Foerster 
99*ffeec8baSJoachim Foerster 	return TEE_SUCCESS;
100*ffeec8baSJoachim Foerster }
101*ffeec8baSJoachim Foerster 
102*ffeec8baSJoachim Foerster static void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len)
103*ffeec8baSJoachim Foerster {
104*ffeec8baSJoachim Foerster 	size_t i = 0;
105*ffeec8baSJoachim Foerster 
106*ffeec8baSJoachim Foerster 	for (i = 0; i < len; i++)
107*ffeec8baSJoachim Foerster 		to[i] = from[len - 1 - i];
108*ffeec8baSJoachim Foerster }
109*ffeec8baSJoachim Foerster 
110*ffeec8baSJoachim Foerster static void crypto_bignum_bn2bin_eswap(uint32_t curve,
111*ffeec8baSJoachim Foerster 				       struct bignum *from, uint8_t *to)
112*ffeec8baSJoachim Foerster {
113*ffeec8baSJoachim Foerster 	uint8_t pad[66] = { 0 };
114*ffeec8baSJoachim Foerster 	size_t len = crypto_bignum_num_bytes(from);
115*ffeec8baSJoachim Foerster 	size_t bytes = 0;
116*ffeec8baSJoachim Foerster 	size_t bits = 0;
117*ffeec8baSJoachim Foerster 
118*ffeec8baSJoachim Foerster 	if (ecc_get_key_size(curve, &bytes, &bits))
119*ffeec8baSJoachim Foerster 		panic();
120*ffeec8baSJoachim Foerster 
121*ffeec8baSJoachim Foerster 	crypto_bignum_bn2bin(from, pad + bytes - len);
122*ffeec8baSJoachim Foerster 	memcpy_swp(to, pad, bytes);
123*ffeec8baSJoachim Foerster }
124*ffeec8baSJoachim Foerster 
125*ffeec8baSJoachim Foerster static TEE_Result ecc_prepare_msg(uint32_t algo, const uint8_t *msg,
126*ffeec8baSJoachim Foerster 				  size_t msg_len, struct versal_mbox_mem *p)
127*ffeec8baSJoachim Foerster {
128*ffeec8baSJoachim Foerster 	uint8_t swp[TEE_SHA512_HASH_SIZE + 2] = { 0 };
129*ffeec8baSJoachim Foerster 	size_t len = 0;
130*ffeec8baSJoachim Foerster 
131*ffeec8baSJoachim Foerster 	if (msg_len > TEE_SHA512_HASH_SIZE + 2)
132*ffeec8baSJoachim Foerster 		return TEE_ERROR_BAD_PARAMETERS;
133*ffeec8baSJoachim Foerster 
134*ffeec8baSJoachim Foerster 	if (algo == TEE_ALG_ECDSA_SHA256)
135*ffeec8baSJoachim Foerster 		len = TEE_SHA256_HASH_SIZE;
136*ffeec8baSJoachim Foerster 	else if (algo == TEE_ALG_ECDSA_SHA384)
137*ffeec8baSJoachim Foerster 		len = TEE_SHA384_HASH_SIZE;
138*ffeec8baSJoachim Foerster 	else if (algo == TEE_ALG_ECDSA_SHA512)
139*ffeec8baSJoachim Foerster 		len = TEE_SHA512_HASH_SIZE + 2;
140*ffeec8baSJoachim Foerster 	else
141*ffeec8baSJoachim Foerster 		return TEE_ERROR_NOT_SUPPORTED;
142*ffeec8baSJoachim Foerster 
143*ffeec8baSJoachim Foerster 	/* Swap the hash/message and pad if necessary */
144*ffeec8baSJoachim Foerster 	memcpy_swp(swp, msg, msg_len);
145*ffeec8baSJoachim Foerster 	return versal_mbox_alloc(len, swp, p);
146*ffeec8baSJoachim Foerster }
147*ffeec8baSJoachim Foerster 
148*ffeec8baSJoachim Foerster TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key,
149*ffeec8baSJoachim Foerster 			     const uint8_t *msg, size_t msg_len,
150*ffeec8baSJoachim Foerster 			     const uint8_t *sig, size_t sig_len)
151*ffeec8baSJoachim Foerster {
152*ffeec8baSJoachim Foerster 	TEE_Result ret = TEE_SUCCESS;
153*ffeec8baSJoachim Foerster 	struct versal_ecc_verify_param *cmd = NULL;
154*ffeec8baSJoachim Foerster 	struct versal_cmd_args arg = { };
155*ffeec8baSJoachim Foerster 	struct versal_mbox_mem x = { };
156*ffeec8baSJoachim Foerster 	struct versal_mbox_mem s = { };
157*ffeec8baSJoachim Foerster 	struct versal_mbox_mem p = { };
158*ffeec8baSJoachim Foerster 	struct versal_mbox_mem cmd_buf = { };
159*ffeec8baSJoachim Foerster 	uint32_t err = 0;
160*ffeec8baSJoachim Foerster 	size_t bytes = 0;
161*ffeec8baSJoachim Foerster 	size_t bits = 0;
162*ffeec8baSJoachim Foerster 
163*ffeec8baSJoachim Foerster 	if (sig_len % 2)
164*ffeec8baSJoachim Foerster 		return TEE_ERROR_SIGNATURE_INVALID;
165*ffeec8baSJoachim Foerster 
166*ffeec8baSJoachim Foerster 	ret = ecc_get_key_size(key->curve, &bytes, &bits);
167*ffeec8baSJoachim Foerster 	if (ret)
168*ffeec8baSJoachim Foerster 		return ret;
169*ffeec8baSJoachim Foerster 
170*ffeec8baSJoachim Foerster 	ret = ecc_prepare_msg(algo, msg, msg_len, &p);
171*ffeec8baSJoachim Foerster 	if (ret)
172*ffeec8baSJoachim Foerster 		return ret;
173*ffeec8baSJoachim Foerster 
174*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(bytes * 2, NULL, &x);
175*ffeec8baSJoachim Foerster 	if (ret)
176*ffeec8baSJoachim Foerster 		goto out;
177*ffeec8baSJoachim Foerster 
178*ffeec8baSJoachim Foerster 	crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf);
179*ffeec8baSJoachim Foerster 	crypto_bignum_bn2bin_eswap(key->curve, key->y,
180*ffeec8baSJoachim Foerster 				   (uint8_t *)x.buf + bytes);
181*ffeec8baSJoachim Foerster 	/* Validate the public key for the curve */
182*ffeec8baSJoachim Foerster 	arg.data[0] = key->curve;
183*ffeec8baSJoachim Foerster 	arg.dlen = 1;
184*ffeec8baSJoachim Foerster 	arg.ibuf[0].mem = x;
185*ffeec8baSJoachim Foerster 	if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY,
186*ffeec8baSJoachim Foerster 				  &arg, &err)) {
187*ffeec8baSJoachim Foerster 		EMSG("Versal ECC: %s", versal_ecc_error(err));
188*ffeec8baSJoachim Foerster 		ret = TEE_ERROR_GENERIC;
189*ffeec8baSJoachim Foerster 		goto out;
190*ffeec8baSJoachim Foerster 	}
191*ffeec8baSJoachim Foerster 	memset(&arg, 0, sizeof(arg));
192*ffeec8baSJoachim Foerster 
193*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(sig_len, NULL, &s);
194*ffeec8baSJoachim Foerster 	if (ret)
195*ffeec8baSJoachim Foerster 		goto out;
196*ffeec8baSJoachim Foerster 
197*ffeec8baSJoachim Foerster 	/* Swap the {R,S} components */
198*ffeec8baSJoachim Foerster 	memcpy_swp(s.buf, sig, sig_len / 2);
199*ffeec8baSJoachim Foerster 	memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2,
200*ffeec8baSJoachim Foerster 		   sig_len / 2);
201*ffeec8baSJoachim Foerster 
202*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
203*ffeec8baSJoachim Foerster 	if (ret)
204*ffeec8baSJoachim Foerster 		goto out;
205*ffeec8baSJoachim Foerster 
206*ffeec8baSJoachim Foerster 	cmd = cmd_buf.buf;
207*ffeec8baSJoachim Foerster 	cmd->signature_addr = virt_to_phys(s.buf);
208*ffeec8baSJoachim Foerster 	cmd->pub_key_addr = virt_to_phys(x.buf);
209*ffeec8baSJoachim Foerster 	cmd->hash_addr = virt_to_phys(p.buf);
210*ffeec8baSJoachim Foerster 	cmd->hash_len = p.len;
211*ffeec8baSJoachim Foerster 	cmd->curve = key->curve;
212*ffeec8baSJoachim Foerster 
213*ffeec8baSJoachim Foerster 	arg.ibuf[0].mem = cmd_buf;
214*ffeec8baSJoachim Foerster 	arg.ibuf[1].mem = p;
215*ffeec8baSJoachim Foerster 	arg.ibuf[1].only_cache = true;
216*ffeec8baSJoachim Foerster 	arg.ibuf[2].mem = x;
217*ffeec8baSJoachim Foerster 	arg.ibuf[3].mem = s;
218*ffeec8baSJoachim Foerster 
219*ffeec8baSJoachim Foerster 	if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) {
220*ffeec8baSJoachim Foerster 		EMSG("Versal ECC: %s", versal_ecc_error(err));
221*ffeec8baSJoachim Foerster 		ret = TEE_ERROR_GENERIC;
222*ffeec8baSJoachim Foerster 	}
223*ffeec8baSJoachim Foerster 
224*ffeec8baSJoachim Foerster out:
225*ffeec8baSJoachim Foerster 	versal_mbox_free(&cmd_buf);
226*ffeec8baSJoachim Foerster 	versal_mbox_free(&s);
227*ffeec8baSJoachim Foerster 	versal_mbox_free(&x);
228*ffeec8baSJoachim Foerster 	versal_mbox_free(&p);
229*ffeec8baSJoachim Foerster 
230*ffeec8baSJoachim Foerster 	return ret;
231*ffeec8baSJoachim Foerster }
232*ffeec8baSJoachim Foerster 
233*ffeec8baSJoachim Foerster TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key,
234*ffeec8baSJoachim Foerster 			   const uint8_t *msg, size_t msg_len,
235*ffeec8baSJoachim Foerster 			   uint8_t *sig, size_t *sig_len)
236*ffeec8baSJoachim Foerster {
237*ffeec8baSJoachim Foerster 	struct versal_ecc_sign_param *cmd = NULL;
238*ffeec8baSJoachim Foerster 	struct versal_mbox_mem cmd_buf = { };
239*ffeec8baSJoachim Foerster 	struct ecc_keypair ephemeral = { };
240*ffeec8baSJoachim Foerster 	struct versal_cmd_args arg = { };
241*ffeec8baSJoachim Foerster 	struct versal_mbox_mem p = { };
242*ffeec8baSJoachim Foerster 	struct versal_mbox_mem k = { };
243*ffeec8baSJoachim Foerster 	struct versal_mbox_mem d = { };
244*ffeec8baSJoachim Foerster 	struct versal_mbox_mem s = { };
245*ffeec8baSJoachim Foerster 	TEE_Result ret = TEE_SUCCESS;
246*ffeec8baSJoachim Foerster 	uint32_t err = 0;
247*ffeec8baSJoachim Foerster 	size_t bytes = 0;
248*ffeec8baSJoachim Foerster 	size_t bits = 0;
249*ffeec8baSJoachim Foerster 
250*ffeec8baSJoachim Foerster 	ret = ecc_get_key_size(key->curve, &bytes, &bits);
251*ffeec8baSJoachim Foerster 	if (ret)
252*ffeec8baSJoachim Foerster 		return ret;
253*ffeec8baSJoachim Foerster 
254*ffeec8baSJoachim Foerster 	/* Hash and update the length */
255*ffeec8baSJoachim Foerster 	ret = ecc_prepare_msg(algo, msg, msg_len, &p);
256*ffeec8baSJoachim Foerster 	if (ret)
257*ffeec8baSJoachim Foerster 		return ret;
258*ffeec8baSJoachim Foerster 
259*ffeec8baSJoachim Foerster 	/* Ephemeral private key */
260*ffeec8baSJoachim Foerster 	ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral,
261*ffeec8baSJoachim Foerster 					      TEE_TYPE_ECDSA_KEYPAIR, bits);
262*ffeec8baSJoachim Foerster 	if (ret) {
263*ffeec8baSJoachim Foerster 		EMSG("Versal, can't allocate the ephemeral key");
264*ffeec8baSJoachim Foerster 		goto out;
265*ffeec8baSJoachim Foerster 	}
266*ffeec8baSJoachim Foerster 
267*ffeec8baSJoachim Foerster 	ephemeral.curve = key->curve;
268*ffeec8baSJoachim Foerster 	ret = crypto_acipher_gen_ecc_key(&ephemeral, bits);
269*ffeec8baSJoachim Foerster 	if (ret) {
270*ffeec8baSJoachim Foerster 		EMSG("Versal, can't generate the ephemeral key");
271*ffeec8baSJoachim Foerster 		goto out;
272*ffeec8baSJoachim Foerster 	}
273*ffeec8baSJoachim Foerster 
274*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(bytes, NULL, &k);
275*ffeec8baSJoachim Foerster 	if (ret)
276*ffeec8baSJoachim Foerster 		goto out;
277*ffeec8baSJoachim Foerster 
278*ffeec8baSJoachim Foerster 	crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf);
279*ffeec8baSJoachim Foerster 
280*ffeec8baSJoachim Foerster 	/* Private key*/
281*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(bytes, NULL, &d);
282*ffeec8baSJoachim Foerster 	if (ret)
283*ffeec8baSJoachim Foerster 		goto out;
284*ffeec8baSJoachim Foerster 
285*ffeec8baSJoachim Foerster 	crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf);
286*ffeec8baSJoachim Foerster 
287*ffeec8baSJoachim Foerster 	/* Signature */
288*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(*sig_len, NULL, &s);
289*ffeec8baSJoachim Foerster 	if (ret)
290*ffeec8baSJoachim Foerster 		goto out;
291*ffeec8baSJoachim Foerster 
292*ffeec8baSJoachim Foerster 	/* IPI command */
293*ffeec8baSJoachim Foerster 	ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
294*ffeec8baSJoachim Foerster 	if (ret)
295*ffeec8baSJoachim Foerster 		goto out;
296*ffeec8baSJoachim Foerster 
297*ffeec8baSJoachim Foerster 	cmd = cmd_buf.buf;
298*ffeec8baSJoachim Foerster 	cmd->priv_key_addr = virt_to_phys(d.buf);
299*ffeec8baSJoachim Foerster 	cmd->epriv_key_addr = virt_to_phys(k.buf);
300*ffeec8baSJoachim Foerster 	cmd->hash_addr = virt_to_phys(p.buf);
301*ffeec8baSJoachim Foerster 	cmd->hash_len = p.len;
302*ffeec8baSJoachim Foerster 	cmd->curve = key->curve;
303*ffeec8baSJoachim Foerster 
304*ffeec8baSJoachim Foerster 	arg.ibuf[0].mem = cmd_buf;
305*ffeec8baSJoachim Foerster 	arg.ibuf[1].mem = s;
306*ffeec8baSJoachim Foerster 	arg.ibuf[2].mem = k;
307*ffeec8baSJoachim Foerster 	arg.ibuf[3].mem = d;
308*ffeec8baSJoachim Foerster 	arg.ibuf[4].mem = p;
309*ffeec8baSJoachim Foerster 
310*ffeec8baSJoachim Foerster 	if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) {
311*ffeec8baSJoachim Foerster 		EMSG("Versal ECC: %s", versal_ecc_error(err));
312*ffeec8baSJoachim Foerster 		ret = TEE_ERROR_GENERIC;
313*ffeec8baSJoachim Foerster 		goto out;
314*ffeec8baSJoachim Foerster 	}
315*ffeec8baSJoachim Foerster 
316*ffeec8baSJoachim Foerster 	*sig_len = 2 * bytes;
317*ffeec8baSJoachim Foerster 
318*ffeec8baSJoachim Foerster 	/* Swap the {R,S} components */
319*ffeec8baSJoachim Foerster 	memcpy_swp(sig, s.buf, *sig_len / 2);
320*ffeec8baSJoachim Foerster 	memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2,
321*ffeec8baSJoachim Foerster 		   *sig_len / 2);
322*ffeec8baSJoachim Foerster 
323*ffeec8baSJoachim Foerster out:
324*ffeec8baSJoachim Foerster 	versal_mbox_free(&cmd_buf);
325*ffeec8baSJoachim Foerster 	versal_mbox_free(&s);
326*ffeec8baSJoachim Foerster 	versal_mbox_free(&d);
327*ffeec8baSJoachim Foerster 	versal_mbox_free(&k);
328*ffeec8baSJoachim Foerster 
329*ffeec8baSJoachim Foerster 	crypto_bignum_free(&ephemeral.d);
330*ffeec8baSJoachim Foerster 	crypto_bignum_free(&ephemeral.x);
331*ffeec8baSJoachim Foerster 	crypto_bignum_free(&ephemeral.y);
332*ffeec8baSJoachim Foerster 
333*ffeec8baSJoachim Foerster 	versal_mbox_free(&p);
334*ffeec8baSJoachim Foerster 
335*ffeec8baSJoachim Foerster 	return ret;
336*ffeec8baSJoachim Foerster }
337*ffeec8baSJoachim Foerster 
338*ffeec8baSJoachim Foerster TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s __maybe_unused)
339*ffeec8baSJoachim Foerster {
340*ffeec8baSJoachim Foerster 	return TEE_ERROR_NOT_SUPPORTED;
341*ffeec8baSJoachim Foerster }
342*ffeec8baSJoachim Foerster 
343*ffeec8baSJoachim Foerster TEE_Result versal_ecc_kat_test(void)
344*ffeec8baSJoachim Foerster {
345*ffeec8baSJoachim Foerster 	struct versal_cmd_args arg = { };
346*ffeec8baSJoachim Foerster 	uint32_t err = 0;
347*ffeec8baSJoachim Foerster 
348*ffeec8baSJoachim Foerster 	arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_GEN_KAT;
349*ffeec8baSJoachim Foerster 	arg.data[arg.dlen++] = XSECURE_ECC_PRIME;
350*ffeec8baSJoachim Foerster 	if (versal_crypto_request(VERSAL_KAT, &arg, &err)) {
351*ffeec8baSJoachim Foerster 		EMSG("Versal KAT ECC SignGen: %s", versal_ecc_error(err));
352*ffeec8baSJoachim Foerster 		return TEE_ERROR_GENERIC;
353*ffeec8baSJoachim Foerster 	}
354*ffeec8baSJoachim Foerster 
355*ffeec8baSJoachim Foerster 	/* Clean previous request */
356*ffeec8baSJoachim Foerster 	arg.dlen = 0;
357*ffeec8baSJoachim Foerster 
358*ffeec8baSJoachim Foerster 	arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_VERIFY_KAT;
359*ffeec8baSJoachim Foerster 	arg.data[arg.dlen++] = XSECURE_ECC_PRIME;
360*ffeec8baSJoachim Foerster 	if (versal_crypto_request(VERSAL_KAT, &arg, &err)) {
361*ffeec8baSJoachim Foerster 		EMSG("Versal KAT ECC SignVerify: %s", versal_ecc_error(err));
362*ffeec8baSJoachim Foerster 		return TEE_ERROR_GENERIC;
363*ffeec8baSJoachim Foerster 	}
364*ffeec8baSJoachim Foerster 
365*ffeec8baSJoachim Foerster 	return TEE_SUCCESS;
366*ffeec8baSJoachim Foerster }
367*ffeec8baSJoachim Foerster 
368*ffeec8baSJoachim Foerster TEE_Result versal_ecc_hw_init(void)
369*ffeec8baSJoachim Foerster {
370*ffeec8baSJoachim Foerster 	return TEE_SUCCESS;
371*ffeec8baSJoachim Foerster }
372