1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2018-2021 NXP
4  *
5  * Crypto ECC interface implementation to enable HW driver.
6  */
7 #include <crypto/crypto_impl.h>
8 #include <drvcrypt.h>
9 #include <drvcrypt_acipher.h>
10 #include <utee_defines.h>
11 
12 /*
13  * Returns the key size in bytes for the given ECC curve
14  *
15  * @curve   ECC Curve ID
16  */
get_ecc_key_size_bytes(uint32_t curve)17 static size_t get_ecc_key_size_bytes(uint32_t curve)
18 {
19 	switch (curve) {
20 	case TEE_ECC_CURVE_NIST_P192:
21 		return 24;
22 
23 	case TEE_ECC_CURVE_NIST_P224:
24 		return 28;
25 
26 	case TEE_ECC_CURVE_NIST_P256:
27 	case TEE_ECC_CURVE_SM2:
28 		return 32;
29 
30 	case TEE_ECC_CURVE_NIST_P384:
31 		return 48;
32 
33 	case TEE_ECC_CURVE_NIST_P521:
34 		return 66;
35 
36 	default:
37 		return 0;
38 	}
39 }
40 
41 /*
42  * Returns the key size in bits for the given ECC curve
43  *
44  * @curve   ECC Curve ID
45  */
46 
get_ecc_key_size_bits(uint32_t curve)47 static size_t get_ecc_key_size_bits(uint32_t curve)
48 {
49 	switch (curve) {
50 	case TEE_ECC_CURVE_NIST_P192:
51 	case TEE_ECC_CURVE_NIST_P224:
52 	case TEE_ECC_CURVE_NIST_P256:
53 	case TEE_ECC_CURVE_NIST_P384:
54 	case TEE_ECC_CURVE_SM2:
55 		return get_ecc_key_size_bytes(curve) * 8;
56 
57 	case TEE_ECC_CURVE_NIST_P521:
58 		return 521;
59 
60 	default:
61 		return 0;
62 	}
63 }
64 
65 /*
66  * Verify if the cryptographic algorithm @algo is valid for
67  * the ECC curve
68  *
69  * @curve   ECC curve
70  * @algo    Cryptographic algorithm
71  */
algo_is_valid(uint32_t curve,uint32_t algo)72 static bool algo_is_valid(uint32_t curve, uint32_t algo)
73 {
74 	unsigned int algo_op = TEE_ALG_GET_CLASS(algo);
75 	unsigned int algo_id = TEE_ALG_GET_MAIN_ALG(algo);
76 	unsigned int algo_curve = TEE_ALG_GET_DIGEST_HASH(algo);
77 
78 	/* Check first the algo operation and id */
79 	if ((algo_op == TEE_OPERATION_ASYMMETRIC_SIGNATURE &&
80 	     algo_id == TEE_MAIN_ALGO_ECDSA) ||
81 	    (algo_op == TEE_OPERATION_KEY_DERIVATION &&
82 	     algo_id == TEE_MAIN_ALGO_ECDH)) {
83 		if (curve == algo_curve) {
84 			CRYPTO_TRACE("Algo 0x%" PRIx32 " curve 0x%" PRIx32
85 				     " is valid", algo, curve);
86 			return true;
87 		}
88 	}
89 
90 	if (algo_op == TEE_OPERATION_ASYMMETRIC_SIGNATURE &&
91 	    algo_id == TEE_MAIN_ALGO_SM2_DSA_SM3) {
92 		if (curve == TEE_ECC_CURVE_SM2)
93 			return true;
94 	}
95 
96 	CRYPTO_TRACE("Algo 0x%" PRIx32 " curve 0x%" PRIx32 " is not valid",
97 		     algo, curve);
98 
99 	return false;
100 }
101 
102 /*
103  * Free an ECC public key
104  *
105  * @key   Public Key
106  */
ecc_free_public_key(struct ecc_public_key * key)107 static void ecc_free_public_key(struct ecc_public_key *key)
108 {
109 	struct drvcrypt_ecc *ecc = NULL;
110 
111 	if (key) {
112 		ecc = drvcrypt_get_ops(CRYPTO_ECC);
113 		if (ecc) {
114 			CRYPTO_TRACE("ECC Public Key free");
115 			ecc->free_publickey(key);
116 		}
117 	}
118 }
119 
120 /*
121  * Generates an ECC keypair
122  *
123  * @key        Keypair
124  * @size_bits  Key size in bits
125  */
ecc_generate_keypair(struct ecc_keypair * key,size_t size_bits __maybe_unused)126 static TEE_Result ecc_generate_keypair(struct ecc_keypair *key,
127 				       size_t size_bits __maybe_unused)
128 {
129 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
130 	struct drvcrypt_ecc *ecc = NULL;
131 	size_t key_size_bits = 0;
132 
133 	/* Check input parameters */
134 	if (!key) {
135 		CRYPTO_TRACE("Parameters error key is NULL");
136 		return TEE_ERROR_BAD_PARAMETERS;
137 	}
138 
139 	key_size_bits = get_ecc_key_size_bits(key->curve);
140 
141 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
142 	if (ecc)
143 		ret = ecc->gen_keypair(key, key_size_bits);
144 
145 	CRYPTO_TRACE("ECC Keypair (%zu bits) generate ret = 0x%" PRIx32,
146 		     key_size_bits, ret);
147 
148 	return ret;
149 }
150 
151 /*
152  * Sign the message with the ECC Key given by the Keypair
153  *
154  * @algo       ECC algorithm
155  * @key        ECC Keypair
156  * @msg        Message to sign
157  * @msg_len    Length of the message (bytes)
158  * @sig        Signature
159  * @sig_len    [in/out] Length of the signature (bytes)
160  */
ecc_sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)161 static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key,
162 			   const uint8_t *msg, size_t msg_len, uint8_t *sig,
163 			   size_t *sig_len)
164 {
165 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
166 	struct drvcrypt_ecc *ecc = NULL;
167 	struct drvcrypt_sign_data sdata = { };
168 	size_t size_bytes = 0;
169 
170 	/* Verify first the input parameters */
171 	if (!key || !msg || !sig_len) {
172 		CRYPTO_TRACE("Input parameters reference error");
173 		return ret;
174 	}
175 
176 	if (!algo_is_valid(key->curve, algo))
177 		return ret;
178 
179 	size_bytes = get_ecc_key_size_bytes(key->curve);
180 	if (!size_bytes)
181 		return TEE_ERROR_BAD_PARAMETERS;
182 
183 	/* Verify the signature length function of the key size */
184 	if (*sig_len < 2 * size_bytes) {
185 		CRYPTO_TRACE("Length (%zu) too short expected %zu bytes",
186 			     *sig_len, 2 * size_bytes);
187 		*sig_len = 2 * size_bytes;
188 		return TEE_ERROR_SHORT_BUFFER;
189 	}
190 
191 	if (!sig) {
192 		CRYPTO_TRACE("Parameter \"sig\" reference error");
193 		return TEE_ERROR_BAD_PARAMETERS;
194 	}
195 
196 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
197 	if (ecc) {
198 		/*
199 		 * Prepare the Signature structure data
200 		 */
201 		sdata.algo = algo;
202 		sdata.key = key;
203 		sdata.size_sec = size_bytes;
204 		sdata.message.data = (uint8_t *)msg;
205 		sdata.message.length = msg_len;
206 		sdata.signature.data = (uint8_t *)sig;
207 		sdata.signature.length = *sig_len;
208 
209 		ret = ecc->sign(&sdata);
210 
211 		/* Set the signature length */
212 		*sig_len = sdata.signature.length;
213 	} else {
214 		ret = TEE_ERROR_NOT_IMPLEMENTED;
215 	}
216 
217 	CRYPTO_TRACE("Sign algo (0x%" PRIx32 ") returned 0x%" PRIx32, algo,
218 		     ret);
219 
220 	return ret;
221 }
222 
223 /*
224  * Verify if signature is signed with the given public key.
225  *
226  * @algo       ECC algorithm
227  * @key        ECC Public key
228  * @msg        Message to sign
229  * @msg_len    Length of the message (bytes)
230  * @sig        Signature
231  * @sig_len    Length of the signature (bytes)
232  */
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)233 static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key,
234 			     const uint8_t *msg, size_t msg_len,
235 			     const uint8_t *sig, size_t sig_len)
236 {
237 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
238 	struct drvcrypt_ecc *ecc = NULL;
239 	struct drvcrypt_sign_data sdata = { };
240 	size_t size_bytes = 0;
241 
242 	/* Verify first the input parameters */
243 	if (!key || !msg || !sig) {
244 		CRYPTO_TRACE("Input parameters reference error");
245 		return ret;
246 	}
247 
248 	if (!algo_is_valid(key->curve, algo))
249 		return ret;
250 
251 	size_bytes = get_ecc_key_size_bytes(key->curve);
252 	if (!size_bytes)
253 		return TEE_ERROR_BAD_PARAMETERS;
254 
255 	/* Verify the signature length against key size */
256 	if (sig_len != 2 * size_bytes) {
257 		CRYPTO_TRACE("Length (%zu) is invalid expected %zu bytes",
258 			     sig_len, 2 * size_bytes);
259 		return TEE_ERROR_SIGNATURE_INVALID;
260 	}
261 
262 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
263 	if (ecc) {
264 		sdata.algo = algo;
265 		sdata.key = key;
266 		sdata.size_sec = size_bytes;
267 		sdata.message.data = (uint8_t *)msg;
268 		sdata.message.length = msg_len;
269 		sdata.signature.data = (uint8_t *)sig;
270 		sdata.signature.length = sig_len;
271 
272 		ret = ecc->verify(&sdata);
273 	} else {
274 		ret = TEE_ERROR_NOT_IMPLEMENTED;
275 	}
276 
277 	CRYPTO_TRACE("Verify algo (0x%" PRIx32 ") returned 0x%" PRIx32, algo,
278 		     ret);
279 
280 	return ret;
281 }
282 
283 /*
284  * Compute the shared secret data from ECC Private key and Public Key
285  *
286  * @private_key  ECC Private key
287  * @public_key   ECC Public key
288  * @secret       Secret
289  * @secret_len   Length of the secret (bytes)
290  */
ecc_shared_secret(struct ecc_keypair * private_key,struct ecc_public_key * public_key,void * secret,unsigned long * secret_len)291 static TEE_Result ecc_shared_secret(struct ecc_keypair *private_key,
292 				    struct ecc_public_key *public_key,
293 				    void *secret, unsigned long *secret_len)
294 {
295 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
296 	struct drvcrypt_ecc *ecc = NULL;
297 	struct drvcrypt_secret_data sdata = { };
298 	size_t size_bytes = 0;
299 
300 	/* Verify first the input parameters */
301 	if (!private_key || !public_key || !secret_len) {
302 		CRYPTO_TRACE("Input parameters reference error");
303 		return ret;
304 	}
305 
306 	if (private_key->curve != public_key->curve) {
307 		CRYPTO_TRACE("Private Key curve (%d) != Public Key curve (%d)",
308 			     private_key->curve, public_key->curve);
309 		return ret;
310 	}
311 
312 	size_bytes = get_ecc_key_size_bytes(public_key->curve);
313 	if (!size_bytes)
314 		return ret;
315 
316 	if (*secret_len < size_bytes) {
317 		*secret_len = size_bytes;
318 		return TEE_ERROR_SHORT_BUFFER;
319 	}
320 
321 	if (!secret) {
322 		CRYPTO_TRACE("Parameter \"secret\" reference error");
323 		return ret;
324 	}
325 
326 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
327 	if (ecc) {
328 		/*
329 		 * Prepare the Secret structure data
330 		 */
331 		sdata.key_priv = private_key;
332 		sdata.key_pub = public_key;
333 		sdata.size_sec = size_bytes;
334 		sdata.secret.data = secret;
335 		sdata.secret.length = *secret_len;
336 
337 		ret = ecc->shared_secret(&sdata);
338 
339 		/* Set the secret length */
340 		*secret_len = sdata.secret.length;
341 	} else {
342 		ret = TEE_ERROR_NOT_IMPLEMENTED;
343 	}
344 
345 	CRYPTO_TRACE("Shared Secret returned 0x%" PRIx32, ret);
346 
347 	return ret;
348 }
349 
ecc_sm2_encrypt(struct ecc_public_key * key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)350 static TEE_Result ecc_sm2_encrypt(struct ecc_public_key *key,
351 				  const uint8_t *src, size_t src_len,
352 				  uint8_t *dst, size_t *dst_len)
353 {
354 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
355 	struct drvcrypt_ecc_ed cdata = { };
356 	struct drvcrypt_ecc *ecc = NULL;
357 	size_t ciphertext_len = 0;
358 	size_t size_bytes = 0;
359 
360 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
361 
362 	size_bytes = get_ecc_key_size_bytes(key->curve);
363 	if (!size_bytes) {
364 		CRYPTO_TRACE("Curve 0x%08"PRIx32" not supported", key->curve);
365 		return TEE_ERROR_BAD_PARAMETERS;
366 	}
367 
368 	/* Uncompressed form indicator */
369 	dst[0] = 0x04;
370 
371 	ciphertext_len = 2 * size_bytes + src_len + TEE_SM3_HASH_SIZE;
372 
373 	cdata.key = key;
374 	cdata.size_sec = size_bytes;
375 	cdata.plaintext.data = (uint8_t *)src;
376 	cdata.plaintext.length = src_len;
377 	cdata.ciphertext.data = dst + 1;
378 	cdata.ciphertext.length = ciphertext_len;
379 
380 	ret = ecc->encrypt(&cdata);
381 
382 	if (!ret || ret == TEE_ERROR_SHORT_BUFFER)
383 		*dst_len = cdata.ciphertext.length + 1;
384 
385 	return ret;
386 }
387 
ecc_encrypt(struct ecc_public_key * key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)388 static TEE_Result ecc_encrypt(struct ecc_public_key *key,
389 			      const uint8_t *src, size_t src_len,
390 			      uint8_t *dst, size_t *dst_len)
391 {
392 	struct drvcrypt_ecc *ecc = NULL;
393 
394 	if (!key || !src || !dst) {
395 		CRYPTO_TRACE("Input parameters reference error");
396 		return TEE_ERROR_BAD_PARAMETERS;
397 	}
398 
399 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
400 	if (!ecc || !ecc->encrypt)
401 		return TEE_ERROR_NOT_IMPLEMENTED;
402 
403 	switch (key->curve) {
404 	case TEE_ECC_CURVE_SM2:
405 		return ecc_sm2_encrypt(key, src, src_len, dst, dst_len);
406 	default:
407 		return TEE_ERROR_NOT_IMPLEMENTED;
408 	}
409 }
410 
ecc_sm2_decrypt(struct ecc_keypair * key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)411 static TEE_Result ecc_sm2_decrypt(struct ecc_keypair *key,
412 				  const uint8_t *src, size_t src_len,
413 				  uint8_t *dst, size_t *dst_len)
414 {
415 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
416 	struct drvcrypt_ecc_ed cdata = { };
417 	struct drvcrypt_ecc *ecc = NULL;
418 	uint8_t *ciphertext = NULL;
419 	size_t ciphertext_len = 0;
420 	size_t size_bytes = 0;
421 	size_t plaintext_len = 0;
422 	/* Point Compression */
423 	uint8_t pc = 0;
424 
425 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
426 
427 	size_bytes = get_ecc_key_size_bytes(key->curve);
428 	if (!size_bytes) {
429 		CRYPTO_TRACE("Curve 0x%08"PRIx32" not supported", key->curve);
430 		return TEE_ERROR_BAD_PARAMETERS;
431 	}
432 
433 	pc = src[0];
434 	switch (pc) {
435 	case 0x02:
436 	case 0x03:
437 		/* Compressed form */
438 		return TEE_ERROR_NOT_SUPPORTED;
439 	case 0x04:
440 		/* Uncompressed form */
441 		ciphertext = (uint8_t *)src + 1;
442 		ciphertext_len = src_len - 1;
443 		break;
444 	case 0x06:
445 	case 0x07:
446 		/* Hybrid form */
447 		return TEE_ERROR_NOT_SUPPORTED;
448 	default:
449 		return TEE_ERROR_BAD_PARAMETERS;
450 	}
451 
452 	if (SUB_OVERFLOW(ciphertext_len, 2 * size_bytes + TEE_SM3_HASH_SIZE,
453 			 &plaintext_len))
454 		return TEE_ERROR_BAD_PARAMETERS;
455 
456 	cdata.key = key;
457 	cdata.size_sec = size_bytes;
458 	cdata.ciphertext.data = ciphertext;
459 	cdata.ciphertext.length = ciphertext_len;
460 	cdata.plaintext.data = dst;
461 	cdata.plaintext.length = plaintext_len;
462 
463 	ret = ecc->decrypt(&cdata);
464 
465 	/* Set the plaintext length */
466 	if (!ret || ret == TEE_ERROR_SHORT_BUFFER)
467 		*dst_len = cdata.plaintext.length;
468 
469 	return ret;
470 }
471 
ecc_decrypt(struct ecc_keypair * key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)472 static TEE_Result ecc_decrypt(struct ecc_keypair *key,
473 			      const uint8_t *src, size_t src_len,
474 			      uint8_t *dst, size_t *dst_len)
475 {
476 	struct drvcrypt_ecc *ecc = NULL;
477 
478 	if (!key || !src || !dst) {
479 		CRYPTO_TRACE("Input parameters reference error");
480 		return TEE_ERROR_BAD_PARAMETERS;
481 	}
482 
483 	ecc = drvcrypt_get_ops(CRYPTO_ECC);
484 	if (!ecc || !ecc->decrypt)
485 		return TEE_ERROR_NOT_IMPLEMENTED;
486 
487 	switch (key->curve) {
488 	case TEE_ECC_CURVE_SM2:
489 		return ecc_sm2_decrypt(key, src, src_len, dst, dst_len);
490 	default:
491 		return TEE_ERROR_NOT_IMPLEMENTED;
492 	}
493 }
494 
495 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = {
496 	.generate = ecc_generate_keypair,
497 	.sign = ecc_sign,
498 	.shared_secret = ecc_shared_secret,
499 	.decrypt = ecc_decrypt,
500 };
501 
drvcrypt_asym_alloc_ecc_keypair(struct ecc_keypair * key,uint32_t type,size_t size_bits)502 TEE_Result drvcrypt_asym_alloc_ecc_keypair(struct ecc_keypair *key,
503 					   uint32_t type, size_t size_bits)
504 {
505 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
506 	struct drvcrypt_ecc *ecc = NULL;
507 
508 	if (!key || !size_bits) {
509 		CRYPTO_TRACE("Bad parameters (key @%p)(size %zu bits)", key,
510 			     size_bits);
511 		return TEE_ERROR_BAD_PARAMETERS;
512 	}
513 
514 	switch (type) {
515 	case TEE_TYPE_ECDSA_KEYPAIR:
516 	case TEE_TYPE_ECDH_KEYPAIR:
517 	case TEE_TYPE_SM2_PKE_KEYPAIR:
518 	case TEE_TYPE_SM2_DSA_KEYPAIR:
519 		ecc = drvcrypt_get_ops(CRYPTO_ECC);
520 		break;
521 	default:
522 		break;
523 	}
524 
525 	if (ecc)
526 		ret = ecc->alloc_keypair(key, type, size_bits);
527 
528 	if (!ret) {
529 		key->ops = &ecc_keypair_ops;
530 
531 		/* ecc->alloc_keypair() can not get type to set curve */
532 		switch (type) {
533 		case TEE_TYPE_SM2_PKE_KEYPAIR:
534 		case TEE_TYPE_SM2_DSA_KEYPAIR:
535 			key->curve = TEE_ECC_CURVE_SM2;
536 			break;
537 		default:
538 			break;
539 		}
540 	}
541 
542 	CRYPTO_TRACE("ECC Keypair (%zu bits) alloc ret = 0x%" PRIx32, size_bits,
543 		     ret);
544 	return ret;
545 }
546 
547 static const struct crypto_ecc_public_ops ecc_public_key_ops = {
548 	.free = ecc_free_public_key,
549 	.verify = ecc_verify,
550 	.encrypt = ecc_encrypt,
551 };
552 
drvcrypt_asym_alloc_ecc_public_key(struct ecc_public_key * key,uint32_t type,size_t size_bits)553 TEE_Result drvcrypt_asym_alloc_ecc_public_key(struct ecc_public_key *key,
554 					      uint32_t type, size_t size_bits)
555 {
556 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
557 	struct drvcrypt_ecc *ecc = NULL;
558 
559 	if (!key || !size_bits) {
560 		CRYPTO_TRACE("Bad parameters (key @%p)(size %zu bits)", key,
561 			     size_bits);
562 		return TEE_ERROR_BAD_PARAMETERS;
563 	}
564 
565 	switch (type) {
566 	case TEE_TYPE_ECDSA_PUBLIC_KEY:
567 	case TEE_TYPE_ECDH_PUBLIC_KEY:
568 	case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
569 	case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
570 		ecc = drvcrypt_get_ops(CRYPTO_ECC);
571 		break;
572 	default:
573 		break;
574 	}
575 
576 	if (ecc)
577 		ret = ecc->alloc_publickey(key, type, size_bits);
578 
579 	if (!ret) {
580 		key->ops = &ecc_public_key_ops;
581 
582 		/* ecc->alloc_publickey() can not get type to set curve */
583 		switch (type) {
584 		case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
585 		case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
586 			key->curve = TEE_ECC_CURVE_SM2;
587 			break;
588 		default:
589 			break;
590 		}
591 	}
592 
593 	CRYPTO_TRACE("ECC Public Key (%zu bits) alloc ret = 0x%" PRIx32,
594 		     size_bits, ret);
595 	return ret;
596 }
597