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