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