189ed30d1SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
289ed30d1SJens Wiklander /*
38f6ac972SJens Wiklander * Copyright (c) 2014-2019, 2022 Linaro Limited
489ed30d1SJens Wiklander */
589ed30d1SJens Wiklander
689ed30d1SJens Wiklander #include <crypto/crypto.h>
7c2c27539SJorge Ramirez-Ortiz #include <crypto/crypto_impl.h>
88f6ac972SJens Wiklander #include <fault_mitigation.h>
9d71c4cd4SJens Wiklander #include <mempool.h>
1089ed30d1SJens Wiklander #include <stdlib.h>
1189ed30d1SJens Wiklander #include <string.h>
1289ed30d1SJens Wiklander #include <tee_api_defines_extensions.h>
138f6ac972SJens Wiklander #include <tee_api_types.h>
1489ed30d1SJens Wiklander #include <tee/tee_cryp_utl.h>
1589ed30d1SJens Wiklander #include <trace.h>
1689ed30d1SJens Wiklander #include <utee_defines.h>
1789ed30d1SJens Wiklander
1889ed30d1SJens Wiklander #include "acipher_helpers.h"
1989ed30d1SJens Wiklander
2089ed30d1SJens Wiklander
2189ed30d1SJens Wiklander /*
2289ed30d1SJens Wiklander * Compute the LibTomCrypt "hashindex" given a TEE Algorithm "algo"
2389ed30d1SJens Wiklander * Return
2489ed30d1SJens Wiklander * - TEE_SUCCESS in case of success,
2589ed30d1SJens Wiklander * - TEE_ERROR_BAD_PARAMETERS in case algo is not a valid algo
2689ed30d1SJens Wiklander * - TEE_ERROR_NOT_SUPPORTED in case algo is not supported by LTC
2789ed30d1SJens Wiklander * Return -1 in case of error
2889ed30d1SJens Wiklander */
tee_algo_to_ltc_hashindex(uint32_t algo,int * ltc_hashindex)2989ed30d1SJens Wiklander static TEE_Result tee_algo_to_ltc_hashindex(uint32_t algo, int *ltc_hashindex)
3089ed30d1SJens Wiklander {
3189ed30d1SJens Wiklander switch (algo) {
3232b31808SJens Wiklander #if defined(_CFG_CORE_LTC_SHA1_DESC)
33*86ee543bSSami Tolvanen case TEE_ALG_SHA1:
3489ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
3589ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
3689ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
3789ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha1");
3889ed30d1SJens Wiklander break;
3989ed30d1SJens Wiklander #endif
4032b31808SJens Wiklander #if defined(_CFG_CORE_LTC_MD5_DESC)
41*86ee543bSSami Tolvanen case TEE_ALG_MD5:
4289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
43f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5:
44f5c3d85aSJulien Masson case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5:
4589ed30d1SJens Wiklander *ltc_hashindex = find_hash("md5");
4689ed30d1SJens Wiklander break;
4789ed30d1SJens Wiklander #endif
4832b31808SJens Wiklander #if defined(_CFG_CORE_LTC_SHA224_DESC)
49*86ee543bSSami Tolvanen case TEE_ALG_SHA224:
5089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
5189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
5289ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
5389ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha224");
5489ed30d1SJens Wiklander break;
5589ed30d1SJens Wiklander #endif
5632b31808SJens Wiklander #if defined(_CFG_CORE_LTC_SHA256_DESC)
57*86ee543bSSami Tolvanen case TEE_ALG_SHA256:
5889ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
5989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
6089ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
6189ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha256");
6289ed30d1SJens Wiklander break;
6389ed30d1SJens Wiklander #endif
6432b31808SJens Wiklander #if defined(_CFG_CORE_LTC_SHA384_DESC)
65*86ee543bSSami Tolvanen case TEE_ALG_SHA384:
6689ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
6789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
6889ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
6989ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha384");
7089ed30d1SJens Wiklander break;
7189ed30d1SJens Wiklander #endif
7232b31808SJens Wiklander #if defined(_CFG_CORE_LTC_SHA512_DESC)
73*86ee543bSSami Tolvanen case TEE_ALG_SHA512:
7489ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
7589ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
7689ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
7789ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha512");
7889ed30d1SJens Wiklander break;
7989ed30d1SJens Wiklander #endif
8089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5:
8189ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_V1_5:
8289ed30d1SJens Wiklander /* invalid one. but it should not be used anyway */
8389ed30d1SJens Wiklander *ltc_hashindex = -1;
8489ed30d1SJens Wiklander return TEE_SUCCESS;
8589ed30d1SJens Wiklander
8689ed30d1SJens Wiklander default:
8789ed30d1SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
8889ed30d1SJens Wiklander }
8989ed30d1SJens Wiklander
9089ed30d1SJens Wiklander if (*ltc_hashindex < 0)
9189ed30d1SJens Wiklander return TEE_ERROR_NOT_SUPPORTED;
9289ed30d1SJens Wiklander else
9389ed30d1SJens Wiklander return TEE_SUCCESS;
9489ed30d1SJens Wiklander }
9589ed30d1SJens Wiklander
9689ed30d1SJens Wiklander TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s,
9789ed30d1SJens Wiklander size_t key_size_bits __unused)
98c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_alloc_rsa_keypair");
99c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_alloc_rsa_keypair(struct rsa_keypair * s,size_t key_size_bits __unused)100c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s,
101c2c27539SJorge Ramirez-Ortiz size_t key_size_bits __unused)
10289ed30d1SJens Wiklander {
10389ed30d1SJens Wiklander memset(s, 0, sizeof(*s));
10489ed30d1SJens Wiklander if (!bn_alloc_max(&s->e))
10589ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
10689ed30d1SJens Wiklander if (!bn_alloc_max(&s->d))
10789ed30d1SJens Wiklander goto err;
10889ed30d1SJens Wiklander if (!bn_alloc_max(&s->n))
10989ed30d1SJens Wiklander goto err;
11089ed30d1SJens Wiklander if (!bn_alloc_max(&s->p))
11189ed30d1SJens Wiklander goto err;
11289ed30d1SJens Wiklander if (!bn_alloc_max(&s->q))
11389ed30d1SJens Wiklander goto err;
11489ed30d1SJens Wiklander if (!bn_alloc_max(&s->qp))
11589ed30d1SJens Wiklander goto err;
11689ed30d1SJens Wiklander if (!bn_alloc_max(&s->dp))
11789ed30d1SJens Wiklander goto err;
11889ed30d1SJens Wiklander if (!bn_alloc_max(&s->dq))
11989ed30d1SJens Wiklander goto err;
12089ed30d1SJens Wiklander
12189ed30d1SJens Wiklander return TEE_SUCCESS;
12289ed30d1SJens Wiklander err:
12392e38694SJerome Forissier crypto_acipher_free_rsa_keypair(s);
12489ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
12589ed30d1SJens Wiklander }
12689ed30d1SJens Wiklander
127c2c27539SJorge Ramirez-Ortiz
12889ed30d1SJens Wiklander TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s,
12989ed30d1SJens Wiklander size_t key_size_bits __unused)
130c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_alloc_rsa_public_key");
131c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_alloc_rsa_public_key(struct rsa_public_key * s,size_t key_size_bits __unused)132c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s,
133c2c27539SJorge Ramirez-Ortiz size_t key_size_bits __unused)
13489ed30d1SJens Wiklander {
13589ed30d1SJens Wiklander memset(s, 0, sizeof(*s));
13689ed30d1SJens Wiklander if (!bn_alloc_max(&s->e))
13789ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
13889ed30d1SJens Wiklander if (!bn_alloc_max(&s->n))
13989ed30d1SJens Wiklander goto err;
14089ed30d1SJens Wiklander return TEE_SUCCESS;
14189ed30d1SJens Wiklander err:
142e2ec831cSJihwan Park crypto_bignum_free(&s->e);
14389ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
14489ed30d1SJens Wiklander }
14589ed30d1SJens Wiklander
146c2c27539SJorge Ramirez-Ortiz
14789ed30d1SJens Wiklander void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s)
148c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_free_rsa_public_key");
149c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_free_rsa_public_key(struct rsa_public_key * s)150c2c27539SJorge Ramirez-Ortiz void sw_crypto_acipher_free_rsa_public_key(struct rsa_public_key *s)
15189ed30d1SJens Wiklander {
15289ed30d1SJens Wiklander if (!s)
15389ed30d1SJens Wiklander return;
154e2ec831cSJihwan Park crypto_bignum_free(&s->n);
155e2ec831cSJihwan Park crypto_bignum_free(&s->e);
15689ed30d1SJens Wiklander }
15789ed30d1SJens Wiklander
158c2c27539SJorge Ramirez-Ortiz
159a1d5c81fSElias von Däniken void crypto_acipher_free_rsa_keypair(struct rsa_keypair *s)
160c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_free_rsa_keypair");
161c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_free_rsa_keypair(struct rsa_keypair * s)162c2c27539SJorge Ramirez-Ortiz void sw_crypto_acipher_free_rsa_keypair(struct rsa_keypair *s)
163a1d5c81fSElias von Däniken {
164a1d5c81fSElias von Däniken if (!s)
165a1d5c81fSElias von Däniken return;
166e2ec831cSJihwan Park crypto_bignum_free(&s->e);
167e2ec831cSJihwan Park crypto_bignum_free(&s->d);
168e2ec831cSJihwan Park crypto_bignum_free(&s->n);
169e2ec831cSJihwan Park crypto_bignum_free(&s->p);
170e2ec831cSJihwan Park crypto_bignum_free(&s->q);
171e2ec831cSJihwan Park crypto_bignum_free(&s->qp);
172e2ec831cSJihwan Park crypto_bignum_free(&s->dp);
173e2ec831cSJihwan Park crypto_bignum_free(&s->dq);
174a1d5c81fSElias von Däniken }
175a1d5c81fSElias von Däniken
176c2c27539SJorge Ramirez-Ortiz TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key,
177c2c27539SJorge Ramirez-Ortiz size_t key_size)
178c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_gen_rsa_key");
179c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_gen_rsa_key(struct rsa_keypair * key,size_t key_size)180c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_gen_rsa_key(struct rsa_keypair *key,
181c2c27539SJorge Ramirez-Ortiz size_t key_size)
18289ed30d1SJens Wiklander {
18389ed30d1SJens Wiklander TEE_Result res;
18489ed30d1SJens Wiklander rsa_key ltc_tmp_key;
18589ed30d1SJens Wiklander int ltc_res;
18689ed30d1SJens Wiklander
18789ed30d1SJens Wiklander /* Generate a temporary RSA key */
18874524a75SCedric Neveux ltc_res = rsa_make_key_bn_e(NULL, find_prng("prng_crypto"),
18974524a75SCedric Neveux key_size / 8, key->e, <c_tmp_key);
19089ed30d1SJens Wiklander if (ltc_res != CRYPT_OK) {
19189ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
19289ed30d1SJens Wiklander } else if ((size_t)mp_count_bits(ltc_tmp_key.N) != key_size) {
19389ed30d1SJens Wiklander rsa_free(<c_tmp_key);
19489ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
19589ed30d1SJens Wiklander } else {
19689ed30d1SJens Wiklander /* Copy the key */
19789ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.d, key->d);
19889ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.N, key->n);
19989ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.p, key->p);
20089ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.q, key->q);
20189ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.qP, key->qp);
20289ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.dP, key->dp);
20389ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.dQ, key->dq);
20489ed30d1SJens Wiklander
20589ed30d1SJens Wiklander /* Free the temporary key */
20689ed30d1SJens Wiklander rsa_free(<c_tmp_key);
20789ed30d1SJens Wiklander res = TEE_SUCCESS;
20889ed30d1SJens Wiklander }
20989ed30d1SJens Wiklander
21089ed30d1SJens Wiklander return res;
21189ed30d1SJens Wiklander }
21289ed30d1SJens Wiklander
rsadorep(rsa_key * ltc_key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)21389ed30d1SJens Wiklander static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src,
21489ed30d1SJens Wiklander size_t src_len, uint8_t *dst, size_t *dst_len)
21589ed30d1SJens Wiklander {
21689ed30d1SJens Wiklander TEE_Result res = TEE_SUCCESS;
21789ed30d1SJens Wiklander uint8_t *buf = NULL;
21889ed30d1SJens Wiklander unsigned long blen, offset;
21989ed30d1SJens Wiklander int ltc_res;
22089ed30d1SJens Wiklander
22189ed30d1SJens Wiklander /*
22289ed30d1SJens Wiklander * Use a temporary buffer since we don't know exactly how large the
22389ed30d1SJens Wiklander * required size of the out buffer without doing a partial decrypt.
22489ed30d1SJens Wiklander * We know the upper bound though.
22589ed30d1SJens Wiklander */
226a1cbb728SJens Wiklander blen = _CFG_CORE_LTC_BIGNUM_MAX_BITS / sizeof(uint8_t);
227d71c4cd4SJens Wiklander buf = mempool_alloc(mempool_default, blen);
22889ed30d1SJens Wiklander if (!buf) {
22989ed30d1SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY;
23089ed30d1SJens Wiklander goto out;
23189ed30d1SJens Wiklander }
23289ed30d1SJens Wiklander
23389ed30d1SJens Wiklander ltc_res = rsa_exptmod(src, src_len, buf, &blen, ltc_key->type,
23489ed30d1SJens Wiklander ltc_key);
23589ed30d1SJens Wiklander switch (ltc_res) {
23689ed30d1SJens Wiklander case CRYPT_PK_NOT_PRIVATE:
23789ed30d1SJens Wiklander case CRYPT_PK_INVALID_TYPE:
23889ed30d1SJens Wiklander case CRYPT_PK_INVALID_SIZE:
23989ed30d1SJens Wiklander case CRYPT_INVALID_PACKET:
24089ed30d1SJens Wiklander EMSG("rsa_exptmod() returned %d", ltc_res);
24189ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
24289ed30d1SJens Wiklander goto out;
24389ed30d1SJens Wiklander case CRYPT_OK:
24489ed30d1SJens Wiklander break;
24589ed30d1SJens Wiklander default:
24689ed30d1SJens Wiklander /* This will result in a panic */
24789ed30d1SJens Wiklander EMSG("rsa_exptmod() returned %d", ltc_res);
24889ed30d1SJens Wiklander res = TEE_ERROR_GENERIC;
24989ed30d1SJens Wiklander goto out;
25089ed30d1SJens Wiklander }
25189ed30d1SJens Wiklander
25289ed30d1SJens Wiklander /* Remove the zero-padding (leave one zero if buff is all zeroes) */
25389ed30d1SJens Wiklander offset = 0;
25489ed30d1SJens Wiklander while ((offset < blen - 1) && (buf[offset] == 0))
25589ed30d1SJens Wiklander offset++;
25689ed30d1SJens Wiklander
25789ed30d1SJens Wiklander if (*dst_len < blen - offset) {
25889ed30d1SJens Wiklander *dst_len = blen - offset;
25989ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER;
26089ed30d1SJens Wiklander goto out;
26189ed30d1SJens Wiklander }
26289ed30d1SJens Wiklander
26389ed30d1SJens Wiklander res = TEE_SUCCESS;
26489ed30d1SJens Wiklander *dst_len = blen - offset;
26589ed30d1SJens Wiklander memcpy(dst, (char *)buf + offset, *dst_len);
26689ed30d1SJens Wiklander
26789ed30d1SJens Wiklander out:
268d71c4cd4SJens Wiklander mempool_free(mempool_default, buf);
26989ed30d1SJens Wiklander
27089ed30d1SJens Wiklander return res;
27189ed30d1SJens Wiklander }
27289ed30d1SJens Wiklander
27389ed30d1SJens Wiklander TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
274c2c27539SJorge Ramirez-Ortiz const uint8_t *src,
275c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
276c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
277c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsanopad_encrypt");
278c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_rsanopad_encrypt(struct rsa_public_key * key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)279c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
280c2c27539SJorge Ramirez-Ortiz const uint8_t *src,
281c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
282c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
28389ed30d1SJens Wiklander {
28489ed30d1SJens Wiklander TEE_Result res;
28589ed30d1SJens Wiklander rsa_key ltc_key = { 0, };
28689ed30d1SJens Wiklander
28789ed30d1SJens Wiklander ltc_key.type = PK_PUBLIC;
28889ed30d1SJens Wiklander ltc_key.e = key->e;
28989ed30d1SJens Wiklander ltc_key.N = key->n;
29089ed30d1SJens Wiklander
29189ed30d1SJens Wiklander res = rsadorep(<c_key, src, src_len, dst, dst_len);
29289ed30d1SJens Wiklander return res;
29389ed30d1SJens Wiklander }
29489ed30d1SJens Wiklander
29589ed30d1SJens Wiklander TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
296c2c27539SJorge Ramirez-Ortiz const uint8_t *src,
297c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
298c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
299c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsanopad_decrypt");
300c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_rsanopad_decrypt(struct rsa_keypair * key,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)301c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
302c2c27539SJorge Ramirez-Ortiz const uint8_t *src,
303c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
304c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
30589ed30d1SJens Wiklander {
30689ed30d1SJens Wiklander TEE_Result res;
30789ed30d1SJens Wiklander rsa_key ltc_key = { 0, };
30889ed30d1SJens Wiklander
30989ed30d1SJens Wiklander ltc_key.type = PK_PRIVATE;
31089ed30d1SJens Wiklander ltc_key.e = key->e;
31189ed30d1SJens Wiklander ltc_key.N = key->n;
31289ed30d1SJens Wiklander ltc_key.d = key->d;
31389ed30d1SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) {
31489ed30d1SJens Wiklander ltc_key.p = key->p;
31589ed30d1SJens Wiklander ltc_key.q = key->q;
31689ed30d1SJens Wiklander ltc_key.qP = key->qp;
31789ed30d1SJens Wiklander ltc_key.dP = key->dp;
31889ed30d1SJens Wiklander ltc_key.dQ = key->dq;
31989ed30d1SJens Wiklander }
32089ed30d1SJens Wiklander
32189ed30d1SJens Wiklander res = rsadorep(<c_key, src, src_len, dst, dst_len);
32289ed30d1SJens Wiklander return res;
32389ed30d1SJens Wiklander }
32489ed30d1SJens Wiklander
325c2c27539SJorge Ramirez-Ortiz TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo,
326c2c27539SJorge Ramirez-Ortiz struct rsa_keypair *key,
327c2c27539SJorge Ramirez-Ortiz const uint8_t *label,
328*86ee543bSSami Tolvanen size_t label_len,
329*86ee543bSSami Tolvanen uint32_t mgf_algo,
330*86ee543bSSami Tolvanen const uint8_t *src,
331c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
332c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
333c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsaes_decrypt");
334c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_rsaes_decrypt(uint32_t algo,struct rsa_keypair * key,const uint8_t * label,size_t label_len,uint32_t mgf_algo,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)335c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,
336c2c27539SJorge Ramirez-Ortiz struct rsa_keypair *key,
337c2c27539SJorge Ramirez-Ortiz const uint8_t *label,
338*86ee543bSSami Tolvanen size_t label_len,
339*86ee543bSSami Tolvanen uint32_t mgf_algo,
340*86ee543bSSami Tolvanen const uint8_t *src,
341c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
342c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
34389ed30d1SJens Wiklander {
34489ed30d1SJens Wiklander TEE_Result res = TEE_SUCCESS;
34589ed30d1SJens Wiklander void *buf = NULL;
34689ed30d1SJens Wiklander unsigned long blen;
347*86ee543bSSami Tolvanen int ltc_hashindex, ltc_mgfindex, ltc_res, ltc_stat, ltc_rsa_algo;
34889ed30d1SJens Wiklander size_t mod_size;
34989ed30d1SJens Wiklander rsa_key ltc_key = { 0, };
35089ed30d1SJens Wiklander
35189ed30d1SJens Wiklander ltc_key.type = PK_PRIVATE;
35289ed30d1SJens Wiklander ltc_key.e = key->e;
35389ed30d1SJens Wiklander ltc_key.d = key->d;
35489ed30d1SJens Wiklander ltc_key.N = key->n;
35589ed30d1SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) {
35689ed30d1SJens Wiklander ltc_key.p = key->p;
35789ed30d1SJens Wiklander ltc_key.q = key->q;
35889ed30d1SJens Wiklander ltc_key.qP = key->qp;
35989ed30d1SJens Wiklander ltc_key.dP = key->dp;
36089ed30d1SJens Wiklander ltc_key.dQ = key->dq;
36189ed30d1SJens Wiklander }
36289ed30d1SJens Wiklander
36389ed30d1SJens Wiklander /* Get the algorithm */
36489ed30d1SJens Wiklander res = tee_algo_to_ltc_hashindex(algo, <c_hashindex);
36589ed30d1SJens Wiklander if (res != TEE_SUCCESS) {
366*86ee543bSSami Tolvanen EMSG("tee_algo_to_ltc_hashindex() returned %#"PRIx32, res);
36789ed30d1SJens Wiklander goto out;
36889ed30d1SJens Wiklander }
369*86ee543bSSami Tolvanen if (algo != TEE_ALG_RSAES_PKCS1_V1_5) {
370*86ee543bSSami Tolvanen res = tee_algo_to_ltc_hashindex(mgf_algo, <c_mgfindex);
371*86ee543bSSami Tolvanen if (res != TEE_SUCCESS) {
372*86ee543bSSami Tolvanen EMSG("tee_algo_to_ltc_hashindex() returned %#"PRIx32"for mgf algo %#"PRIx32,
373*86ee543bSSami Tolvanen res, mgf_algo);
374*86ee543bSSami Tolvanen goto out;
375*86ee543bSSami Tolvanen }
376*86ee543bSSami Tolvanen } else {
377*86ee543bSSami Tolvanen ltc_mgfindex = -1;
378*86ee543bSSami Tolvanen }
37989ed30d1SJens Wiklander
38089ed30d1SJens Wiklander /*
38189ed30d1SJens Wiklander * Use a temporary buffer since we don't know exactly how large
38289ed30d1SJens Wiklander * the required size of the out buffer without doing a partial
38389ed30d1SJens Wiklander * decrypt. We know the upper bound though.
38489ed30d1SJens Wiklander */
38589ed30d1SJens Wiklander if (algo == TEE_ALG_RSAES_PKCS1_V1_5) {
38689ed30d1SJens Wiklander mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
38789ed30d1SJens Wiklander blen = mod_size - 11;
38889ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5;
38989ed30d1SJens Wiklander } else {
39089ed30d1SJens Wiklander /* Decoded message is always shorter than encrypted message */
39189ed30d1SJens Wiklander blen = src_len;
39289ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_OAEP;
39389ed30d1SJens Wiklander }
39489ed30d1SJens Wiklander
395d71c4cd4SJens Wiklander buf = mempool_alloc(mempool_default, blen);
39689ed30d1SJens Wiklander if (!buf) {
39789ed30d1SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY;
39889ed30d1SJens Wiklander goto out;
39989ed30d1SJens Wiklander }
40089ed30d1SJens Wiklander
40189ed30d1SJens Wiklander ltc_res = rsa_decrypt_key_ex(src, src_len, buf, &blen,
40289ed30d1SJens Wiklander ((label_len == 0) ? 0 : label), label_len,
403*86ee543bSSami Tolvanen ltc_mgfindex, ltc_hashindex, ltc_rsa_algo,
404*86ee543bSSami Tolvanen <c_stat, <c_key);
40589ed30d1SJens Wiklander switch (ltc_res) {
40689ed30d1SJens Wiklander case CRYPT_PK_INVALID_PADDING:
40789ed30d1SJens Wiklander case CRYPT_INVALID_PACKET:
40889ed30d1SJens Wiklander case CRYPT_PK_INVALID_SIZE:
40989ed30d1SJens Wiklander EMSG("rsa_decrypt_key_ex() returned %d", ltc_res);
41089ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
41189ed30d1SJens Wiklander goto out;
41289ed30d1SJens Wiklander case CRYPT_OK:
41389ed30d1SJens Wiklander break;
41489ed30d1SJens Wiklander default:
41589ed30d1SJens Wiklander /* This will result in a panic */
41689ed30d1SJens Wiklander EMSG("rsa_decrypt_key_ex() returned %d", ltc_res);
41789ed30d1SJens Wiklander res = TEE_ERROR_GENERIC;
41889ed30d1SJens Wiklander goto out;
41989ed30d1SJens Wiklander }
42089ed30d1SJens Wiklander if (ltc_stat != 1) {
42189ed30d1SJens Wiklander /* This will result in a panic */
42289ed30d1SJens Wiklander EMSG("rsa_decrypt_key_ex() returned %d and %d",
42389ed30d1SJens Wiklander ltc_res, ltc_stat);
42489ed30d1SJens Wiklander res = TEE_ERROR_GENERIC;
42589ed30d1SJens Wiklander goto out;
42689ed30d1SJens Wiklander }
42789ed30d1SJens Wiklander
42889ed30d1SJens Wiklander if (*dst_len < blen) {
42989ed30d1SJens Wiklander *dst_len = blen;
43089ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER;
43189ed30d1SJens Wiklander goto out;
43289ed30d1SJens Wiklander }
43389ed30d1SJens Wiklander
43489ed30d1SJens Wiklander res = TEE_SUCCESS;
43589ed30d1SJens Wiklander *dst_len = blen;
43689ed30d1SJens Wiklander memcpy(dst, buf, blen);
43789ed30d1SJens Wiklander
43889ed30d1SJens Wiklander out:
439d71c4cd4SJens Wiklander mempool_free(mempool_default, buf);
44089ed30d1SJens Wiklander
44189ed30d1SJens Wiklander return res;
44289ed30d1SJens Wiklander }
44389ed30d1SJens Wiklander
44489ed30d1SJens Wiklander TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
44589ed30d1SJens Wiklander struct rsa_public_key *key,
446c2c27539SJorge Ramirez-Ortiz const uint8_t *label,
447*86ee543bSSami Tolvanen size_t label_len,
448*86ee543bSSami Tolvanen uint32_t mgf_algo,
449*86ee543bSSami Tolvanen const uint8_t *src,
450c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
451c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
452c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsaes_encrypt");
453c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_rsaes_encrypt(uint32_t algo,struct rsa_public_key * key,const uint8_t * label,size_t label_len,uint32_t mgf_algo,const uint8_t * src,size_t src_len,uint8_t * dst,size_t * dst_len)454c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo,
455c2c27539SJorge Ramirez-Ortiz struct rsa_public_key *key,
456c2c27539SJorge Ramirez-Ortiz const uint8_t *label,
457*86ee543bSSami Tolvanen size_t label_len,
458*86ee543bSSami Tolvanen uint32_t mgf_algo,
459*86ee543bSSami Tolvanen const uint8_t *src,
460c2c27539SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst,
461c2c27539SJorge Ramirez-Ortiz size_t *dst_len)
46289ed30d1SJens Wiklander {
46389ed30d1SJens Wiklander TEE_Result res;
46489ed30d1SJens Wiklander uint32_t mod_size;
465*86ee543bSSami Tolvanen int ltc_hashindex, ltc_mgfindex, ltc_res, ltc_rsa_algo;
46689ed30d1SJens Wiklander rsa_key ltc_key = {
46789ed30d1SJens Wiklander .type = PK_PUBLIC,
46889ed30d1SJens Wiklander .e = key->e,
46989ed30d1SJens Wiklander .N = key->n
47089ed30d1SJens Wiklander };
47189ed30d1SJens Wiklander
47289ed30d1SJens Wiklander mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
47389ed30d1SJens Wiklander if (*dst_len < mod_size) {
47489ed30d1SJens Wiklander *dst_len = mod_size;
47589ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER;
47689ed30d1SJens Wiklander goto out;
47789ed30d1SJens Wiklander }
47889ed30d1SJens Wiklander *dst_len = mod_size;
47989ed30d1SJens Wiklander
48089ed30d1SJens Wiklander /* Get the algorithm */
48189ed30d1SJens Wiklander res = tee_algo_to_ltc_hashindex(algo, <c_hashindex);
48289ed30d1SJens Wiklander if (res != TEE_SUCCESS)
48389ed30d1SJens Wiklander goto out;
48489ed30d1SJens Wiklander
485*86ee543bSSami Tolvanen if (algo != TEE_ALG_RSAES_PKCS1_V1_5) {
486*86ee543bSSami Tolvanen res = tee_algo_to_ltc_hashindex(mgf_algo, <c_mgfindex);
487*86ee543bSSami Tolvanen if (res != TEE_SUCCESS)
488*86ee543bSSami Tolvanen goto out;
489*86ee543bSSami Tolvanen } else {
490*86ee543bSSami Tolvanen ltc_mgfindex = -1;
491*86ee543bSSami Tolvanen }
492*86ee543bSSami Tolvanen
49389ed30d1SJens Wiklander if (algo == TEE_ALG_RSAES_PKCS1_V1_5)
49489ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5;
49589ed30d1SJens Wiklander else
49689ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_OAEP;
49789ed30d1SJens Wiklander
49889ed30d1SJens Wiklander ltc_res = rsa_encrypt_key_ex(src, src_len, dst,
49989ed30d1SJens Wiklander (unsigned long *)(dst_len), label,
5001f3b1115SJens Wiklander label_len, NULL, find_prng("prng_crypto"),
501*86ee543bSSami Tolvanen ltc_mgfindex, ltc_hashindex, ltc_rsa_algo,
502*86ee543bSSami Tolvanen <c_key);
50389ed30d1SJens Wiklander switch (ltc_res) {
50489ed30d1SJens Wiklander case CRYPT_PK_INVALID_PADDING:
50589ed30d1SJens Wiklander case CRYPT_INVALID_PACKET:
50689ed30d1SJens Wiklander case CRYPT_PK_INVALID_SIZE:
50789ed30d1SJens Wiklander EMSG("rsa_encrypt_key_ex() returned %d", ltc_res);
50889ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
50989ed30d1SJens Wiklander goto out;
51089ed30d1SJens Wiklander case CRYPT_OK:
51189ed30d1SJens Wiklander break;
51289ed30d1SJens Wiklander default:
51389ed30d1SJens Wiklander /* This will result in a panic */
51489ed30d1SJens Wiklander res = TEE_ERROR_GENERIC;
51589ed30d1SJens Wiklander goto out;
51689ed30d1SJens Wiklander }
51789ed30d1SJens Wiklander res = TEE_SUCCESS;
51889ed30d1SJens Wiklander
51989ed30d1SJens Wiklander out:
52089ed30d1SJens Wiklander return res;
52189ed30d1SJens Wiklander }
52289ed30d1SJens Wiklander
52389ed30d1SJens Wiklander TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key,
52489ed30d1SJens Wiklander int salt_len, const uint8_t *msg,
52589ed30d1SJens Wiklander size_t msg_len, uint8_t *sig,
52689ed30d1SJens Wiklander size_t *sig_len)
527c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsassa_sign");
528c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_rsassa_sign(uint32_t algo,struct rsa_keypair * key,int salt_len,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)529c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key,
530c2c27539SJorge Ramirez-Ortiz int salt_len, const uint8_t *msg,
531c2c27539SJorge Ramirez-Ortiz size_t msg_len, uint8_t *sig,
532c2c27539SJorge Ramirez-Ortiz size_t *sig_len)
53389ed30d1SJens Wiklander {
53489ed30d1SJens Wiklander TEE_Result res;
53589ed30d1SJens Wiklander size_t hash_size, mod_size;
53689ed30d1SJens Wiklander int ltc_res, ltc_rsa_algo, ltc_hashindex;
53789ed30d1SJens Wiklander unsigned long ltc_sig_len;
53889ed30d1SJens Wiklander rsa_key ltc_key = { 0, };
53989ed30d1SJens Wiklander
54089ed30d1SJens Wiklander ltc_key.type = PK_PRIVATE;
54189ed30d1SJens Wiklander ltc_key.e = key->e;
54289ed30d1SJens Wiklander ltc_key.N = key->n;
54389ed30d1SJens Wiklander ltc_key.d = key->d;
54489ed30d1SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) {
54589ed30d1SJens Wiklander ltc_key.p = key->p;
54689ed30d1SJens Wiklander ltc_key.q = key->q;
54789ed30d1SJens Wiklander ltc_key.qP = key->qp;
54889ed30d1SJens Wiklander ltc_key.dP = key->dp;
54989ed30d1SJens Wiklander ltc_key.dQ = key->dq;
55089ed30d1SJens Wiklander }
55189ed30d1SJens Wiklander
55289ed30d1SJens Wiklander switch (algo) {
55389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5:
55489ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1;
55589ed30d1SJens Wiklander break;
55689ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
55789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
55889ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
55989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
56089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
56189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
56289ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5;
56389ed30d1SJens Wiklander break;
564f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5:
56589ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
56689ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
56789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
56889ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
56989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
57089ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_PSS;
57189ed30d1SJens Wiklander break;
57289ed30d1SJens Wiklander default:
57389ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
57489ed30d1SJens Wiklander goto err;
57589ed30d1SJens Wiklander }
57689ed30d1SJens Wiklander
57789ed30d1SJens Wiklander if (ltc_rsa_algo != LTC_PKCS_1_V1_5_NA1) {
57889ed30d1SJens Wiklander ltc_res = tee_algo_to_ltc_hashindex(algo, <c_hashindex);
57989ed30d1SJens Wiklander if (ltc_res != CRYPT_OK) {
58089ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
58189ed30d1SJens Wiklander goto err;
58289ed30d1SJens Wiklander }
58389ed30d1SJens Wiklander
5847c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
58589ed30d1SJens Wiklander &hash_size);
58689ed30d1SJens Wiklander if (res != TEE_SUCCESS)
58789ed30d1SJens Wiklander goto err;
58889ed30d1SJens Wiklander
58989ed30d1SJens Wiklander if (msg_len != hash_size) {
59089ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
59189ed30d1SJens Wiklander goto err;
59289ed30d1SJens Wiklander }
59389ed30d1SJens Wiklander }
59489ed30d1SJens Wiklander
59589ed30d1SJens Wiklander mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
59689ed30d1SJens Wiklander
59789ed30d1SJens Wiklander if (*sig_len < mod_size) {
59889ed30d1SJens Wiklander *sig_len = mod_size;
59989ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER;
60089ed30d1SJens Wiklander goto err;
60189ed30d1SJens Wiklander }
60289ed30d1SJens Wiklander
60389ed30d1SJens Wiklander ltc_sig_len = mod_size;
60489ed30d1SJens Wiklander
60589ed30d1SJens Wiklander ltc_res = rsa_sign_hash_ex(msg, msg_len, sig, <c_sig_len,
6061f3b1115SJens Wiklander ltc_rsa_algo, NULL, find_prng("prng_crypto"),
60789ed30d1SJens Wiklander ltc_hashindex, salt_len, <c_key);
60889ed30d1SJens Wiklander
60989ed30d1SJens Wiklander *sig_len = ltc_sig_len;
61089ed30d1SJens Wiklander
61189ed30d1SJens Wiklander if (ltc_res != CRYPT_OK) {
61289ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
61389ed30d1SJens Wiklander goto err;
61489ed30d1SJens Wiklander }
61589ed30d1SJens Wiklander res = TEE_SUCCESS;
61689ed30d1SJens Wiklander
61789ed30d1SJens Wiklander err:
61889ed30d1SJens Wiklander return res;
61989ed30d1SJens Wiklander }
62089ed30d1SJens Wiklander
62189ed30d1SJens Wiklander TEE_Result crypto_acipher_rsassa_verify(uint32_t algo,
62289ed30d1SJens Wiklander struct rsa_public_key *key,
62389ed30d1SJens Wiklander int salt_len, const uint8_t *msg,
62489ed30d1SJens Wiklander size_t msg_len, const uint8_t *sig,
62589ed30d1SJens Wiklander size_t sig_len)
626c2c27539SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsassa_verify");
627c2c27539SJorge Ramirez-Ortiz
sw_crypto_acipher_rsassa_verify(uint32_t algo,struct rsa_public_key * key,int salt_len,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)628c2c27539SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo,
629c2c27539SJorge Ramirez-Ortiz struct rsa_public_key *key,
630c2c27539SJorge Ramirez-Ortiz int salt_len, const uint8_t *msg,
631c2c27539SJorge Ramirez-Ortiz size_t msg_len, const uint8_t *sig,
632c2c27539SJorge Ramirez-Ortiz size_t sig_len)
63389ed30d1SJens Wiklander {
63489ed30d1SJens Wiklander TEE_Result res;
63589ed30d1SJens Wiklander uint32_t bigint_size;
63689ed30d1SJens Wiklander size_t hash_size;
63789ed30d1SJens Wiklander int stat, ltc_hashindex, ltc_res, ltc_rsa_algo;
63889ed30d1SJens Wiklander rsa_key ltc_key = {
63989ed30d1SJens Wiklander .type = PK_PUBLIC,
64089ed30d1SJens Wiklander .e = key->e,
64189ed30d1SJens Wiklander .N = key->n
64289ed30d1SJens Wiklander };
6438f6ac972SJens Wiklander struct ftmn ftmn = { };
6448f6ac972SJens Wiklander
6458f6ac972SJens Wiklander /*
6468f6ac972SJens Wiklander * The caller expects to call crypto_acipher_rsassa_verify(),
6478f6ac972SJens Wiklander * update the hash as needed.
6488f6ac972SJens Wiklander */
6498f6ac972SJens Wiklander FTMN_CALLEE_SWAP_HASH(FTMN_FUNC_HASH("crypto_acipher_rsassa_verify"));
65089ed30d1SJens Wiklander
65189ed30d1SJens Wiklander if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
6527c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
65389ed30d1SJens Wiklander &hash_size);
65489ed30d1SJens Wiklander if (res != TEE_SUCCESS)
65589ed30d1SJens Wiklander goto err;
65689ed30d1SJens Wiklander
65789ed30d1SJens Wiklander if (msg_len != hash_size) {
65889ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
65989ed30d1SJens Wiklander goto err;
66089ed30d1SJens Wiklander }
66189ed30d1SJens Wiklander }
66289ed30d1SJens Wiklander
66389ed30d1SJens Wiklander bigint_size = ltc_mp.unsigned_size(ltc_key.N);
66489ed30d1SJens Wiklander if (sig_len < bigint_size) {
66589ed30d1SJens Wiklander res = TEE_ERROR_SIGNATURE_INVALID;
66689ed30d1SJens Wiklander goto err;
66789ed30d1SJens Wiklander }
66889ed30d1SJens Wiklander
66989ed30d1SJens Wiklander /* Get the algorithm */
67089ed30d1SJens Wiklander if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
67189ed30d1SJens Wiklander res = tee_algo_to_ltc_hashindex(algo, <c_hashindex);
67289ed30d1SJens Wiklander if (res != TEE_SUCCESS)
67389ed30d1SJens Wiklander goto err;
67489ed30d1SJens Wiklander }
67589ed30d1SJens Wiklander
67689ed30d1SJens Wiklander switch (algo) {
67789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5:
67889ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1;
67989ed30d1SJens Wiklander break;
68089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
68189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
68289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
68389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
68489ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
68589ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
68689ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5;
68789ed30d1SJens Wiklander break;
688f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5:
68989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
69089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
69189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
69289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
69389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
69489ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_PSS;
69589ed30d1SJens Wiklander break;
69689ed30d1SJens Wiklander default:
69789ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
69889ed30d1SJens Wiklander goto err;
69989ed30d1SJens Wiklander }
70089ed30d1SJens Wiklander
7018f6ac972SJens Wiklander FTMN_PUSH_LINKED_CALL(&ftmn, FTMN_FUNC_HASH("rsa_verify_hash_ex"));
70289ed30d1SJens Wiklander ltc_res = rsa_verify_hash_ex(sig, sig_len, msg, msg_len, ltc_rsa_algo,
70389ed30d1SJens Wiklander ltc_hashindex, salt_len, &stat, <c_key);
70489ed30d1SJens Wiklander res = convert_ltc_verify_status(ltc_res, stat);
7058f6ac972SJens Wiklander if (res)
7068f6ac972SJens Wiklander FTMN_SET_CHECK_RES_NOT_ZERO(&ftmn, FTMN_INCR0, res);
7078f6ac972SJens Wiklander else
7088f6ac972SJens Wiklander FTMN_SET_CHECK_RES_FROM_CALL(&ftmn, FTMN_INCR0, 0);
7098f6ac972SJens Wiklander FTMN_POP_LINKED_CALL(&ftmn);
7108f6ac972SJens Wiklander FTMN_CALLEE_DONE_CHECK(&ftmn, FTMN_INCR0, FTMN_STEP_COUNT(1), res);
7118f6ac972SJens Wiklander return res;
71289ed30d1SJens Wiklander err:
7138f6ac972SJens Wiklander FTMN_CALLEE_DONE_NOT_ZERO(res);
71489ed30d1SJens Wiklander return res;
71589ed30d1SJens Wiklander }
716