xref: /optee_os/lib/libmbedtls/core/rsa.c (revision 5118efbe82358fd69fda6e0158a30e59f59ba09d)
1f8907bbfSEdison Ai // SPDX-License-Identifier: BSD-2-Clause
2f8907bbfSEdison Ai /*
3f8907bbfSEdison Ai  * Copyright (C) 2018, ARM Limited
4f8907bbfSEdison Ai  * Copyright (C) 2019, Linaro Limited
5f8907bbfSEdison Ai  */
6f8907bbfSEdison Ai 
7f8907bbfSEdison Ai #include <assert.h>
8f8907bbfSEdison Ai #include <crypto/crypto.h>
9f8907bbfSEdison Ai #include <mbedtls/ctr_drbg.h>
10f8907bbfSEdison Ai #include <mbedtls/entropy.h>
11f8907bbfSEdison Ai #include <mbedtls/pk.h>
12f8907bbfSEdison Ai #include <mbedtls/pk_internal.h>
13f8907bbfSEdison Ai #include <stdlib.h>
14f8907bbfSEdison Ai #include <string.h>
15f8907bbfSEdison Ai #include <tee/tee_cryp_utl.h>
16f8907bbfSEdison Ai #include <utee_defines.h>
17f8907bbfSEdison Ai 
18f8907bbfSEdison Ai #include "mbd_rand.h"
19f8907bbfSEdison Ai 
20f8907bbfSEdison Ai static TEE_Result get_tee_result(int lmd_res)
21f8907bbfSEdison Ai {
22f8907bbfSEdison Ai 	switch (lmd_res) {
23f8907bbfSEdison Ai 	case 0:
24f8907bbfSEdison Ai 		return TEE_SUCCESS;
25f8907bbfSEdison Ai 	case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
26f8907bbfSEdison Ai 	case MBEDTLS_ERR_RSA_INVALID_PADDING:
27f8907bbfSEdison Ai 	case MBEDTLS_ERR_PK_TYPE_MISMATCH:
28f8907bbfSEdison Ai 		return TEE_ERROR_BAD_PARAMETERS;
29f8907bbfSEdison Ai 	case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
30f8907bbfSEdison Ai 		return TEE_ERROR_SHORT_BUFFER;
31f8907bbfSEdison Ai 	default:
32f8907bbfSEdison Ai 		return TEE_ERROR_BAD_STATE;
33f8907bbfSEdison Ai 	}
34f8907bbfSEdison Ai }
35f8907bbfSEdison Ai 
36f8907bbfSEdison Ai static uint32_t tee_algo_to_mbedtls_hash_algo(uint32_t algo)
37f8907bbfSEdison Ai {
38f8907bbfSEdison Ai 	switch (algo) {
39f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA1)
40f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
41f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
42f8907bbfSEdison Ai 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
43f8907bbfSEdison Ai 	case TEE_ALG_SHA1:
44f8907bbfSEdison Ai 	case TEE_ALG_DSA_SHA1:
45f8907bbfSEdison Ai 	case TEE_ALG_HMAC_SHA1:
46f8907bbfSEdison Ai 		return MBEDTLS_MD_SHA1;
47f8907bbfSEdison Ai #endif
48f8907bbfSEdison Ai #if defined(CFG_CRYPTO_MD5)
49f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
50f8907bbfSEdison Ai 	case TEE_ALG_MD5:
51f8907bbfSEdison Ai 	case TEE_ALG_HMAC_MD5:
52f8907bbfSEdison Ai 		return MBEDTLS_MD_MD5;
53f8907bbfSEdison Ai #endif
54f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA224)
55f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
56f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
57f8907bbfSEdison Ai 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
58f8907bbfSEdison Ai 	case TEE_ALG_SHA224:
59f8907bbfSEdison Ai 	case TEE_ALG_DSA_SHA224:
60f8907bbfSEdison Ai 	case TEE_ALG_HMAC_SHA224:
61f8907bbfSEdison Ai 		return MBEDTLS_MD_SHA224;
62f8907bbfSEdison Ai #endif
63f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA256)
64f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
65f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
66f8907bbfSEdison Ai 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
67f8907bbfSEdison Ai 	case TEE_ALG_SHA256:
68f8907bbfSEdison Ai 	case TEE_ALG_DSA_SHA256:
69f8907bbfSEdison Ai 	case TEE_ALG_HMAC_SHA256:
70f8907bbfSEdison Ai 		return MBEDTLS_MD_SHA256;
71f8907bbfSEdison Ai #endif
72f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA384)
73f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
74f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
75f8907bbfSEdison Ai 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
76f8907bbfSEdison Ai 	case TEE_ALG_SHA384:
77f8907bbfSEdison Ai 	case TEE_ALG_HMAC_SHA384:
78f8907bbfSEdison Ai 		return MBEDTLS_MD_SHA384;
79f8907bbfSEdison Ai #endif
80f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA512)
81f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
82f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
83f8907bbfSEdison Ai 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
84f8907bbfSEdison Ai 	case TEE_ALG_SHA512:
85f8907bbfSEdison Ai 	case TEE_ALG_HMAC_SHA512:
86f8907bbfSEdison Ai 		return MBEDTLS_MD_SHA512;
87f8907bbfSEdison Ai #endif
88f8907bbfSEdison Ai 	default:
89f8907bbfSEdison Ai 		return MBEDTLS_MD_NONE;
90f8907bbfSEdison Ai 	}
91f8907bbfSEdison Ai }
92f8907bbfSEdison Ai 
93f8907bbfSEdison Ai static void rsa_init_from_key_pair(mbedtls_rsa_context *rsa,
94f8907bbfSEdison Ai 				struct rsa_keypair *key)
95f8907bbfSEdison Ai {
96f8907bbfSEdison Ai 	mbedtls_rsa_init(rsa, 0, 0);
97f8907bbfSEdison Ai 
98f8907bbfSEdison Ai 	rsa->E = *(mbedtls_mpi *)key->e;
99f8907bbfSEdison Ai 	rsa->N = *(mbedtls_mpi *)key->n;
100f8907bbfSEdison Ai 	rsa->D = *(mbedtls_mpi *)key->d;
101f8907bbfSEdison Ai 	if (key->p && crypto_bignum_num_bytes(key->p)) {
102f8907bbfSEdison Ai 		rsa->P = *(mbedtls_mpi *)key->p;
103f8907bbfSEdison Ai 		rsa->Q = *(mbedtls_mpi *)key->q;
104f8907bbfSEdison Ai 		rsa->QP = *(mbedtls_mpi *)key->qp;
105f8907bbfSEdison Ai 		rsa->DP = *(mbedtls_mpi *)key->dp;
106f8907bbfSEdison Ai 		rsa->DQ = *(mbedtls_mpi *)key->dq;
107f8907bbfSEdison Ai 	}
108f8907bbfSEdison Ai 	rsa->len = mbedtls_mpi_size(&rsa->N);
109f8907bbfSEdison Ai }
110f8907bbfSEdison Ai 
111f8907bbfSEdison Ai static void mbd_rsa_free(mbedtls_rsa_context *rsa)
112f8907bbfSEdison Ai {
113f8907bbfSEdison Ai 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
114f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa->E);
115f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa->N);
116f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa->D);
117f8907bbfSEdison Ai 	if (mbedtls_mpi_size(&rsa->P)) {
118f8907bbfSEdison Ai 		mbedtls_mpi_init(&rsa->P);
119f8907bbfSEdison Ai 		mbedtls_mpi_init(&rsa->Q);
120f8907bbfSEdison Ai 		mbedtls_mpi_init(&rsa->QP);
121f8907bbfSEdison Ai 		mbedtls_mpi_init(&rsa->DP);
122f8907bbfSEdison Ai 		mbedtls_mpi_init(&rsa->DQ);
123f8907bbfSEdison Ai 	}
124f8907bbfSEdison Ai 	mbedtls_rsa_free(rsa);
125f8907bbfSEdison Ai }
126f8907bbfSEdison Ai 
127f8907bbfSEdison Ai TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s,
128f8907bbfSEdison Ai 					    size_t key_size_bits)
129f8907bbfSEdison Ai {
130f8907bbfSEdison Ai 	memset(s, 0, sizeof(*s));
131f8907bbfSEdison Ai 	s->e = crypto_bignum_allocate(key_size_bits);
132f8907bbfSEdison Ai 	if (!s->e)
133f8907bbfSEdison Ai 		goto err;
134f8907bbfSEdison Ai 	s->d = crypto_bignum_allocate(key_size_bits);
135f8907bbfSEdison Ai 	if (!s->d)
136f8907bbfSEdison Ai 		goto err;
137f8907bbfSEdison Ai 	s->n = crypto_bignum_allocate(key_size_bits);
138f8907bbfSEdison Ai 	if (!s->n)
139f8907bbfSEdison Ai 		goto err;
140f8907bbfSEdison Ai 	s->p = crypto_bignum_allocate(key_size_bits);
141f8907bbfSEdison Ai 	if (!s->p)
142f8907bbfSEdison Ai 		goto err;
143f8907bbfSEdison Ai 	s->q = crypto_bignum_allocate(key_size_bits);
144f8907bbfSEdison Ai 	if (!s->q)
145f8907bbfSEdison Ai 		goto err;
146f8907bbfSEdison Ai 	s->qp = crypto_bignum_allocate(key_size_bits);
147f8907bbfSEdison Ai 	if (!s->qp)
148f8907bbfSEdison Ai 		goto err;
149f8907bbfSEdison Ai 	s->dp = crypto_bignum_allocate(key_size_bits);
150f8907bbfSEdison Ai 	if (!s->dp)
151f8907bbfSEdison Ai 		goto err;
152f8907bbfSEdison Ai 	s->dq = crypto_bignum_allocate(key_size_bits);
153f8907bbfSEdison Ai 	if (!s->dq)
154f8907bbfSEdison Ai 		goto err;
155f8907bbfSEdison Ai 
156f8907bbfSEdison Ai 	return TEE_SUCCESS;
157f8907bbfSEdison Ai err:
158f8907bbfSEdison Ai 	crypto_bignum_free(s->e);
159f8907bbfSEdison Ai 	crypto_bignum_free(s->d);
160f8907bbfSEdison Ai 	crypto_bignum_free(s->n);
161f8907bbfSEdison Ai 	crypto_bignum_free(s->p);
162f8907bbfSEdison Ai 	crypto_bignum_free(s->q);
163f8907bbfSEdison Ai 	crypto_bignum_free(s->qp);
164f8907bbfSEdison Ai 	crypto_bignum_free(s->dp);
165f8907bbfSEdison Ai 
166f8907bbfSEdison Ai 	return TEE_ERROR_OUT_OF_MEMORY;
167f8907bbfSEdison Ai }
168f8907bbfSEdison Ai 
169f8907bbfSEdison Ai TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s,
170f8907bbfSEdison Ai 					       size_t key_size_bits)
171f8907bbfSEdison Ai {
172f8907bbfSEdison Ai 	memset(s, 0, sizeof(*s));
173f8907bbfSEdison Ai 	s->e = crypto_bignum_allocate(key_size_bits);
174f8907bbfSEdison Ai 	if (!s->e)
175f8907bbfSEdison Ai 		return TEE_ERROR_OUT_OF_MEMORY;
176f8907bbfSEdison Ai 	s->n = crypto_bignum_allocate(key_size_bits);
177f8907bbfSEdison Ai 	if (!s->n)
178f8907bbfSEdison Ai 		goto err;
179f8907bbfSEdison Ai 	return TEE_SUCCESS;
180f8907bbfSEdison Ai err:
181f8907bbfSEdison Ai 	crypto_bignum_free(s->e);
182f8907bbfSEdison Ai 	return TEE_ERROR_OUT_OF_MEMORY;
183f8907bbfSEdison Ai }
184f8907bbfSEdison Ai 
185f8907bbfSEdison Ai void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s)
186f8907bbfSEdison Ai {
187f8907bbfSEdison Ai 	if (!s)
188f8907bbfSEdison Ai 		return;
189f8907bbfSEdison Ai 	crypto_bignum_free(s->n);
190f8907bbfSEdison Ai 	crypto_bignum_free(s->e);
191f8907bbfSEdison Ai }
192f8907bbfSEdison Ai 
193a1d5c81fSElias von Däniken void crypto_acipher_free_rsa_keypair(struct rsa_keypair *s)
194a1d5c81fSElias von Däniken {
195a1d5c81fSElias von Däniken 	if (!s)
196a1d5c81fSElias von Däniken 		return;
197a1d5c81fSElias von Däniken 	crypto_bignum_free(s->e);
198a1d5c81fSElias von Däniken 	crypto_bignum_free(s->d);
199a1d5c81fSElias von Däniken 	crypto_bignum_free(s->n);
200a1d5c81fSElias von Däniken 	crypto_bignum_free(s->p);
201a1d5c81fSElias von Däniken 	crypto_bignum_free(s->q);
202a1d5c81fSElias von Däniken 	crypto_bignum_free(s->qp);
203a1d5c81fSElias von Däniken 	crypto_bignum_free(s->dp);
204*5118efbeSJerome Forissier 	crypto_bignum_free(s->dq);
205a1d5c81fSElias von Däniken }
206a1d5c81fSElias von Däniken 
207f8907bbfSEdison Ai TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key, size_t key_size)
208f8907bbfSEdison Ai {
209f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
210f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
211f8907bbfSEdison Ai 	int lmd_res = 0;
212f8907bbfSEdison Ai 	uint32_t e = 0;
213f8907bbfSEdison Ai 
214f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
215f8907bbfSEdison Ai 	mbedtls_rsa_init(&rsa, 0, 0);
216f8907bbfSEdison Ai 
217f8907bbfSEdison Ai 	/* get the public exponent */
218f8907bbfSEdison Ai 	mbedtls_mpi_write_binary((mbedtls_mpi *)key->e,
219f8907bbfSEdison Ai 				 (unsigned char *)&e, sizeof(uint32_t));
220f8907bbfSEdison Ai 
221f8907bbfSEdison Ai 	e = TEE_U32_FROM_BIG_ENDIAN(e);
222f8907bbfSEdison Ai 	lmd_res = mbedtls_rsa_gen_key(&rsa, mbd_rand, NULL, key_size, (int)e);
223f8907bbfSEdison Ai 	if (lmd_res != 0) {
224f8907bbfSEdison Ai 		res = get_tee_result(lmd_res);
225f8907bbfSEdison Ai 	} else if ((size_t)mbedtls_mpi_bitlen(&rsa.N) != key_size) {
226f8907bbfSEdison Ai 		res = TEE_ERROR_BAD_PARAMETERS;
227f8907bbfSEdison Ai 	} else {
228f8907bbfSEdison Ai 		/* Copy the key */
229f8907bbfSEdison Ai 		crypto_bignum_copy(key->e, (void *)&rsa.E);
230f8907bbfSEdison Ai 		crypto_bignum_copy(key->d, (void *)&rsa.D);
231f8907bbfSEdison Ai 		crypto_bignum_copy(key->n, (void *)&rsa.N);
232f8907bbfSEdison Ai 		crypto_bignum_copy(key->p, (void *)&rsa.P);
233f8907bbfSEdison Ai 
234f8907bbfSEdison Ai 		crypto_bignum_copy(key->q, (void *)&rsa.Q);
235f8907bbfSEdison Ai 		crypto_bignum_copy(key->qp, (void *)&rsa.QP);
236f8907bbfSEdison Ai 		crypto_bignum_copy(key->dp, (void *)&rsa.DP);
237f8907bbfSEdison Ai 		crypto_bignum_copy(key->dq, (void *)&rsa.DQ);
238f8907bbfSEdison Ai 
239f8907bbfSEdison Ai 		res = TEE_SUCCESS;
240f8907bbfSEdison Ai 	}
241f8907bbfSEdison Ai 
242f8907bbfSEdison Ai 	mbedtls_rsa_free(&rsa);
243f8907bbfSEdison Ai 
244f8907bbfSEdison Ai 	return res;
245f8907bbfSEdison Ai }
246f8907bbfSEdison Ai 
247f8907bbfSEdison Ai TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
248f8907bbfSEdison Ai 					   const uint8_t *src, size_t src_len,
249f8907bbfSEdison Ai 					   uint8_t *dst, size_t *dst_len)
250f8907bbfSEdison Ai {
251f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
252f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
253f8907bbfSEdison Ai 	int lmd_res = 0;
254f8907bbfSEdison Ai 	uint8_t *buf = NULL;
255f8907bbfSEdison Ai 	unsigned long blen = 0;
256f8907bbfSEdison Ai 	unsigned long offset = 0;
257f8907bbfSEdison Ai 
258f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
259f8907bbfSEdison Ai 	mbedtls_rsa_init(&rsa, 0, 0);
260f8907bbfSEdison Ai 
261f8907bbfSEdison Ai 	rsa.E = *(mbedtls_mpi *)key->e;
262f8907bbfSEdison Ai 	rsa.N = *(mbedtls_mpi *)key->n;
263f8907bbfSEdison Ai 
264f8907bbfSEdison Ai 	rsa.len = crypto_bignum_num_bytes((void *)&rsa.N);
265f8907bbfSEdison Ai 
266f8907bbfSEdison Ai 	blen = CFG_CORE_BIGNUM_MAX_BITS / 8;
267f8907bbfSEdison Ai 	buf = malloc(blen);
268f8907bbfSEdison Ai 	if (!buf) {
269f8907bbfSEdison Ai 		res = TEE_ERROR_OUT_OF_MEMORY;
270f8907bbfSEdison Ai 		goto out;
271f8907bbfSEdison Ai 	}
272f8907bbfSEdison Ai 
273f8907bbfSEdison Ai 	memset(buf, 0, blen);
274f8907bbfSEdison Ai 	memcpy(buf + rsa.len - src_len, src, src_len);
275f8907bbfSEdison Ai 
276f8907bbfSEdison Ai 	lmd_res = mbedtls_rsa_public(&rsa, buf, buf);
277f8907bbfSEdison Ai 	if (lmd_res != 0) {
278f8907bbfSEdison Ai 		FMSG("mbedtls_rsa_public() returned 0x%x", -lmd_res);
279f8907bbfSEdison Ai 		res = get_tee_result(lmd_res);
280f8907bbfSEdison Ai 		goto out;
281f8907bbfSEdison Ai 	}
282f8907bbfSEdison Ai 
283f8907bbfSEdison Ai 	/* Remove the zero-padding (leave one zero if buff is all zeroes) */
284f8907bbfSEdison Ai 	offset = 0;
285f8907bbfSEdison Ai 	while ((offset < rsa.len - 1) && (buf[offset] == 0))
286f8907bbfSEdison Ai 		offset++;
287f8907bbfSEdison Ai 
288f8907bbfSEdison Ai 	if (*dst_len < rsa.len - offset) {
289f8907bbfSEdison Ai 		*dst_len = rsa.len - offset;
290f8907bbfSEdison Ai 		res = TEE_ERROR_SHORT_BUFFER;
291f8907bbfSEdison Ai 		goto out;
292f8907bbfSEdison Ai 	}
293f8907bbfSEdison Ai 	*dst_len = rsa.len - offset;
294f8907bbfSEdison Ai 	memcpy(dst, buf + offset, *dst_len);
295f8907bbfSEdison Ai out:
296f8907bbfSEdison Ai 	free(buf);
297f8907bbfSEdison Ai 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
298f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa.E);
299f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa.N);
300f8907bbfSEdison Ai 	mbedtls_rsa_free(&rsa);
301f8907bbfSEdison Ai 
302f8907bbfSEdison Ai 	return res;
303f8907bbfSEdison Ai }
304f8907bbfSEdison Ai 
305f8907bbfSEdison Ai TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
306f8907bbfSEdison Ai 					   const uint8_t *src, size_t src_len,
307f8907bbfSEdison Ai 					   uint8_t *dst, size_t *dst_len)
308f8907bbfSEdison Ai {
309f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
310f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
311f8907bbfSEdison Ai 	int lmd_res = 0;
312f8907bbfSEdison Ai 	uint8_t *buf = NULL;
313f8907bbfSEdison Ai 	unsigned long blen = 0;
314f8907bbfSEdison Ai 	unsigned long offset = 0;
315f8907bbfSEdison Ai 
316f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
317f8907bbfSEdison Ai 	rsa_init_from_key_pair(&rsa, key);
318f8907bbfSEdison Ai 
319f8907bbfSEdison Ai 	blen = CFG_CORE_BIGNUM_MAX_BITS / 8;
320f8907bbfSEdison Ai 	buf = malloc(blen);
321f8907bbfSEdison Ai 	if (!buf) {
322f8907bbfSEdison Ai 		res = TEE_ERROR_OUT_OF_MEMORY;
323f8907bbfSEdison Ai 		goto out;
324f8907bbfSEdison Ai 	}
325f8907bbfSEdison Ai 
326f8907bbfSEdison Ai 	memset(buf, 0, blen);
327f8907bbfSEdison Ai 	memcpy(buf + rsa.len - src_len, src, src_len);
328f8907bbfSEdison Ai 
329f8907bbfSEdison Ai 	lmd_res = mbedtls_rsa_private(&rsa, NULL, NULL, buf, buf);
330f8907bbfSEdison Ai 	if (lmd_res != 0) {
331f8907bbfSEdison Ai 		FMSG("mbedtls_rsa_private() returned 0x%x", -lmd_res);
332f8907bbfSEdison Ai 		res = get_tee_result(lmd_res);
333f8907bbfSEdison Ai 		goto out;
334f8907bbfSEdison Ai 	}
335f8907bbfSEdison Ai 
336f8907bbfSEdison Ai 	/* Remove the zero-padding (leave one zero if buff is all zeroes) */
337f8907bbfSEdison Ai 	offset = 0;
338f8907bbfSEdison Ai 	while ((offset < rsa.len - 1) && (buf[offset] == 0))
339f8907bbfSEdison Ai 		offset++;
340f8907bbfSEdison Ai 
341f8907bbfSEdison Ai 	if (*dst_len < rsa.len - offset) {
342f8907bbfSEdison Ai 		*dst_len = rsa.len - offset;
343f8907bbfSEdison Ai 		res = TEE_ERROR_SHORT_BUFFER;
344f8907bbfSEdison Ai 		goto out;
345f8907bbfSEdison Ai 	}
346f8907bbfSEdison Ai 	*dst_len = rsa.len - offset;
347f8907bbfSEdison Ai 	memcpy(dst, (char *)buf + offset, *dst_len);
348f8907bbfSEdison Ai out:
349f8907bbfSEdison Ai 	if (buf)
350f8907bbfSEdison Ai 		free(buf);
351f8907bbfSEdison Ai 	mbd_rsa_free(&rsa);
352f8907bbfSEdison Ai 	return res;
353f8907bbfSEdison Ai }
354f8907bbfSEdison Ai 
355f8907bbfSEdison Ai TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key,
356f8907bbfSEdison Ai 					const uint8_t *label __unused,
357f8907bbfSEdison Ai 					size_t label_len __unused,
358f8907bbfSEdison Ai 					const uint8_t *src, size_t src_len,
359f8907bbfSEdison Ai 					uint8_t *dst, size_t *dst_len)
360f8907bbfSEdison Ai {
361f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
362f8907bbfSEdison Ai 	int lmd_res = 0;
363f8907bbfSEdison Ai 	int lmd_padding = 0;
364f8907bbfSEdison Ai 	size_t blen = 0;
365f8907bbfSEdison Ai 	size_t mod_size = 0;
366f8907bbfSEdison Ai 	void *buf = NULL;
367f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
368f8907bbfSEdison Ai 	const mbedtls_pk_info_t *pk_info = NULL;
369f8907bbfSEdison Ai 	uint32_t md_algo = MBEDTLS_MD_NONE;
370f8907bbfSEdison Ai 
371f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
372f8907bbfSEdison Ai 	rsa_init_from_key_pair(&rsa, key);
373f8907bbfSEdison Ai 
374f8907bbfSEdison Ai 	/*
375f8907bbfSEdison Ai 	 * Use a temporary buffer since we don't know exactly how large
376f8907bbfSEdison Ai 	 * the required size of the out buffer without doing a partial
377f8907bbfSEdison Ai 	 * decrypt. We know the upper bound though.
378f8907bbfSEdison Ai 	 */
379f8907bbfSEdison Ai 	if (algo == TEE_ALG_RSAES_PKCS1_V1_5) {
380f8907bbfSEdison Ai 		mod_size = crypto_bignum_num_bytes(key->n);
381f8907bbfSEdison Ai 		blen = mod_size - 11;
382f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V15;
383f8907bbfSEdison Ai 	} else {
384f8907bbfSEdison Ai 		/* Decoded message is always shorter than encrypted message */
385f8907bbfSEdison Ai 		blen = src_len;
386f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V21;
387f8907bbfSEdison Ai 	}
388f8907bbfSEdison Ai 
389f8907bbfSEdison Ai 	buf = malloc(blen);
390f8907bbfSEdison Ai 	if (!buf) {
391f8907bbfSEdison Ai 		res = TEE_ERROR_OUT_OF_MEMORY;
392f8907bbfSEdison Ai 		goto out;
393f8907bbfSEdison Ai 	}
394f8907bbfSEdison Ai 
395f8907bbfSEdison Ai 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
396f8907bbfSEdison Ai 	if (!pk_info) {
397f8907bbfSEdison Ai 		res = TEE_ERROR_NOT_SUPPORTED;
398f8907bbfSEdison Ai 		goto out;
399f8907bbfSEdison Ai 	}
400f8907bbfSEdison Ai 
401f8907bbfSEdison Ai 	/*
402f8907bbfSEdison Ai 	 * TEE_ALG_RSAES_PKCS1_V1_5 is invalid in hash. But its hash algo will
403f8907bbfSEdison Ai 	 * not be used in rsa, so skip it here.
404f8907bbfSEdison Ai 	 */
405f8907bbfSEdison Ai 	if (algo != TEE_ALG_RSAES_PKCS1_V1_5) {
406f8907bbfSEdison Ai 		md_algo = tee_algo_to_mbedtls_hash_algo(algo);
407f8907bbfSEdison Ai 		if (md_algo == MBEDTLS_MD_NONE) {
408f8907bbfSEdison Ai 			res = TEE_ERROR_NOT_SUPPORTED;
409f8907bbfSEdison Ai 			goto out;
410f8907bbfSEdison Ai 		}
411f8907bbfSEdison Ai 	}
412f8907bbfSEdison Ai 
413f8907bbfSEdison Ai 	mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo);
414f8907bbfSEdison Ai 
415f8907bbfSEdison Ai 	if (lmd_padding == MBEDTLS_RSA_PKCS_V15)
416f8907bbfSEdison Ai 		lmd_res = pk_info->decrypt_func(&rsa, src, src_len, buf, &blen,
417f8907bbfSEdison Ai 						blen, NULL, NULL);
418f8907bbfSEdison Ai 	else
419f8907bbfSEdison Ai 		lmd_res = pk_info->decrypt_func(&rsa, src, src_len, buf, &blen,
420f8907bbfSEdison Ai 						blen, mbd_rand, NULL);
421f8907bbfSEdison Ai 	if (lmd_res != 0) {
422f8907bbfSEdison Ai 		FMSG("decrypt_func() returned 0x%x", -lmd_res);
423f8907bbfSEdison Ai 		res = get_tee_result(lmd_res);
424f8907bbfSEdison Ai 		goto out;
425f8907bbfSEdison Ai 	}
426f8907bbfSEdison Ai 
427f8907bbfSEdison Ai 	if (*dst_len < blen) {
428f8907bbfSEdison Ai 		*dst_len = blen;
429f8907bbfSEdison Ai 		res = TEE_ERROR_SHORT_BUFFER;
430f8907bbfSEdison Ai 		goto out;
431f8907bbfSEdison Ai 	}
432f8907bbfSEdison Ai 
433f8907bbfSEdison Ai 	res = TEE_SUCCESS;
434f8907bbfSEdison Ai 	*dst_len = blen;
435f8907bbfSEdison Ai 	memcpy(dst, buf, blen);
436f8907bbfSEdison Ai out:
437f8907bbfSEdison Ai 	if (buf)
438f8907bbfSEdison Ai 		free(buf);
439f8907bbfSEdison Ai 	mbd_rsa_free(&rsa);
440f8907bbfSEdison Ai 	return res;
441f8907bbfSEdison Ai }
442f8907bbfSEdison Ai 
443f8907bbfSEdison Ai TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
444f8907bbfSEdison Ai 					struct rsa_public_key *key,
445f8907bbfSEdison Ai 					const uint8_t *label __unused,
446f8907bbfSEdison Ai 					size_t label_len __unused,
447f8907bbfSEdison Ai 					const uint8_t *src, size_t src_len,
448f8907bbfSEdison Ai 					uint8_t *dst, size_t *dst_len)
449f8907bbfSEdison Ai {
450f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
451f8907bbfSEdison Ai 	int lmd_res = 0;
452f8907bbfSEdison Ai 	int lmd_padding = 0;
453f8907bbfSEdison Ai 	size_t mod_size = 0;
454f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
455f8907bbfSEdison Ai 	const mbedtls_pk_info_t *pk_info = NULL;
456f8907bbfSEdison Ai 	uint32_t md_algo = MBEDTLS_MD_NONE;
457f8907bbfSEdison Ai 
458f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
459f8907bbfSEdison Ai 	mbedtls_rsa_init(&rsa, 0, 0);
460f8907bbfSEdison Ai 
461f8907bbfSEdison Ai 	rsa.E = *(mbedtls_mpi *)key->e;
462f8907bbfSEdison Ai 	rsa.N = *(mbedtls_mpi *)key->n;
463f8907bbfSEdison Ai 
464f8907bbfSEdison Ai 	mod_size = crypto_bignum_num_bytes(key->n);
465f8907bbfSEdison Ai 	if (*dst_len < mod_size) {
466f8907bbfSEdison Ai 		*dst_len = mod_size;
467f8907bbfSEdison Ai 		res = TEE_ERROR_SHORT_BUFFER;
468f8907bbfSEdison Ai 		goto out;
469f8907bbfSEdison Ai 	}
470f8907bbfSEdison Ai 	*dst_len = mod_size;
471f8907bbfSEdison Ai 	rsa.len = mod_size;
472f8907bbfSEdison Ai 
473f8907bbfSEdison Ai 	if (algo == TEE_ALG_RSAES_PKCS1_V1_5)
474f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V15;
475f8907bbfSEdison Ai 	else
476f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V21;
477f8907bbfSEdison Ai 
478f8907bbfSEdison Ai 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
479f8907bbfSEdison Ai 	if (!pk_info) {
480f8907bbfSEdison Ai 		res = TEE_ERROR_NOT_SUPPORTED;
481f8907bbfSEdison Ai 		goto out;
482f8907bbfSEdison Ai 	}
483f8907bbfSEdison Ai 
484f8907bbfSEdison Ai 	/*
485f8907bbfSEdison Ai 	 * TEE_ALG_RSAES_PKCS1_V1_5 is invalid in hash. But its hash algo will
486f8907bbfSEdison Ai 	 * not be used in rsa, so skip it here.
487f8907bbfSEdison Ai 	 */
488f8907bbfSEdison Ai 	if (algo != TEE_ALG_RSAES_PKCS1_V1_5) {
489f8907bbfSEdison Ai 		md_algo = tee_algo_to_mbedtls_hash_algo(algo);
490f8907bbfSEdison Ai 		if (md_algo == MBEDTLS_MD_NONE) {
491f8907bbfSEdison Ai 			res = TEE_ERROR_NOT_SUPPORTED;
492f8907bbfSEdison Ai 			goto out;
493f8907bbfSEdison Ai 		}
494f8907bbfSEdison Ai 	}
495f8907bbfSEdison Ai 
496f8907bbfSEdison Ai 	mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo);
497f8907bbfSEdison Ai 
498f8907bbfSEdison Ai 	lmd_res = pk_info->encrypt_func(&rsa, src, src_len, dst, dst_len,
499f8907bbfSEdison Ai 					*dst_len, mbd_rand, NULL);
500f8907bbfSEdison Ai 	if (lmd_res != 0) {
501f8907bbfSEdison Ai 		FMSG("encrypt_func() returned 0x%x", -lmd_res);
502f8907bbfSEdison Ai 		res = get_tee_result(lmd_res);
503f8907bbfSEdison Ai 		goto out;
504f8907bbfSEdison Ai 	}
505f8907bbfSEdison Ai 	res = TEE_SUCCESS;
506f8907bbfSEdison Ai out:
507f8907bbfSEdison Ai 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
508f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa.E);
509f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa.N);
510f8907bbfSEdison Ai 	mbedtls_rsa_free(&rsa);
511f8907bbfSEdison Ai 	return res;
512f8907bbfSEdison Ai }
513f8907bbfSEdison Ai 
514f8907bbfSEdison Ai TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key,
515f8907bbfSEdison Ai 				      int salt_len __unused, const uint8_t *msg,
516f8907bbfSEdison Ai 				      size_t msg_len, uint8_t *sig,
517f8907bbfSEdison Ai 				      size_t *sig_len)
518f8907bbfSEdison Ai {
519f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
520f8907bbfSEdison Ai 	int lmd_res = 0;
521f8907bbfSEdison Ai 	int lmd_padding = 0;
522f8907bbfSEdison Ai 	size_t mod_size = 0;
523f8907bbfSEdison Ai 	size_t hash_size = 0;
524f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
525f8907bbfSEdison Ai 	const mbedtls_pk_info_t *pk_info = NULL;
526f8907bbfSEdison Ai 	uint32_t md_algo = 0;
527f8907bbfSEdison Ai 
528f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
529f8907bbfSEdison Ai 	rsa_init_from_key_pair(&rsa, key);
530f8907bbfSEdison Ai 
531f8907bbfSEdison Ai 	switch (algo) {
532f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
533f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
534f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
535f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
536f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
537f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
538f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V15;
539f8907bbfSEdison Ai 		break;
540f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
541f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
542f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
543f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
544f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
545f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V21;
546f8907bbfSEdison Ai 		break;
547f8907bbfSEdison Ai 	default:
548f8907bbfSEdison Ai 		res = TEE_ERROR_BAD_PARAMETERS;
549f8907bbfSEdison Ai 		goto err;
550f8907bbfSEdison Ai 	}
551f8907bbfSEdison Ai 
5527c767434SAlbert Schwarzkopf 	res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
553f8907bbfSEdison Ai 				      &hash_size);
554f8907bbfSEdison Ai 	if (res != TEE_SUCCESS)
555f8907bbfSEdison Ai 		goto err;
556f8907bbfSEdison Ai 
557f8907bbfSEdison Ai 	if (msg_len != hash_size) {
558f8907bbfSEdison Ai 		res = TEE_ERROR_BAD_PARAMETERS;
559f8907bbfSEdison Ai 		goto err;
560f8907bbfSEdison Ai 	}
561f8907bbfSEdison Ai 
562f8907bbfSEdison Ai 	mod_size = crypto_bignum_num_bytes(key->n);
563f8907bbfSEdison Ai 	if (*sig_len < mod_size) {
564f8907bbfSEdison Ai 		*sig_len = mod_size;
565f8907bbfSEdison Ai 		res = TEE_ERROR_SHORT_BUFFER;
566f8907bbfSEdison Ai 		goto err;
567f8907bbfSEdison Ai 	}
568f8907bbfSEdison Ai 	rsa.len = mod_size;
569f8907bbfSEdison Ai 
570f8907bbfSEdison Ai 	md_algo = tee_algo_to_mbedtls_hash_algo(algo);
571f8907bbfSEdison Ai 	if (md_algo == MBEDTLS_MD_NONE) {
572f8907bbfSEdison Ai 		res = TEE_ERROR_NOT_SUPPORTED;
573f8907bbfSEdison Ai 		goto err;
574f8907bbfSEdison Ai 	}
575f8907bbfSEdison Ai 
576f8907bbfSEdison Ai 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
577f8907bbfSEdison Ai 	if (!pk_info) {
578f8907bbfSEdison Ai 		res = TEE_ERROR_NOT_SUPPORTED;
579f8907bbfSEdison Ai 		goto err;
580f8907bbfSEdison Ai 	}
581f8907bbfSEdison Ai 
582f8907bbfSEdison Ai 	mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo);
583f8907bbfSEdison Ai 
584f8907bbfSEdison Ai 	if (lmd_padding == MBEDTLS_RSA_PKCS_V15)
585f8907bbfSEdison Ai 		lmd_res = pk_info->sign_func(&rsa, md_algo, msg, msg_len, sig,
586f8907bbfSEdison Ai 					     sig_len, NULL, NULL);
587f8907bbfSEdison Ai 	else
588f8907bbfSEdison Ai 		lmd_res = pk_info->sign_func(&rsa, md_algo, msg, msg_len, sig,
589f8907bbfSEdison Ai 					     sig_len, mbd_rand, NULL);
590f8907bbfSEdison Ai 	if (lmd_res != 0) {
591f8907bbfSEdison Ai 		FMSG("sign_func failed, returned 0x%x", -lmd_res);
592f8907bbfSEdison Ai 		res = get_tee_result(lmd_res);
593f8907bbfSEdison Ai 		goto err;
594f8907bbfSEdison Ai 	}
595f8907bbfSEdison Ai 	res = TEE_SUCCESS;
596f8907bbfSEdison Ai err:
597f8907bbfSEdison Ai 	mbd_rsa_free(&rsa);
598f8907bbfSEdison Ai 	return res;
599f8907bbfSEdison Ai }
600f8907bbfSEdison Ai 
601f8907bbfSEdison Ai TEE_Result crypto_acipher_rsassa_verify(uint32_t algo,
602f8907bbfSEdison Ai 					struct rsa_public_key *key,
603f8907bbfSEdison Ai 					int salt_len __unused,
604f8907bbfSEdison Ai 					const uint8_t *msg,
605f8907bbfSEdison Ai 					size_t msg_len, const uint8_t *sig,
606f8907bbfSEdison Ai 					size_t sig_len)
607f8907bbfSEdison Ai {
608f8907bbfSEdison Ai 	TEE_Result res = TEE_SUCCESS;
609f8907bbfSEdison Ai 	int lmd_res = 0;
610f8907bbfSEdison Ai 	int lmd_padding = 0;
611f8907bbfSEdison Ai 	size_t hash_size = 0;
612f8907bbfSEdison Ai 	size_t bigint_size = 0;
613f8907bbfSEdison Ai 	mbedtls_rsa_context rsa;
614f8907bbfSEdison Ai 	const mbedtls_pk_info_t *pk_info = NULL;
615f8907bbfSEdison Ai 	uint32_t md_algo = 0;
616f8907bbfSEdison Ai 
617f8907bbfSEdison Ai 	memset(&rsa, 0, sizeof(rsa));
618f8907bbfSEdison Ai 	mbedtls_rsa_init(&rsa, 0, 0);
619f8907bbfSEdison Ai 
620f8907bbfSEdison Ai 	rsa.E = *(mbedtls_mpi *)key->e;
621f8907bbfSEdison Ai 	rsa.N = *(mbedtls_mpi *)key->n;
622f8907bbfSEdison Ai 
6237c767434SAlbert Schwarzkopf 	res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
624f8907bbfSEdison Ai 				      &hash_size);
625f8907bbfSEdison Ai 	if (res != TEE_SUCCESS)
626f8907bbfSEdison Ai 		goto err;
627f8907bbfSEdison Ai 
628f8907bbfSEdison Ai 	if (msg_len != hash_size) {
629f8907bbfSEdison Ai 		res = TEE_ERROR_BAD_PARAMETERS;
630f8907bbfSEdison Ai 		goto err;
631f8907bbfSEdison Ai 	}
632f8907bbfSEdison Ai 
633f8907bbfSEdison Ai 	bigint_size = crypto_bignum_num_bytes(key->n);
634f8907bbfSEdison Ai 	if (sig_len < bigint_size) {
635f8907bbfSEdison Ai 		res = TEE_ERROR_MAC_INVALID;
636f8907bbfSEdison Ai 		goto err;
637f8907bbfSEdison Ai 	}
638f8907bbfSEdison Ai 
639f8907bbfSEdison Ai 	rsa.len = bigint_size;
640f8907bbfSEdison Ai 
641f8907bbfSEdison Ai 	switch (algo) {
642f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
643f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
644f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
645f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
646f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
647f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
648f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V15;
649f8907bbfSEdison Ai 		break;
650f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
651f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
652f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
653f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
654f8907bbfSEdison Ai 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
655f8907bbfSEdison Ai 		lmd_padding = MBEDTLS_RSA_PKCS_V21;
656f8907bbfSEdison Ai 		break;
657f8907bbfSEdison Ai 	default:
658f8907bbfSEdison Ai 		res = TEE_ERROR_BAD_PARAMETERS;
659f8907bbfSEdison Ai 		goto err;
660f8907bbfSEdison Ai 	}
661f8907bbfSEdison Ai 
662f8907bbfSEdison Ai 	md_algo = tee_algo_to_mbedtls_hash_algo(algo);
663f8907bbfSEdison Ai 	if (md_algo == MBEDTLS_MD_NONE) {
664f8907bbfSEdison Ai 		res = TEE_ERROR_NOT_SUPPORTED;
665f8907bbfSEdison Ai 		goto err;
666f8907bbfSEdison Ai 	}
667f8907bbfSEdison Ai 
668f8907bbfSEdison Ai 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
669f8907bbfSEdison Ai 	if (!pk_info) {
670f8907bbfSEdison Ai 		res = TEE_ERROR_NOT_SUPPORTED;
671f8907bbfSEdison Ai 		goto err;
672f8907bbfSEdison Ai 	}
673f8907bbfSEdison Ai 
674f8907bbfSEdison Ai 	mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo);
675f8907bbfSEdison Ai 
676f8907bbfSEdison Ai 	lmd_res = pk_info->verify_func(&rsa, md_algo, msg, msg_len,
677f8907bbfSEdison Ai 				       sig, sig_len);
678f8907bbfSEdison Ai 	if (lmd_res != 0) {
679f8907bbfSEdison Ai 		FMSG("verify_func failed, returned 0x%x", -lmd_res);
680f8907bbfSEdison Ai 		res = TEE_ERROR_SIGNATURE_INVALID;
681f8907bbfSEdison Ai 		goto err;
682f8907bbfSEdison Ai 	}
683f8907bbfSEdison Ai 	res = TEE_SUCCESS;
684f8907bbfSEdison Ai err:
685f8907bbfSEdison Ai 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
686f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa.E);
687f8907bbfSEdison Ai 	mbedtls_mpi_init(&rsa.N);
688f8907bbfSEdison Ai 	mbedtls_rsa_free(&rsa);
689f8907bbfSEdison Ai 	return res;
690f8907bbfSEdison Ai }
691