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 <c_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(<c_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(<c_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(<c_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(<c_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, <c_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, <c_stat, 333*89ed30d1SJens Wiklander <c_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, <c_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, <c_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, <c_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, <c_sig_len, 507*89ed30d1SJens Wiklander ltc_rsa_algo, NULL, find_prng("prng_mpa"), 508*89ed30d1SJens Wiklander ltc_hashindex, salt_len, <c_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, <c_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, <c_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