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