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