xref: /optee_os/core/lib/libtomcrypt/rsa.c (revision c2c27539cc9e2bf92ffc047699a1eba6917ebe66)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014-2019, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <crypto/crypto_impl.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <tee_api_types.h>
11 #include <tee_api_defines_extensions.h>
12 #include <tee/tee_cryp_utl.h>
13 #include <trace.h>
14 #include <utee_defines.h>
15 
16 #include "acipher_helpers.h"
17 
18 
19 /*
20  * Compute the LibTomCrypt "hashindex" given a TEE Algorithm "algo"
21  * Return
22  * - TEE_SUCCESS in case of success,
23  * - TEE_ERROR_BAD_PARAMETERS in case algo is not a valid algo
24  * - TEE_ERROR_NOT_SUPPORTED in case algo is not supported by LTC
25  * Return -1 in case of error
26  */
27 static TEE_Result tee_algo_to_ltc_hashindex(uint32_t algo, int *ltc_hashindex)
28 {
29 	switch (algo) {
30 #if defined(_CFG_CORE_LTC_SHA1)
31 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
32 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
33 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
34 		*ltc_hashindex = find_hash("sha1");
35 		break;
36 #endif
37 #if defined(_CFG_CORE_LTC_MD5)
38 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
39 		*ltc_hashindex = find_hash("md5");
40 		break;
41 #endif
42 #if defined(_CFG_CORE_LTC_SHA224)
43 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
44 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
45 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
46 		*ltc_hashindex = find_hash("sha224");
47 		break;
48 #endif
49 #if defined(_CFG_CORE_LTC_SHA256)
50 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
51 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
52 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
53 		*ltc_hashindex = find_hash("sha256");
54 		break;
55 #endif
56 #if defined(_CFG_CORE_LTC_SHA384)
57 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
58 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
59 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
60 		*ltc_hashindex = find_hash("sha384");
61 		break;
62 #endif
63 #if defined(_CFG_CORE_LTC_SHA512)
64 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
65 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
66 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
67 		*ltc_hashindex = find_hash("sha512");
68 		break;
69 #endif
70 	case TEE_ALG_RSASSA_PKCS1_V1_5:
71 	case TEE_ALG_RSAES_PKCS1_V1_5:
72 		/* invalid one. but it should not be used anyway */
73 		*ltc_hashindex = -1;
74 		return TEE_SUCCESS;
75 
76 	default:
77 		return TEE_ERROR_BAD_PARAMETERS;
78 	}
79 
80 	if (*ltc_hashindex < 0)
81 		return TEE_ERROR_NOT_SUPPORTED;
82 	else
83 		return TEE_SUCCESS;
84 }
85 
86 TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s,
87 					    size_t key_size_bits __unused)
88 __weak __alias("sw_crypto_acipher_alloc_rsa_keypair");
89 
90 TEE_Result sw_crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s,
91 					       size_t key_size_bits __unused)
92 {
93 	memset(s, 0, sizeof(*s));
94 	if (!bn_alloc_max(&s->e))
95 		return TEE_ERROR_OUT_OF_MEMORY;
96 	if (!bn_alloc_max(&s->d))
97 		goto err;
98 	if (!bn_alloc_max(&s->n))
99 		goto err;
100 	if (!bn_alloc_max(&s->p))
101 		goto err;
102 	if (!bn_alloc_max(&s->q))
103 		goto err;
104 	if (!bn_alloc_max(&s->qp))
105 		goto err;
106 	if (!bn_alloc_max(&s->dp))
107 		goto err;
108 	if (!bn_alloc_max(&s->dq))
109 		goto err;
110 
111 	return TEE_SUCCESS;
112 err:
113 	crypto_acipher_free_rsa_keypair(s);
114 	return TEE_ERROR_OUT_OF_MEMORY;
115 }
116 
117 
118 TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s,
119 					       size_t key_size_bits __unused)
120 __weak __alias("sw_crypto_acipher_alloc_rsa_public_key");
121 
122 TEE_Result sw_crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s,
123 						  size_t key_size_bits __unused)
124 {
125 	memset(s, 0, sizeof(*s));
126 	if (!bn_alloc_max(&s->e))
127 		return TEE_ERROR_OUT_OF_MEMORY;
128 	if (!bn_alloc_max(&s->n))
129 		goto err;
130 	return TEE_SUCCESS;
131 err:
132 	crypto_bignum_free(s->e);
133 	return TEE_ERROR_OUT_OF_MEMORY;
134 }
135 
136 
137 void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s)
138 __weak __alias("sw_crypto_acipher_free_rsa_public_key");
139 
140 void sw_crypto_acipher_free_rsa_public_key(struct rsa_public_key *s)
141 {
142 	if (!s)
143 		return;
144 	crypto_bignum_free(s->n);
145 	crypto_bignum_free(s->e);
146 }
147 
148 
149 void crypto_acipher_free_rsa_keypair(struct rsa_keypair *s)
150 __weak __alias("sw_crypto_acipher_free_rsa_keypair");
151 
152 void sw_crypto_acipher_free_rsa_keypair(struct rsa_keypair *s)
153 {
154 	if (!s)
155 		return;
156 	crypto_bignum_free(s->e);
157 	crypto_bignum_free(s->d);
158 	crypto_bignum_free(s->n);
159 	crypto_bignum_free(s->p);
160 	crypto_bignum_free(s->q);
161 	crypto_bignum_free(s->qp);
162 	crypto_bignum_free(s->dp);
163 	crypto_bignum_free(s->dq);
164 }
165 
166 TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key,
167 				      size_t key_size)
168 __weak __alias("sw_crypto_acipher_gen_rsa_key");
169 
170 TEE_Result sw_crypto_acipher_gen_rsa_key(struct rsa_keypair *key,
171 					 size_t key_size)
172 {
173 	TEE_Result res;
174 	rsa_key ltc_tmp_key;
175 	int ltc_res;
176 
177 	/* Generate a temporary RSA key */
178 	ltc_res = rsa_make_key_bn_e(NULL, find_prng("prng_crypto"),
179 				    key_size / 8, key->e, &ltc_tmp_key);
180 	if (ltc_res != CRYPT_OK) {
181 		res = TEE_ERROR_BAD_PARAMETERS;
182 	} else if ((size_t)mp_count_bits(ltc_tmp_key.N) != key_size) {
183 		rsa_free(&ltc_tmp_key);
184 		res = TEE_ERROR_BAD_PARAMETERS;
185 	} else {
186 		/* Copy the key */
187 		ltc_mp.copy(ltc_tmp_key.d,  key->d);
188 		ltc_mp.copy(ltc_tmp_key.N,  key->n);
189 		ltc_mp.copy(ltc_tmp_key.p,  key->p);
190 		ltc_mp.copy(ltc_tmp_key.q,  key->q);
191 		ltc_mp.copy(ltc_tmp_key.qP, key->qp);
192 		ltc_mp.copy(ltc_tmp_key.dP, key->dp);
193 		ltc_mp.copy(ltc_tmp_key.dQ, key->dq);
194 
195 		/* Free the temporary key */
196 		rsa_free(&ltc_tmp_key);
197 		res = TEE_SUCCESS;
198 	}
199 
200 	return res;
201 }
202 
203 static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src,
204 			   size_t src_len, uint8_t *dst, size_t *dst_len)
205 {
206 	TEE_Result res = TEE_SUCCESS;
207 	uint8_t *buf = NULL;
208 	unsigned long blen, offset;
209 	int ltc_res;
210 
211 	/*
212 	 * Use a temporary buffer since we don't know exactly how large the
213 	 * required size of the out buffer without doing a partial decrypt.
214 	 * We know the upper bound though.
215 	 */
216 	blen = _CFG_CORE_LTC_BIGNUM_MAX_BITS / sizeof(uint8_t);
217 	buf = malloc(blen);
218 	if (!buf) {
219 		res = TEE_ERROR_OUT_OF_MEMORY;
220 		goto out;
221 	}
222 
223 	ltc_res = rsa_exptmod(src, src_len, buf, &blen, ltc_key->type,
224 			      ltc_key);
225 	switch (ltc_res) {
226 	case CRYPT_PK_NOT_PRIVATE:
227 	case CRYPT_PK_INVALID_TYPE:
228 	case CRYPT_PK_INVALID_SIZE:
229 	case CRYPT_INVALID_PACKET:
230 		EMSG("rsa_exptmod() returned %d", ltc_res);
231 		res = TEE_ERROR_BAD_PARAMETERS;
232 		goto out;
233 	case CRYPT_OK:
234 		break;
235 	default:
236 		/* This will result in a panic */
237 		EMSG("rsa_exptmod() returned %d", ltc_res);
238 		res = TEE_ERROR_GENERIC;
239 		goto out;
240 	}
241 
242 	/* Remove the zero-padding (leave one zero if buff is all zeroes) */
243 	offset = 0;
244 	while ((offset < blen - 1) && (buf[offset] == 0))
245 		offset++;
246 
247 	if (*dst_len < blen - offset) {
248 		*dst_len = blen - offset;
249 		res = TEE_ERROR_SHORT_BUFFER;
250 		goto out;
251 	}
252 
253 	res = TEE_SUCCESS;
254 	*dst_len = blen - offset;
255 	memcpy(dst, (char *)buf + offset, *dst_len);
256 
257 out:
258 	if (buf)
259 		free(buf);
260 
261 	return res;
262 }
263 
264 TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
265 					   const uint8_t *src,
266 					   size_t src_len, uint8_t *dst,
267 					   size_t *dst_len)
268 __weak __alias("sw_crypto_acipher_rsanopad_encrypt");
269 
270 TEE_Result sw_crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
271 					      const uint8_t *src,
272 					      size_t src_len, uint8_t *dst,
273 					      size_t *dst_len)
274 {
275 	TEE_Result res;
276 	rsa_key ltc_key = { 0, };
277 
278 	ltc_key.type = PK_PUBLIC;
279 	ltc_key.e = key->e;
280 	ltc_key.N = key->n;
281 
282 	res = rsadorep(&ltc_key, src, src_len, dst, dst_len);
283 	return res;
284 }
285 
286 TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
287 					   const uint8_t *src,
288 					   size_t src_len, uint8_t *dst,
289 					   size_t *dst_len)
290 __weak __alias("sw_crypto_acipher_rsanopad_decrypt");
291 
292 TEE_Result sw_crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
293 					      const uint8_t *src,
294 					      size_t src_len, uint8_t *dst,
295 					      size_t *dst_len)
296 {
297 	TEE_Result res;
298 	rsa_key ltc_key = { 0, };
299 
300 	ltc_key.type = PK_PRIVATE;
301 	ltc_key.e = key->e;
302 	ltc_key.N = key->n;
303 	ltc_key.d = key->d;
304 	if (key->p && crypto_bignum_num_bytes(key->p)) {
305 		ltc_key.p = key->p;
306 		ltc_key.q = key->q;
307 		ltc_key.qP = key->qp;
308 		ltc_key.dP = key->dp;
309 		ltc_key.dQ = key->dq;
310 	}
311 
312 	res = rsadorep(&ltc_key, src, src_len, dst, dst_len);
313 	return res;
314 }
315 
316 TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo,
317 					struct rsa_keypair *key,
318 					const uint8_t *label,
319 					size_t label_len, const uint8_t *src,
320 					size_t src_len, uint8_t *dst,
321 					size_t *dst_len)
322 __weak __alias("sw_crypto_acipher_rsaes_decrypt");
323 
324 TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,
325 					   struct rsa_keypair *key,
326 					   const uint8_t *label,
327 					   size_t label_len, const uint8_t *src,
328 					   size_t src_len, uint8_t *dst,
329 					   size_t *dst_len)
330 {
331 	TEE_Result res = TEE_SUCCESS;
332 	void *buf = NULL;
333 	unsigned long blen;
334 	int ltc_hashindex, ltc_res, ltc_stat, ltc_rsa_algo;
335 	size_t mod_size;
336 	rsa_key ltc_key = { 0, };
337 
338 	ltc_key.type = PK_PRIVATE;
339 	ltc_key.e = key->e;
340 	ltc_key.d = key->d;
341 	ltc_key.N = key->n;
342 	if (key->p && crypto_bignum_num_bytes(key->p)) {
343 		ltc_key.p = key->p;
344 		ltc_key.q = key->q;
345 		ltc_key.qP = key->qp;
346 		ltc_key.dP = key->dp;
347 		ltc_key.dQ = key->dq;
348 	}
349 
350 	/* Get the algorithm */
351 	res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
352 	if (res != TEE_SUCCESS) {
353 		EMSG("tee_algo_to_ltc_hashindex() returned %d", (int)res);
354 		goto out;
355 	}
356 
357 	/*
358 	 * Use a temporary buffer since we don't know exactly how large
359 	 * the required size of the out buffer without doing a partial
360 	 * decrypt. We know the upper bound though.
361 	 */
362 	if (algo == TEE_ALG_RSAES_PKCS1_V1_5) {
363 		mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
364 		blen = mod_size - 11;
365 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
366 	} else {
367 		/* Decoded message is always shorter than encrypted message */
368 		blen = src_len;
369 		ltc_rsa_algo = LTC_PKCS_1_OAEP;
370 	}
371 
372 	buf = malloc(blen);
373 	if (!buf) {
374 		res = TEE_ERROR_OUT_OF_MEMORY;
375 		goto out;
376 	}
377 
378 	ltc_res = rsa_decrypt_key_ex(src, src_len, buf, &blen,
379 				     ((label_len == 0) ? 0 : label), label_len,
380 				     ltc_hashindex, ltc_rsa_algo, &ltc_stat,
381 				     &ltc_key);
382 	switch (ltc_res) {
383 	case CRYPT_PK_INVALID_PADDING:
384 	case CRYPT_INVALID_PACKET:
385 	case CRYPT_PK_INVALID_SIZE:
386 		EMSG("rsa_decrypt_key_ex() returned %d", ltc_res);
387 		res = TEE_ERROR_BAD_PARAMETERS;
388 		goto out;
389 	case CRYPT_OK:
390 		break;
391 	default:
392 		/* This will result in a panic */
393 		EMSG("rsa_decrypt_key_ex() returned %d", ltc_res);
394 		res = TEE_ERROR_GENERIC;
395 		goto out;
396 	}
397 	if (ltc_stat != 1) {
398 		/* This will result in a panic */
399 		EMSG("rsa_decrypt_key_ex() returned %d and %d",
400 		     ltc_res, ltc_stat);
401 		res = TEE_ERROR_GENERIC;
402 		goto out;
403 	}
404 
405 	if (*dst_len < blen) {
406 		*dst_len = blen;
407 		res = TEE_ERROR_SHORT_BUFFER;
408 		goto out;
409 	}
410 
411 	res = TEE_SUCCESS;
412 	*dst_len = blen;
413 	memcpy(dst, buf, blen);
414 
415 out:
416 	if (buf)
417 		free(buf);
418 
419 	return res;
420 }
421 
422 TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
423 					struct rsa_public_key *key,
424 					const uint8_t *label,
425 					size_t label_len, const uint8_t *src,
426 					size_t src_len, uint8_t *dst,
427 					size_t *dst_len)
428 __weak __alias("sw_crypto_acipher_rsaes_encrypt");
429 
430 TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo,
431 					   struct rsa_public_key *key,
432 					   const uint8_t *label,
433 					   size_t label_len, const uint8_t *src,
434 					   size_t src_len, uint8_t *dst,
435 					   size_t *dst_len)
436 {
437 	TEE_Result res;
438 	uint32_t mod_size;
439 	int ltc_hashindex, ltc_res, ltc_rsa_algo;
440 	rsa_key ltc_key = {
441 		.type = PK_PUBLIC,
442 		.e = key->e,
443 		.N = key->n
444 	};
445 
446 	mod_size =  ltc_mp.unsigned_size((void *)(ltc_key.N));
447 	if (*dst_len < mod_size) {
448 		*dst_len = mod_size;
449 		res = TEE_ERROR_SHORT_BUFFER;
450 		goto out;
451 	}
452 	*dst_len = mod_size;
453 
454 	/* Get the algorithm */
455 	res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
456 	if (res != TEE_SUCCESS)
457 		goto out;
458 
459 	if (algo == TEE_ALG_RSAES_PKCS1_V1_5)
460 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
461 	else
462 		ltc_rsa_algo = LTC_PKCS_1_OAEP;
463 
464 	ltc_res = rsa_encrypt_key_ex(src, src_len, dst,
465 				     (unsigned long *)(dst_len), label,
466 				     label_len, NULL, find_prng("prng_crypto"),
467 				     ltc_hashindex, ltc_rsa_algo, &ltc_key);
468 	switch (ltc_res) {
469 	case CRYPT_PK_INVALID_PADDING:
470 	case CRYPT_INVALID_PACKET:
471 	case CRYPT_PK_INVALID_SIZE:
472 		EMSG("rsa_encrypt_key_ex() returned %d", ltc_res);
473 		res = TEE_ERROR_BAD_PARAMETERS;
474 		goto out;
475 	case CRYPT_OK:
476 		break;
477 	default:
478 		/* This will result in a panic */
479 		res = TEE_ERROR_GENERIC;
480 		goto out;
481 	}
482 	res = TEE_SUCCESS;
483 
484 out:
485 	return res;
486 }
487 
488 TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key,
489 				      int salt_len, const uint8_t *msg,
490 				      size_t msg_len, uint8_t *sig,
491 				      size_t *sig_len)
492 __weak __alias("sw_crypto_acipher_rsassa_sign");
493 
494 TEE_Result sw_crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key,
495 					 int salt_len, const uint8_t *msg,
496 					 size_t msg_len, uint8_t *sig,
497 					 size_t *sig_len)
498 {
499 	TEE_Result res;
500 	size_t hash_size, mod_size;
501 	int ltc_res, ltc_rsa_algo, ltc_hashindex;
502 	unsigned long ltc_sig_len;
503 	rsa_key ltc_key = { 0, };
504 
505 	ltc_key.type = PK_PRIVATE;
506 	ltc_key.e = key->e;
507 	ltc_key.N = key->n;
508 	ltc_key.d = key->d;
509 	if (key->p && crypto_bignum_num_bytes(key->p)) {
510 		ltc_key.p = key->p;
511 		ltc_key.q = key->q;
512 		ltc_key.qP = key->qp;
513 		ltc_key.dP = key->dp;
514 		ltc_key.dQ = key->dq;
515 	}
516 
517 	switch (algo) {
518 	case TEE_ALG_RSASSA_PKCS1_V1_5:
519 		ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1;
520 		break;
521 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
522 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
523 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
524 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
525 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
526 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
527 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
528 		break;
529 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
530 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
531 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
532 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
533 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
534 		ltc_rsa_algo = LTC_PKCS_1_PSS;
535 		break;
536 	default:
537 		res = TEE_ERROR_BAD_PARAMETERS;
538 		goto err;
539 	}
540 
541 	if (ltc_rsa_algo != LTC_PKCS_1_V1_5_NA1) {
542 		ltc_res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
543 		if (ltc_res != CRYPT_OK) {
544 			res = TEE_ERROR_BAD_PARAMETERS;
545 			goto err;
546 		}
547 
548 		res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
549 					      &hash_size);
550 		if (res != TEE_SUCCESS)
551 			goto err;
552 
553 		if (msg_len != hash_size) {
554 			res = TEE_ERROR_BAD_PARAMETERS;
555 			goto err;
556 		}
557 	}
558 
559 	mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
560 
561 	if (*sig_len < mod_size) {
562 		*sig_len = mod_size;
563 		res = TEE_ERROR_SHORT_BUFFER;
564 		goto err;
565 	}
566 
567 	ltc_sig_len = mod_size;
568 
569 	ltc_res = rsa_sign_hash_ex(msg, msg_len, sig, &ltc_sig_len,
570 				   ltc_rsa_algo, NULL, find_prng("prng_crypto"),
571 				   ltc_hashindex, salt_len, &ltc_key);
572 
573 	*sig_len = ltc_sig_len;
574 
575 	if (ltc_res != CRYPT_OK) {
576 		res = TEE_ERROR_BAD_PARAMETERS;
577 		goto err;
578 	}
579 	res = TEE_SUCCESS;
580 
581 err:
582 	return res;
583 }
584 
585 TEE_Result crypto_acipher_rsassa_verify(uint32_t algo,
586 					struct rsa_public_key *key,
587 					int salt_len, const uint8_t *msg,
588 					size_t msg_len, const uint8_t *sig,
589 					size_t sig_len)
590 __weak __alias("sw_crypto_acipher_rsassa_verify");
591 
592 TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo,
593 					   struct rsa_public_key *key,
594 					   int salt_len, const uint8_t *msg,
595 					   size_t msg_len, const uint8_t *sig,
596 					   size_t sig_len)
597 {
598 	TEE_Result res;
599 	uint32_t bigint_size;
600 	size_t hash_size;
601 	int stat, ltc_hashindex, ltc_res, ltc_rsa_algo;
602 	rsa_key ltc_key = {
603 		.type = PK_PUBLIC,
604 		.e = key->e,
605 		.N = key->n
606 	};
607 
608 	if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
609 		res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
610 					      &hash_size);
611 		if (res != TEE_SUCCESS)
612 			goto err;
613 
614 		if (msg_len != hash_size) {
615 			res = TEE_ERROR_BAD_PARAMETERS;
616 			goto err;
617 		}
618 	}
619 
620 	bigint_size = ltc_mp.unsigned_size(ltc_key.N);
621 	if (sig_len < bigint_size) {
622 		res = TEE_ERROR_SIGNATURE_INVALID;
623 		goto err;
624 	}
625 
626 	/* Get the algorithm */
627 	if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
628 		res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
629 		if (res != TEE_SUCCESS)
630 			goto err;
631 	}
632 
633 	switch (algo) {
634 	case TEE_ALG_RSASSA_PKCS1_V1_5:
635 		ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1;
636 		break;
637 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
638 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
639 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
640 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
641 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
642 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
643 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
644 		break;
645 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
646 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
647 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
648 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
649 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
650 		ltc_rsa_algo = LTC_PKCS_1_PSS;
651 		break;
652 	default:
653 		res = TEE_ERROR_BAD_PARAMETERS;
654 		goto err;
655 	}
656 
657 	ltc_res = rsa_verify_hash_ex(sig, sig_len, msg, msg_len, ltc_rsa_algo,
658 				     ltc_hashindex, salt_len, &stat, &ltc_key);
659 	res = convert_ltc_verify_status(ltc_res, stat);
660 err:
661 	return res;
662 }
663