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 <drvcrypt.h>
8 #include <drvcrypt_acipher.h>
9 #include <crypto/crypto_impl.h>
10 #include <initcall.h>
11 #include <ipi.h>
12 #include <kernel/panic.h>
13 #include <mm/core_memprot.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_ECDSA_KAT_NIST_P384	0
21 #define XSECURE_ECDSA_KAT_NIST_P521	2
22 
23 /* Software based ECDSA operations */
24 static const struct crypto_ecc_keypair_ops *keypair_ops;
25 static const struct crypto_ecc_public_ops *pub_ops;
26 
27 enum versal_ecc_err {
28 	KAT_KEY_NOTVALID_ERROR = 0xC0,
29 	KAT_FAILED_ERROR,
30 	NON_SUPPORTED_CURVE,
31 	KEY_ZERO,
32 	KEY_WRONG_ORDER,
33 	KEY_NOT_ON_CURVE,
34 	BAD_SIGN,
35 	GEN_SIGN_INCORRECT_HASH_LEN,
36 	VER_SIGN_INCORRECT_HASH_LEN,
37 	GEN_SIGN_BAD_RAND_NUM,
38 	GEN_KEY_ERR,
39 	INVALID_PARAM,
40 	VER_SIGN_R_ZERO,
41 	VER_SIGN_S_ZERO,
42 	VER_SIGN_R_ORDER_ERROR,
43 	VER_SIGN_S_ORDER_ERROR,
44 	KAT_INVLD_CRV_ERROR,
45 };
46 
47 #define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) }
48 
versal_ecc_error(uint8_t err)49 static const char *versal_ecc_error(uint8_t err)
50 {
51 	struct {
52 		enum versal_ecc_err error;
53 		const char *name;
54 	} elist[] = {
55 		VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR),
56 		VERSAL_ECC_ERROR(KAT_FAILED_ERROR),
57 		VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE),
58 		VERSAL_ECC_ERROR(KEY_ZERO),
59 		VERSAL_ECC_ERROR(KEY_WRONG_ORDER),
60 		VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE),
61 		VERSAL_ECC_ERROR(BAD_SIGN),
62 		VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN),
63 		VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN),
64 		VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM),
65 		VERSAL_ECC_ERROR(GEN_KEY_ERR),
66 		VERSAL_ECC_ERROR(INVALID_PARAM),
67 		VERSAL_ECC_ERROR(VER_SIGN_R_ZERO),
68 		VERSAL_ECC_ERROR(VER_SIGN_S_ZERO),
69 		VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR),
70 		VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR),
71 		VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR),
72 	};
73 
74 	if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) {
75 		if (elist[err - KAT_KEY_NOTVALID_ERROR].name)
76 			return elist[err - KAT_KEY_NOTVALID_ERROR].name;
77 
78 		return "Invalid";
79 	}
80 
81 	return "Unknown";
82 }
83 
ecc_get_key_size(uint32_t curve,size_t * bytes,size_t * bits)84 static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits)
85 {
86 	switch (curve) {
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 
crypto_bignum_bn2bin_eswap(uint32_t curve,struct bignum * from,uint8_t * to)102 static void crypto_bignum_bn2bin_eswap(uint32_t curve,
103 				       struct bignum *from, uint8_t *to)
104 {
105 	uint8_t pad[66] = { 0 };
106 	uint8_t tmp = 0;
107 	size_t i = 0;
108 	size_t j = 0;
109 	size_t len = crypto_bignum_num_bytes(from);
110 	size_t bytes = 0;
111 	size_t bits = 0;
112 
113 	if (ecc_get_key_size(curve, &bytes, &bits))
114 		panic();
115 
116 	crypto_bignum_bn2bin(from, pad + bytes - len);
117 	for (i = 0, j = bytes - 1; i < j; i++, j--) {
118 		tmp = pad[i];
119 		pad[i] = pad[j];
120 		pad[j] = tmp;
121 	}
122 	memcpy(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 buf[TEE_SHA512_HASH_SIZE + 2] = { 0 };
129 	TEE_Result ret = TEE_SUCCESS;
130 	size_t len = 0;
131 
132 	switch (algo) {
133 	case TEE_ALG_ECDSA_P384:
134 		len = TEE_SHA384_HASH_SIZE;
135 
136 		if (msg_len == len)
137 			return versal_mbox_alloc(len, msg, p);
138 
139 		ret = tee_hash_createdigest(TEE_ALG_SHA384, msg, msg_len,
140 					    buf, sizeof(buf));
141 		if (ret)
142 			return ret;
143 		break;
144 	case TEE_ALG_ECDSA_P521:
145 		len = TEE_SHA512_HASH_SIZE + 2;
146 
147 		if (msg_len == len)
148 			return versal_mbox_alloc(len, msg, p);
149 
150 		ret = tee_hash_createdigest(TEE_ALG_SHA512, msg, msg_len, buf,
151 					    sizeof(buf));
152 		if (ret)
153 			return ret;
154 		break;
155 	default:
156 		return TEE_ERROR_GENERIC;
157 	}
158 
159 	/* provide the hash */
160 	versal_mbox_alloc(len, buf, p);
161 
162 	return TEE_SUCCESS;
163 }
164 
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)165 static TEE_Result verify(uint32_t algo, struct ecc_public_key *key,
166 			 const uint8_t *msg, size_t msg_len,
167 			 const uint8_t *sig, size_t sig_len)
168 {
169 	TEE_Result ret = TEE_SUCCESS;
170 	struct versal_ecc_verify_param *cmd = NULL;
171 	struct versal_cmd_args arg = { };
172 	struct versal_mbox_mem x = { };
173 	struct versal_mbox_mem s = { };
174 	struct versal_mbox_mem p = { };
175 	struct versal_mbox_mem cmd_buf = { };
176 	uint32_t err = 0;
177 	size_t bytes = 0;
178 	size_t bits = 0;
179 
180 	ret = ecc_get_key_size(key->curve, &bytes, &bits);
181 	if (ret != TEE_SUCCESS) {
182 		if (ret != TEE_ERROR_NOT_SUPPORTED)
183 			return ret;
184 
185 		/* Fallback to software */
186 		return pub_ops->verify(algo, key, msg, msg_len, sig, sig_len);
187 	}
188 
189 	ret = ecc_prepare_msg(algo, msg, msg_len, &p);
190 	if (ret)
191 		return ret;
192 
193 	versal_mbox_alloc(bytes * 2, NULL, &x);
194 	crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf);
195 	crypto_bignum_bn2bin_eswap(key->curve, key->y,
196 				   (uint8_t *)x.buf + bytes);
197 	/* Validate the public key for the curve */
198 	arg.data[0] = key->curve;
199 	arg.dlen = 1;
200 	arg.ibuf[0].mem = x;
201 	if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY,
202 				  &arg, &err)) {
203 		EMSG("Versal ECC: %s", versal_ecc_error(err));
204 		ret = TEE_ERROR_GENERIC;
205 		goto out;
206 	}
207 	memset(&arg, 0, sizeof(arg));
208 
209 	/* Verify the message with the validated key */
210 	versal_mbox_alloc(sig_len, sig, &s);
211 	versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
212 
213 	cmd = cmd_buf.buf;
214 	cmd->signature_addr = virt_to_phys(s.buf);
215 	cmd->pub_key_addr = virt_to_phys(x.buf);
216 	cmd->hash_addr = virt_to_phys(p.buf);
217 	cmd->hash_len = p.len;
218 	cmd->curve = key->curve;
219 
220 	arg.ibuf[0].mem = cmd_buf;
221 	arg.ibuf[1].mem = p;
222 	arg.ibuf[1].only_cache = true;
223 	arg.ibuf[2].mem = x;
224 	arg.ibuf[3].mem = s;
225 
226 	if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) {
227 		EMSG("Versal ECC: %s", versal_ecc_error(err));
228 		ret = TEE_ERROR_GENERIC;
229 	}
230 out:
231 	free(p.buf);
232 	free(x.buf);
233 	free(s.buf);
234 	free(cmd);
235 
236 	return ret;
237 }
238 
sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)239 static TEE_Result sign(uint32_t algo, struct ecc_keypair *key,
240 		       const uint8_t *msg, size_t msg_len,
241 		       uint8_t *sig, size_t *sig_len)
242 {
243 	struct versal_ecc_sign_param *cmd = NULL;
244 	struct versal_mbox_mem cmd_buf = { };
245 	struct ecc_keypair ephemeral = { };
246 	struct versal_cmd_args arg = { };
247 	struct versal_mbox_mem p = { };
248 	struct versal_mbox_mem k = { };
249 	struct versal_mbox_mem d = { };
250 	struct versal_mbox_mem s = { };
251 	TEE_Result ret = TEE_SUCCESS;
252 	uint32_t err = 0;
253 	size_t bytes = 0;
254 	size_t bits = 0;
255 
256 	ret = ecc_get_key_size(key->curve, &bytes, &bits);
257 	if (ret != TEE_SUCCESS) {
258 		if (ret != TEE_ERROR_NOT_SUPPORTED)
259 			return ret;
260 
261 		/* Fallback to software */
262 		return keypair_ops->sign(algo, key, msg, msg_len, sig, sig_len);
263 	}
264 
265 	/* Hash and update the length */
266 	ret = ecc_prepare_msg(algo, msg, msg_len, &p);
267 	if (ret)
268 		return ret;
269 
270 	/* Ephemeral private key */
271 	ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral,
272 					      TEE_TYPE_ECDSA_KEYPAIR, bits);
273 	if (ret) {
274 		EMSG("Versal, can't allocate the ephemeral key");
275 		return ret;
276 	}
277 
278 	ephemeral.curve = key->curve;
279 	ret = crypto_acipher_gen_ecc_key(&ephemeral, bits);
280 	if (ret) {
281 		EMSG("Versal, can't generate the ephemeral key");
282 		return ret;
283 	}
284 
285 	versal_mbox_alloc(bytes, NULL, &k);
286 	crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf);
287 	crypto_bignum_free(ephemeral.d);
288 	crypto_bignum_free(ephemeral.x);
289 	crypto_bignum_free(ephemeral.y);
290 
291 	/* Private key*/
292 	versal_mbox_alloc(bytes, NULL, &d);
293 	crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf);
294 
295 	/* Signature */
296 	versal_mbox_alloc(*sig_len, NULL, &s);
297 
298 	/* IPI command */
299 	versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
300 
301 	cmd = cmd_buf.buf;
302 	cmd->priv_key_addr = virt_to_phys(d.buf);
303 	cmd->epriv_key_addr = virt_to_phys(k.buf);
304 	cmd->hash_addr = virt_to_phys(p.buf);
305 	cmd->hash_len = p.len;
306 	cmd->curve = key->curve;
307 
308 	arg.ibuf[0].mem = cmd_buf;
309 	arg.ibuf[1].mem = s;
310 	arg.ibuf[2].mem = k;
311 	arg.ibuf[3].mem = d;
312 	arg.ibuf[4].mem = p;
313 
314 	if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) {
315 		EMSG("Versal ECC: %s", versal_ecc_error(err));
316 		ret = TEE_ERROR_GENERIC;
317 		goto out;
318 	}
319 
320 	*sig_len = 2 * bytes;
321 	memcpy(sig, s.buf, *sig_len);
322 out:
323 	free(cmd);
324 	free(k.buf);
325 	free(p.buf);
326 	free(s.buf);
327 	free(d.buf);
328 
329 	return ret;
330 }
331 
shared_secret(struct ecc_keypair * private_key,struct ecc_public_key * public_key,void * secret,size_t * secret_len)332 static TEE_Result shared_secret(struct ecc_keypair *private_key,
333 				struct ecc_public_key *public_key,
334 				void *secret, size_t *secret_len)
335 {
336 	return keypair_ops->shared_secret(private_key, public_key,
337 					  secret, secret_len);
338 }
339 
do_shared_secret(struct drvcrypt_secret_data * sdata)340 static TEE_Result do_shared_secret(struct drvcrypt_secret_data *sdata)
341 {
342 	return shared_secret(sdata->key_priv,
343 			     sdata->key_pub,
344 			     sdata->secret.data,
345 			     &sdata->secret.length);
346 }
347 
do_sign(struct drvcrypt_sign_data * sdata)348 static TEE_Result do_sign(struct drvcrypt_sign_data *sdata)
349 {
350 	return sign(sdata->algo,
351 		    sdata->key,
352 		    sdata->message.data,
353 		    sdata->message.length,
354 		    sdata->signature.data,
355 		    &sdata->signature.length);
356 }
357 
do_verify(struct drvcrypt_sign_data * sdata)358 static TEE_Result do_verify(struct drvcrypt_sign_data *sdata)
359 {
360 	return verify(sdata->algo,
361 		      sdata->key,
362 		      sdata->message.data,
363 		      sdata->message.length,
364 		      sdata->signature.data,
365 		      sdata->signature.length);
366 }
367 
do_gen_keypair(struct ecc_keypair * s,size_t size_bits)368 static TEE_Result do_gen_keypair(struct ecc_keypair *s, size_t size_bits)
369 {
370 	/*
371 	 * Versal requires little endian so need to eswap on Versal IP ops.
372 	 * We chose not to do it here because some tests might be using
373 	 * their own keys
374 	 */
375 	return keypair_ops->generate(s, size_bits);
376 }
377 
do_alloc_keypair(struct ecc_keypair * s,size_t size_bits)378 static TEE_Result do_alloc_keypair(struct ecc_keypair *s, size_t size_bits)
379 {
380 	TEE_Result ret = TEE_SUCCESS;
381 
382 	ret = crypto_asym_alloc_ecc_keypair(s, TEE_TYPE_ECDSA_KEYPAIR,
383 					    size_bits);
384 	if (ret)
385 		return TEE_ERROR_NOT_IMPLEMENTED;
386 
387 	s->ops = NULL;
388 
389 	return TEE_SUCCESS;
390 }
391 
do_alloc_publickey(struct ecc_public_key * s,size_t size_bits)392 static TEE_Result do_alloc_publickey(struct ecc_public_key *s, size_t size_bits)
393 {
394 	TEE_Result ret = TEE_SUCCESS;
395 
396 	ret = crypto_asym_alloc_ecc_public_key(s, TEE_TYPE_ECDSA_PUBLIC_KEY,
397 					       size_bits);
398 	if (ret)
399 		return TEE_ERROR_NOT_IMPLEMENTED;
400 
401 	s->ops = NULL;
402 
403 	return TEE_SUCCESS;
404 }
405 
do_free_publickey(struct ecc_public_key * s)406 static void do_free_publickey(struct ecc_public_key *s)
407 {
408 	return pub_ops->free(s);
409 }
410 
411 static struct drvcrypt_ecc driver_ecc = {
412 	.shared_secret = do_shared_secret,
413 	.alloc_publickey = do_alloc_publickey,
414 	.free_publickey = do_free_publickey,
415 	.alloc_keypair = do_alloc_keypair,
416 	.gen_keypair = do_gen_keypair,
417 	.verify = do_verify,
418 	.sign = do_sign,
419 };
420 
ecc_init(void)421 static TEE_Result ecc_init(void)
422 {
423 	struct versal_cmd_args arg = { };
424 	uint32_t err = 0;
425 
426 	arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P384;
427 	if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) {
428 		EMSG("Versal KAG NIST_P384: %s", versal_ecc_error(err));
429 		return TEE_ERROR_GENERIC;
430 	}
431 
432 	/* Clean previous request */
433 	arg.dlen = 0;
434 
435 	arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P521;
436 	if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) {
437 		EMSG("Versal KAG NIST_P521 %s", versal_ecc_error(err));
438 		return TEE_ERROR_GENERIC;
439 	}
440 
441 	keypair_ops = crypto_asym_get_ecc_keypair_ops(TEE_TYPE_ECDSA_KEYPAIR);
442 	if (!keypair_ops)
443 		return TEE_ERROR_GENERIC;
444 
445 	pub_ops = crypto_asym_get_ecc_public_ops(TEE_TYPE_ECDSA_PUBLIC_KEY);
446 	if (!pub_ops)
447 		return TEE_ERROR_GENERIC;
448 
449 	return drvcrypt_register_ecc(&driver_ecc);
450 }
451 
452 driver_init(ecc_init);
453