189ed30d1SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 289ed30d1SJens Wiklander /* 389ed30d1SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited 489ed30d1SJens Wiklander */ 589ed30d1SJens Wiklander 689ed30d1SJens Wiklander #include <crypto/crypto.h> 789ed30d1SJens Wiklander #include <stdlib.h> 889ed30d1SJens Wiklander #include <string.h> 989ed30d1SJens Wiklander #include <tee_api_types.h> 1089ed30d1SJens Wiklander #include <tee_api_defines_extensions.h> 1189ed30d1SJens Wiklander #include <tee/tee_cryp_utl.h> 1289ed30d1SJens Wiklander #include <trace.h> 1389ed30d1SJens Wiklander #include <utee_defines.h> 1489ed30d1SJens Wiklander 1589ed30d1SJens Wiklander #include "acipher_helpers.h" 1689ed30d1SJens Wiklander 1789ed30d1SJens Wiklander 1889ed30d1SJens Wiklander /* 1989ed30d1SJens Wiklander * Compute the LibTomCrypt "hashindex" given a TEE Algorithm "algo" 2089ed30d1SJens Wiklander * Return 2189ed30d1SJens Wiklander * - TEE_SUCCESS in case of success, 2289ed30d1SJens Wiklander * - TEE_ERROR_BAD_PARAMETERS in case algo is not a valid algo 2389ed30d1SJens Wiklander * - TEE_ERROR_NOT_SUPPORTED in case algo is not supported by LTC 2489ed30d1SJens Wiklander * Return -1 in case of error 2589ed30d1SJens Wiklander */ 2689ed30d1SJens Wiklander static TEE_Result tee_algo_to_ltc_hashindex(uint32_t algo, int *ltc_hashindex) 2789ed30d1SJens Wiklander { 2889ed30d1SJens Wiklander switch (algo) { 29a1cbb728SJens Wiklander #if defined(_CFG_CORE_LTC_SHA1) 3089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 3189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 3289ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 3389ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha1"); 3489ed30d1SJens Wiklander break; 3589ed30d1SJens Wiklander #endif 36a1cbb728SJens Wiklander #if defined(_CFG_CORE_LTC_MD5) 3789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 3889ed30d1SJens Wiklander *ltc_hashindex = find_hash("md5"); 3989ed30d1SJens Wiklander break; 4089ed30d1SJens Wiklander #endif 41a1cbb728SJens Wiklander #if defined(_CFG_CORE_LTC_SHA224) 4289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 4389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 4489ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 4589ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha224"); 4689ed30d1SJens Wiklander break; 4789ed30d1SJens Wiklander #endif 48a1cbb728SJens Wiklander #if defined(_CFG_CORE_LTC_SHA256) 4989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 5089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 5189ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 5289ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha256"); 5389ed30d1SJens Wiklander break; 5489ed30d1SJens Wiklander #endif 55a1cbb728SJens Wiklander #if defined(_CFG_CORE_LTC_SHA384) 5689ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 5789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 5889ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 5989ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha384"); 6089ed30d1SJens Wiklander break; 6189ed30d1SJens Wiklander #endif 62a1cbb728SJens Wiklander #if defined(_CFG_CORE_LTC_SHA512) 6389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 6489ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 6589ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 6689ed30d1SJens Wiklander *ltc_hashindex = find_hash("sha512"); 6789ed30d1SJens Wiklander break; 6889ed30d1SJens Wiklander #endif 6989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5: 7089ed30d1SJens Wiklander case TEE_ALG_RSAES_PKCS1_V1_5: 7189ed30d1SJens Wiklander /* invalid one. but it should not be used anyway */ 7289ed30d1SJens Wiklander *ltc_hashindex = -1; 7389ed30d1SJens Wiklander return TEE_SUCCESS; 7489ed30d1SJens Wiklander 7589ed30d1SJens Wiklander default: 7689ed30d1SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 7789ed30d1SJens Wiklander } 7889ed30d1SJens Wiklander 7989ed30d1SJens Wiklander if (*ltc_hashindex < 0) 8089ed30d1SJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 8189ed30d1SJens Wiklander else 8289ed30d1SJens Wiklander return TEE_SUCCESS; 8389ed30d1SJens Wiklander } 8489ed30d1SJens Wiklander 8589ed30d1SJens Wiklander TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s, 8689ed30d1SJens Wiklander size_t key_size_bits __unused) 8789ed30d1SJens Wiklander { 8889ed30d1SJens Wiklander memset(s, 0, sizeof(*s)); 8989ed30d1SJens Wiklander if (!bn_alloc_max(&s->e)) 9089ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 9189ed30d1SJens Wiklander if (!bn_alloc_max(&s->d)) 9289ed30d1SJens Wiklander goto err; 9389ed30d1SJens Wiklander if (!bn_alloc_max(&s->n)) 9489ed30d1SJens Wiklander goto err; 9589ed30d1SJens Wiklander if (!bn_alloc_max(&s->p)) 9689ed30d1SJens Wiklander goto err; 9789ed30d1SJens Wiklander if (!bn_alloc_max(&s->q)) 9889ed30d1SJens Wiklander goto err; 9989ed30d1SJens Wiklander if (!bn_alloc_max(&s->qp)) 10089ed30d1SJens Wiklander goto err; 10189ed30d1SJens Wiklander if (!bn_alloc_max(&s->dp)) 10289ed30d1SJens Wiklander goto err; 10389ed30d1SJens Wiklander if (!bn_alloc_max(&s->dq)) 10489ed30d1SJens Wiklander goto err; 10589ed30d1SJens Wiklander 10689ed30d1SJens Wiklander return TEE_SUCCESS; 10789ed30d1SJens Wiklander err: 10889ed30d1SJens Wiklander crypto_bignum_free(s->e); 10989ed30d1SJens Wiklander crypto_bignum_free(s->d); 11089ed30d1SJens Wiklander crypto_bignum_free(s->n); 11189ed30d1SJens Wiklander crypto_bignum_free(s->p); 11289ed30d1SJens Wiklander crypto_bignum_free(s->q); 11389ed30d1SJens Wiklander crypto_bignum_free(s->qp); 11489ed30d1SJens Wiklander crypto_bignum_free(s->dp); 11589ed30d1SJens Wiklander 11689ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 11789ed30d1SJens Wiklander } 11889ed30d1SJens Wiklander 11989ed30d1SJens Wiklander TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s, 12089ed30d1SJens Wiklander size_t key_size_bits __unused) 12189ed30d1SJens Wiklander { 12289ed30d1SJens Wiklander memset(s, 0, sizeof(*s)); 12389ed30d1SJens Wiklander if (!bn_alloc_max(&s->e)) 12489ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 12589ed30d1SJens Wiklander if (!bn_alloc_max(&s->n)) 12689ed30d1SJens Wiklander goto err; 12789ed30d1SJens Wiklander return TEE_SUCCESS; 12889ed30d1SJens Wiklander err: 12989ed30d1SJens Wiklander crypto_bignum_free(s->e); 13089ed30d1SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 13189ed30d1SJens Wiklander } 13289ed30d1SJens Wiklander 13389ed30d1SJens Wiklander void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s) 13489ed30d1SJens Wiklander { 13589ed30d1SJens Wiklander if (!s) 13689ed30d1SJens Wiklander return; 13789ed30d1SJens Wiklander crypto_bignum_free(s->n); 13889ed30d1SJens Wiklander crypto_bignum_free(s->e); 13989ed30d1SJens Wiklander } 14089ed30d1SJens Wiklander 141*a1d5c81fSElias von Däniken void crypto_acipher_free_rsa_keypair(struct rsa_keypair *s) 142*a1d5c81fSElias von Däniken { 143*a1d5c81fSElias von Däniken if (!s) 144*a1d5c81fSElias von Däniken return; 145*a1d5c81fSElias von Däniken crypto_bignum_free(s->e); 146*a1d5c81fSElias von Däniken crypto_bignum_free(s->d); 147*a1d5c81fSElias von Däniken crypto_bignum_free(s->n); 148*a1d5c81fSElias von Däniken crypto_bignum_free(s->p); 149*a1d5c81fSElias von Däniken crypto_bignum_free(s->q); 150*a1d5c81fSElias von Däniken crypto_bignum_free(s->qp); 151*a1d5c81fSElias von Däniken crypto_bignum_free(s->dp); 152*a1d5c81fSElias von Däniken } 153*a1d5c81fSElias von Däniken 15489ed30d1SJens Wiklander TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key, size_t key_size) 15589ed30d1SJens Wiklander { 15689ed30d1SJens Wiklander TEE_Result res; 15789ed30d1SJens Wiklander rsa_key ltc_tmp_key; 15889ed30d1SJens Wiklander int ltc_res; 15989ed30d1SJens Wiklander long e; 16089ed30d1SJens Wiklander 16189ed30d1SJens Wiklander /* get the public exponent */ 16289ed30d1SJens Wiklander e = mp_get_int(key->e); 16389ed30d1SJens Wiklander 16489ed30d1SJens Wiklander /* Generate a temporary RSA key */ 1651f3b1115SJens Wiklander ltc_res = rsa_make_key(NULL, find_prng("prng_crypto"), key_size / 8, e, 16689ed30d1SJens Wiklander <c_tmp_key); 16789ed30d1SJens Wiklander if (ltc_res != CRYPT_OK) { 16889ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 16989ed30d1SJens Wiklander } else if ((size_t)mp_count_bits(ltc_tmp_key.N) != key_size) { 17089ed30d1SJens Wiklander rsa_free(<c_tmp_key); 17189ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 17289ed30d1SJens Wiklander } else { 17389ed30d1SJens Wiklander /* Copy the key */ 17489ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.e, key->e); 17589ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.d, key->d); 17689ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.N, key->n); 17789ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.p, key->p); 17889ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.q, key->q); 17989ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.qP, key->qp); 18089ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.dP, key->dp); 18189ed30d1SJens Wiklander ltc_mp.copy(ltc_tmp_key.dQ, key->dq); 18289ed30d1SJens Wiklander 18389ed30d1SJens Wiklander /* Free the temporary key */ 18489ed30d1SJens Wiklander rsa_free(<c_tmp_key); 18589ed30d1SJens Wiklander res = TEE_SUCCESS; 18689ed30d1SJens Wiklander } 18789ed30d1SJens Wiklander 18889ed30d1SJens Wiklander return res; 18989ed30d1SJens Wiklander } 19089ed30d1SJens Wiklander 19189ed30d1SJens Wiklander static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src, 19289ed30d1SJens Wiklander size_t src_len, uint8_t *dst, size_t *dst_len) 19389ed30d1SJens Wiklander { 19489ed30d1SJens Wiklander TEE_Result res = TEE_SUCCESS; 19589ed30d1SJens Wiklander uint8_t *buf = NULL; 19689ed30d1SJens Wiklander unsigned long blen, offset; 19789ed30d1SJens Wiklander int ltc_res; 19889ed30d1SJens Wiklander 19989ed30d1SJens Wiklander /* 20089ed30d1SJens Wiklander * Use a temporary buffer since we don't know exactly how large the 20189ed30d1SJens Wiklander * required size of the out buffer without doing a partial decrypt. 20289ed30d1SJens Wiklander * We know the upper bound though. 20389ed30d1SJens Wiklander */ 204a1cbb728SJens Wiklander blen = _CFG_CORE_LTC_BIGNUM_MAX_BITS / sizeof(uint8_t); 20589ed30d1SJens Wiklander buf = malloc(blen); 20689ed30d1SJens Wiklander if (!buf) { 20789ed30d1SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY; 20889ed30d1SJens Wiklander goto out; 20989ed30d1SJens Wiklander } 21089ed30d1SJens Wiklander 21189ed30d1SJens Wiklander ltc_res = rsa_exptmod(src, src_len, buf, &blen, ltc_key->type, 21289ed30d1SJens Wiklander ltc_key); 21389ed30d1SJens Wiklander switch (ltc_res) { 21489ed30d1SJens Wiklander case CRYPT_PK_NOT_PRIVATE: 21589ed30d1SJens Wiklander case CRYPT_PK_INVALID_TYPE: 21689ed30d1SJens Wiklander case CRYPT_PK_INVALID_SIZE: 21789ed30d1SJens Wiklander case CRYPT_INVALID_PACKET: 21889ed30d1SJens Wiklander EMSG("rsa_exptmod() returned %d", ltc_res); 21989ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 22089ed30d1SJens Wiklander goto out; 22189ed30d1SJens Wiklander case CRYPT_OK: 22289ed30d1SJens Wiklander break; 22389ed30d1SJens Wiklander default: 22489ed30d1SJens Wiklander /* This will result in a panic */ 22589ed30d1SJens Wiklander EMSG("rsa_exptmod() returned %d", ltc_res); 22689ed30d1SJens Wiklander res = TEE_ERROR_GENERIC; 22789ed30d1SJens Wiklander goto out; 22889ed30d1SJens Wiklander } 22989ed30d1SJens Wiklander 23089ed30d1SJens Wiklander /* Remove the zero-padding (leave one zero if buff is all zeroes) */ 23189ed30d1SJens Wiklander offset = 0; 23289ed30d1SJens Wiklander while ((offset < blen - 1) && (buf[offset] == 0)) 23389ed30d1SJens Wiklander offset++; 23489ed30d1SJens Wiklander 23589ed30d1SJens Wiklander if (*dst_len < blen - offset) { 23689ed30d1SJens Wiklander *dst_len = blen - offset; 23789ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 23889ed30d1SJens Wiklander goto out; 23989ed30d1SJens Wiklander } 24089ed30d1SJens Wiklander 24189ed30d1SJens Wiklander res = TEE_SUCCESS; 24289ed30d1SJens Wiklander *dst_len = blen - offset; 24389ed30d1SJens Wiklander memcpy(dst, (char *)buf + offset, *dst_len); 24489ed30d1SJens Wiklander 24589ed30d1SJens Wiklander out: 24689ed30d1SJens Wiklander if (buf) 24789ed30d1SJens Wiklander free(buf); 24889ed30d1SJens Wiklander 24989ed30d1SJens Wiklander return res; 25089ed30d1SJens Wiklander } 25189ed30d1SJens Wiklander 25289ed30d1SJens Wiklander TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key, 25389ed30d1SJens Wiklander const uint8_t *src, size_t src_len, 25489ed30d1SJens Wiklander uint8_t *dst, size_t *dst_len) 25589ed30d1SJens Wiklander { 25689ed30d1SJens Wiklander TEE_Result res; 25789ed30d1SJens Wiklander rsa_key ltc_key = { 0, }; 25889ed30d1SJens Wiklander 25989ed30d1SJens Wiklander ltc_key.type = PK_PUBLIC; 26089ed30d1SJens Wiklander ltc_key.e = key->e; 26189ed30d1SJens Wiklander ltc_key.N = key->n; 26289ed30d1SJens Wiklander 26389ed30d1SJens Wiklander res = rsadorep(<c_key, src, src_len, dst, dst_len); 26489ed30d1SJens Wiklander return res; 26589ed30d1SJens Wiklander } 26689ed30d1SJens Wiklander 26789ed30d1SJens Wiklander TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key, 26889ed30d1SJens Wiklander const uint8_t *src, size_t src_len, 26989ed30d1SJens Wiklander uint8_t *dst, size_t *dst_len) 27089ed30d1SJens Wiklander { 27189ed30d1SJens Wiklander TEE_Result res; 27289ed30d1SJens Wiklander rsa_key ltc_key = { 0, }; 27389ed30d1SJens Wiklander 27489ed30d1SJens Wiklander ltc_key.type = PK_PRIVATE; 27589ed30d1SJens Wiklander ltc_key.e = key->e; 27689ed30d1SJens Wiklander ltc_key.N = key->n; 27789ed30d1SJens Wiklander ltc_key.d = key->d; 27889ed30d1SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) { 27989ed30d1SJens Wiklander ltc_key.p = key->p; 28089ed30d1SJens Wiklander ltc_key.q = key->q; 28189ed30d1SJens Wiklander ltc_key.qP = key->qp; 28289ed30d1SJens Wiklander ltc_key.dP = key->dp; 28389ed30d1SJens Wiklander ltc_key.dQ = key->dq; 28489ed30d1SJens Wiklander } 28589ed30d1SJens Wiklander 28689ed30d1SJens Wiklander res = rsadorep(<c_key, src, src_len, dst, dst_len); 28789ed30d1SJens Wiklander return res; 28889ed30d1SJens Wiklander } 28989ed30d1SJens Wiklander 29089ed30d1SJens Wiklander TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, 29189ed30d1SJens Wiklander const uint8_t *label, size_t label_len, 29289ed30d1SJens Wiklander const uint8_t *src, size_t src_len, 29389ed30d1SJens Wiklander uint8_t *dst, size_t *dst_len) 29489ed30d1SJens Wiklander { 29589ed30d1SJens Wiklander TEE_Result res = TEE_SUCCESS; 29689ed30d1SJens Wiklander void *buf = NULL; 29789ed30d1SJens Wiklander unsigned long blen; 29889ed30d1SJens Wiklander int ltc_hashindex, ltc_res, ltc_stat, ltc_rsa_algo; 29989ed30d1SJens Wiklander size_t mod_size; 30089ed30d1SJens Wiklander rsa_key ltc_key = { 0, }; 30189ed30d1SJens Wiklander 30289ed30d1SJens Wiklander ltc_key.type = PK_PRIVATE; 30389ed30d1SJens Wiklander ltc_key.e = key->e; 30489ed30d1SJens Wiklander ltc_key.d = key->d; 30589ed30d1SJens Wiklander ltc_key.N = key->n; 30689ed30d1SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) { 30789ed30d1SJens Wiklander ltc_key.p = key->p; 30889ed30d1SJens Wiklander ltc_key.q = key->q; 30989ed30d1SJens Wiklander ltc_key.qP = key->qp; 31089ed30d1SJens Wiklander ltc_key.dP = key->dp; 31189ed30d1SJens Wiklander ltc_key.dQ = key->dq; 31289ed30d1SJens Wiklander } 31389ed30d1SJens Wiklander 31489ed30d1SJens Wiklander /* Get the algorithm */ 31589ed30d1SJens Wiklander res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); 31689ed30d1SJens Wiklander if (res != TEE_SUCCESS) { 31789ed30d1SJens Wiklander EMSG("tee_algo_to_ltc_hashindex() returned %d", (int)res); 31889ed30d1SJens Wiklander goto out; 31989ed30d1SJens Wiklander } 32089ed30d1SJens Wiklander 32189ed30d1SJens Wiklander /* 32289ed30d1SJens Wiklander * Use a temporary buffer since we don't know exactly how large 32389ed30d1SJens Wiklander * the required size of the out buffer without doing a partial 32489ed30d1SJens Wiklander * decrypt. We know the upper bound though. 32589ed30d1SJens Wiklander */ 32689ed30d1SJens Wiklander if (algo == TEE_ALG_RSAES_PKCS1_V1_5) { 32789ed30d1SJens Wiklander mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N)); 32889ed30d1SJens Wiklander blen = mod_size - 11; 32989ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5; 33089ed30d1SJens Wiklander } else { 33189ed30d1SJens Wiklander /* Decoded message is always shorter than encrypted message */ 33289ed30d1SJens Wiklander blen = src_len; 33389ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_OAEP; 33489ed30d1SJens Wiklander } 33589ed30d1SJens Wiklander 33689ed30d1SJens Wiklander buf = malloc(blen); 33789ed30d1SJens Wiklander if (!buf) { 33889ed30d1SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY; 33989ed30d1SJens Wiklander goto out; 34089ed30d1SJens Wiklander } 34189ed30d1SJens Wiklander 34289ed30d1SJens Wiklander ltc_res = rsa_decrypt_key_ex(src, src_len, buf, &blen, 34389ed30d1SJens Wiklander ((label_len == 0) ? 0 : label), label_len, 34489ed30d1SJens Wiklander ltc_hashindex, ltc_rsa_algo, <c_stat, 34589ed30d1SJens Wiklander <c_key); 34689ed30d1SJens Wiklander switch (ltc_res) { 34789ed30d1SJens Wiklander case CRYPT_PK_INVALID_PADDING: 34889ed30d1SJens Wiklander case CRYPT_INVALID_PACKET: 34989ed30d1SJens Wiklander case CRYPT_PK_INVALID_SIZE: 35089ed30d1SJens Wiklander EMSG("rsa_decrypt_key_ex() returned %d", ltc_res); 35189ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 35289ed30d1SJens Wiklander goto out; 35389ed30d1SJens Wiklander case CRYPT_OK: 35489ed30d1SJens Wiklander break; 35589ed30d1SJens Wiklander default: 35689ed30d1SJens Wiklander /* This will result in a panic */ 35789ed30d1SJens Wiklander EMSG("rsa_decrypt_key_ex() returned %d", ltc_res); 35889ed30d1SJens Wiklander res = TEE_ERROR_GENERIC; 35989ed30d1SJens Wiklander goto out; 36089ed30d1SJens Wiklander } 36189ed30d1SJens Wiklander if (ltc_stat != 1) { 36289ed30d1SJens Wiklander /* This will result in a panic */ 36389ed30d1SJens Wiklander EMSG("rsa_decrypt_key_ex() returned %d and %d", 36489ed30d1SJens Wiklander ltc_res, ltc_stat); 36589ed30d1SJens Wiklander res = TEE_ERROR_GENERIC; 36689ed30d1SJens Wiklander goto out; 36789ed30d1SJens Wiklander } 36889ed30d1SJens Wiklander 36989ed30d1SJens Wiklander if (*dst_len < blen) { 37089ed30d1SJens Wiklander *dst_len = blen; 37189ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 37289ed30d1SJens Wiklander goto out; 37389ed30d1SJens Wiklander } 37489ed30d1SJens Wiklander 37589ed30d1SJens Wiklander res = TEE_SUCCESS; 37689ed30d1SJens Wiklander *dst_len = blen; 37789ed30d1SJens Wiklander memcpy(dst, buf, blen); 37889ed30d1SJens Wiklander 37989ed30d1SJens Wiklander out: 38089ed30d1SJens Wiklander if (buf) 38189ed30d1SJens Wiklander free(buf); 38289ed30d1SJens Wiklander 38389ed30d1SJens Wiklander return res; 38489ed30d1SJens Wiklander } 38589ed30d1SJens Wiklander 38689ed30d1SJens Wiklander TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo, 38789ed30d1SJens Wiklander struct rsa_public_key *key, 38889ed30d1SJens Wiklander const uint8_t *label, size_t label_len, 38989ed30d1SJens Wiklander const uint8_t *src, size_t src_len, 39089ed30d1SJens Wiklander uint8_t *dst, size_t *dst_len) 39189ed30d1SJens Wiklander { 39289ed30d1SJens Wiklander TEE_Result res; 39389ed30d1SJens Wiklander uint32_t mod_size; 39489ed30d1SJens Wiklander int ltc_hashindex, ltc_res, ltc_rsa_algo; 39589ed30d1SJens Wiklander rsa_key ltc_key = { 39689ed30d1SJens Wiklander .type = PK_PUBLIC, 39789ed30d1SJens Wiklander .e = key->e, 39889ed30d1SJens Wiklander .N = key->n 39989ed30d1SJens Wiklander }; 40089ed30d1SJens Wiklander 40189ed30d1SJens Wiklander mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N)); 40289ed30d1SJens Wiklander if (*dst_len < mod_size) { 40389ed30d1SJens Wiklander *dst_len = mod_size; 40489ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 40589ed30d1SJens Wiklander goto out; 40689ed30d1SJens Wiklander } 40789ed30d1SJens Wiklander *dst_len = mod_size; 40889ed30d1SJens Wiklander 40989ed30d1SJens Wiklander /* Get the algorithm */ 41089ed30d1SJens Wiklander res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); 41189ed30d1SJens Wiklander if (res != TEE_SUCCESS) 41289ed30d1SJens Wiklander goto out; 41389ed30d1SJens Wiklander 41489ed30d1SJens Wiklander if (algo == TEE_ALG_RSAES_PKCS1_V1_5) 41589ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5; 41689ed30d1SJens Wiklander else 41789ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_OAEP; 41889ed30d1SJens Wiklander 41989ed30d1SJens Wiklander ltc_res = rsa_encrypt_key_ex(src, src_len, dst, 42089ed30d1SJens Wiklander (unsigned long *)(dst_len), label, 4211f3b1115SJens Wiklander label_len, NULL, find_prng("prng_crypto"), 42289ed30d1SJens Wiklander ltc_hashindex, ltc_rsa_algo, <c_key); 42389ed30d1SJens Wiklander switch (ltc_res) { 42489ed30d1SJens Wiklander case CRYPT_PK_INVALID_PADDING: 42589ed30d1SJens Wiklander case CRYPT_INVALID_PACKET: 42689ed30d1SJens Wiklander case CRYPT_PK_INVALID_SIZE: 42789ed30d1SJens Wiklander EMSG("rsa_encrypt_key_ex() returned %d", ltc_res); 42889ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 42989ed30d1SJens Wiklander goto out; 43089ed30d1SJens Wiklander case CRYPT_OK: 43189ed30d1SJens Wiklander break; 43289ed30d1SJens Wiklander default: 43389ed30d1SJens Wiklander /* This will result in a panic */ 43489ed30d1SJens Wiklander res = TEE_ERROR_GENERIC; 43589ed30d1SJens Wiklander goto out; 43689ed30d1SJens Wiklander } 43789ed30d1SJens Wiklander res = TEE_SUCCESS; 43889ed30d1SJens Wiklander 43989ed30d1SJens Wiklander out: 44089ed30d1SJens Wiklander return res; 44189ed30d1SJens Wiklander } 44289ed30d1SJens Wiklander 44389ed30d1SJens Wiklander TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, 44489ed30d1SJens Wiklander int salt_len, const uint8_t *msg, 44589ed30d1SJens Wiklander size_t msg_len, uint8_t *sig, 44689ed30d1SJens Wiklander size_t *sig_len) 44789ed30d1SJens Wiklander { 44889ed30d1SJens Wiklander TEE_Result res; 44989ed30d1SJens Wiklander size_t hash_size, mod_size; 45089ed30d1SJens Wiklander int ltc_res, ltc_rsa_algo, ltc_hashindex; 45189ed30d1SJens Wiklander unsigned long ltc_sig_len; 45289ed30d1SJens Wiklander rsa_key ltc_key = { 0, }; 45389ed30d1SJens Wiklander 45489ed30d1SJens Wiklander ltc_key.type = PK_PRIVATE; 45589ed30d1SJens Wiklander ltc_key.e = key->e; 45689ed30d1SJens Wiklander ltc_key.N = key->n; 45789ed30d1SJens Wiklander ltc_key.d = key->d; 45889ed30d1SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) { 45989ed30d1SJens Wiklander ltc_key.p = key->p; 46089ed30d1SJens Wiklander ltc_key.q = key->q; 46189ed30d1SJens Wiklander ltc_key.qP = key->qp; 46289ed30d1SJens Wiklander ltc_key.dP = key->dp; 46389ed30d1SJens Wiklander ltc_key.dQ = key->dq; 46489ed30d1SJens Wiklander } 46589ed30d1SJens Wiklander 46689ed30d1SJens Wiklander switch (algo) { 46789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5: 46889ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1; 46989ed30d1SJens Wiklander break; 47089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 47189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 47289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 47389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 47489ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 47589ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 47689ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5; 47789ed30d1SJens Wiklander break; 47889ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 47989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 48089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 48189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 48289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 48389ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_PSS; 48489ed30d1SJens Wiklander break; 48589ed30d1SJens Wiklander default: 48689ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 48789ed30d1SJens Wiklander goto err; 48889ed30d1SJens Wiklander } 48989ed30d1SJens Wiklander 49089ed30d1SJens Wiklander if (ltc_rsa_algo != LTC_PKCS_1_V1_5_NA1) { 49189ed30d1SJens Wiklander ltc_res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); 49289ed30d1SJens Wiklander if (ltc_res != CRYPT_OK) { 49389ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 49489ed30d1SJens Wiklander goto err; 49589ed30d1SJens Wiklander } 49689ed30d1SJens Wiklander 4977c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 49889ed30d1SJens Wiklander &hash_size); 49989ed30d1SJens Wiklander if (res != TEE_SUCCESS) 50089ed30d1SJens Wiklander goto err; 50189ed30d1SJens Wiklander 50289ed30d1SJens Wiklander if (msg_len != hash_size) { 50389ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 50489ed30d1SJens Wiklander goto err; 50589ed30d1SJens Wiklander } 50689ed30d1SJens Wiklander } 50789ed30d1SJens Wiklander 50889ed30d1SJens Wiklander mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N)); 50989ed30d1SJens Wiklander 51089ed30d1SJens Wiklander if (*sig_len < mod_size) { 51189ed30d1SJens Wiklander *sig_len = mod_size; 51289ed30d1SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 51389ed30d1SJens Wiklander goto err; 51489ed30d1SJens Wiklander } 51589ed30d1SJens Wiklander 51689ed30d1SJens Wiklander ltc_sig_len = mod_size; 51789ed30d1SJens Wiklander 51889ed30d1SJens Wiklander ltc_res = rsa_sign_hash_ex(msg, msg_len, sig, <c_sig_len, 5191f3b1115SJens Wiklander ltc_rsa_algo, NULL, find_prng("prng_crypto"), 52089ed30d1SJens Wiklander ltc_hashindex, salt_len, <c_key); 52189ed30d1SJens Wiklander 52289ed30d1SJens Wiklander *sig_len = ltc_sig_len; 52389ed30d1SJens Wiklander 52489ed30d1SJens Wiklander if (ltc_res != CRYPT_OK) { 52589ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 52689ed30d1SJens Wiklander goto err; 52789ed30d1SJens Wiklander } 52889ed30d1SJens Wiklander res = TEE_SUCCESS; 52989ed30d1SJens Wiklander 53089ed30d1SJens Wiklander err: 53189ed30d1SJens Wiklander return res; 53289ed30d1SJens Wiklander } 53389ed30d1SJens Wiklander 53489ed30d1SJens Wiklander TEE_Result crypto_acipher_rsassa_verify(uint32_t algo, 53589ed30d1SJens Wiklander struct rsa_public_key *key, 53689ed30d1SJens Wiklander int salt_len, const uint8_t *msg, 53789ed30d1SJens Wiklander size_t msg_len, const uint8_t *sig, 53889ed30d1SJens Wiklander size_t sig_len) 53989ed30d1SJens Wiklander { 54089ed30d1SJens Wiklander TEE_Result res; 54189ed30d1SJens Wiklander uint32_t bigint_size; 54289ed30d1SJens Wiklander size_t hash_size; 54389ed30d1SJens Wiklander int stat, ltc_hashindex, ltc_res, ltc_rsa_algo; 54489ed30d1SJens Wiklander rsa_key ltc_key = { 54589ed30d1SJens Wiklander .type = PK_PUBLIC, 54689ed30d1SJens Wiklander .e = key->e, 54789ed30d1SJens Wiklander .N = key->n 54889ed30d1SJens Wiklander }; 54989ed30d1SJens Wiklander 55089ed30d1SJens Wiklander if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) { 5517c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 55289ed30d1SJens Wiklander &hash_size); 55389ed30d1SJens Wiklander if (res != TEE_SUCCESS) 55489ed30d1SJens Wiklander goto err; 55589ed30d1SJens Wiklander 55689ed30d1SJens Wiklander if (msg_len != hash_size) { 55789ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 55889ed30d1SJens Wiklander goto err; 55989ed30d1SJens Wiklander } 56089ed30d1SJens Wiklander } 56189ed30d1SJens Wiklander 56289ed30d1SJens Wiklander bigint_size = ltc_mp.unsigned_size(ltc_key.N); 56389ed30d1SJens Wiklander if (sig_len < bigint_size) { 56489ed30d1SJens Wiklander res = TEE_ERROR_SIGNATURE_INVALID; 56589ed30d1SJens Wiklander goto err; 56689ed30d1SJens Wiklander } 56789ed30d1SJens Wiklander 56889ed30d1SJens Wiklander /* Get the algorithm */ 56989ed30d1SJens Wiklander if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) { 57089ed30d1SJens Wiklander res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); 57189ed30d1SJens Wiklander if (res != TEE_SUCCESS) 57289ed30d1SJens Wiklander goto err; 57389ed30d1SJens Wiklander } 57489ed30d1SJens Wiklander 57589ed30d1SJens Wiklander switch (algo) { 57689ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5: 57789ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1; 57889ed30d1SJens Wiklander break; 57989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 58089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 58189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 58289ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 58389ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 58489ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 58589ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_V1_5; 58689ed30d1SJens Wiklander break; 58789ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 58889ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 58989ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 59089ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 59189ed30d1SJens Wiklander case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 59289ed30d1SJens Wiklander ltc_rsa_algo = LTC_PKCS_1_PSS; 59389ed30d1SJens Wiklander break; 59489ed30d1SJens Wiklander default: 59589ed30d1SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 59689ed30d1SJens Wiklander goto err; 59789ed30d1SJens Wiklander } 59889ed30d1SJens Wiklander 59989ed30d1SJens Wiklander ltc_res = rsa_verify_hash_ex(sig, sig_len, msg, msg_len, ltc_rsa_algo, 60089ed30d1SJens Wiklander ltc_hashindex, salt_len, &stat, <c_key); 60189ed30d1SJens Wiklander res = convert_ltc_verify_status(ltc_res, stat); 60289ed30d1SJens Wiklander err: 60389ed30d1SJens Wiklander return res; 60489ed30d1SJens Wiklander } 605