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