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