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 <stdlib.h> 14f8907bbfSEdison Ai #include <string.h> 15f8907bbfSEdison Ai #include <tee/tee_cryp_utl.h> 16f8907bbfSEdison Ai #include <utee_defines.h> 1798ada65eSJens Wiklander #include <fault_mitigation.h> 18f8907bbfSEdison Ai 196630b846SJerome Forissier #include "mbed_helpers.h" 2032b31808SJens Wiklander #include "../mbedtls/library/pk_wrap.h" 2132b31808SJens Wiklander #include "../mbedtls/library/rsa_alt_helpers.h" 22f8907bbfSEdison Ai 23f8907bbfSEdison Ai static TEE_Result get_tee_result(int lmd_res) 24f8907bbfSEdison Ai { 25f8907bbfSEdison Ai switch (lmd_res) { 26f8907bbfSEdison Ai case 0: 27f8907bbfSEdison Ai return TEE_SUCCESS; 283ddd5cd7Sliushiwei case MBEDTLS_ERR_RSA_PRIVATE_FAILED + 293ddd5cd7Sliushiwei MBEDTLS_ERR_MPI_BAD_INPUT_DATA: 30f8907bbfSEdison Ai case MBEDTLS_ERR_RSA_BAD_INPUT_DATA: 31f8907bbfSEdison Ai case MBEDTLS_ERR_RSA_INVALID_PADDING: 32f8907bbfSEdison Ai case MBEDTLS_ERR_PK_TYPE_MISMATCH: 33f8907bbfSEdison Ai return TEE_ERROR_BAD_PARAMETERS; 34f8907bbfSEdison Ai case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE: 35f8907bbfSEdison Ai return TEE_ERROR_SHORT_BUFFER; 36f8907bbfSEdison Ai default: 37f8907bbfSEdison Ai return TEE_ERROR_BAD_STATE; 38f8907bbfSEdison Ai } 39f8907bbfSEdison Ai } 40f8907bbfSEdison Ai 41f8907bbfSEdison Ai static uint32_t tee_algo_to_mbedtls_hash_algo(uint32_t algo) 42f8907bbfSEdison Ai { 43f8907bbfSEdison Ai switch (algo) { 44f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA1) 45f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 46f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 47f8907bbfSEdison Ai case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 48f8907bbfSEdison Ai case TEE_ALG_SHA1: 49f8907bbfSEdison Ai case TEE_ALG_DSA_SHA1: 50f8907bbfSEdison Ai case TEE_ALG_HMAC_SHA1: 51f8907bbfSEdison Ai return MBEDTLS_MD_SHA1; 52f8907bbfSEdison Ai #endif 53f8907bbfSEdison Ai #if defined(CFG_CRYPTO_MD5) 54f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 55f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5: 56f5c3d85aSJulien Masson case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5: 57f8907bbfSEdison Ai case TEE_ALG_MD5: 58f8907bbfSEdison Ai case TEE_ALG_HMAC_MD5: 59f8907bbfSEdison Ai return MBEDTLS_MD_MD5; 60f8907bbfSEdison Ai #endif 61f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA224) 62f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 63f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 64f8907bbfSEdison Ai case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 65f8907bbfSEdison Ai case TEE_ALG_SHA224: 66f8907bbfSEdison Ai case TEE_ALG_DSA_SHA224: 67f8907bbfSEdison Ai case TEE_ALG_HMAC_SHA224: 68f8907bbfSEdison Ai return MBEDTLS_MD_SHA224; 69f8907bbfSEdison Ai #endif 70f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA256) 71f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 72f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 73f8907bbfSEdison Ai case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 74f8907bbfSEdison Ai case TEE_ALG_SHA256: 75f8907bbfSEdison Ai case TEE_ALG_DSA_SHA256: 76f8907bbfSEdison Ai case TEE_ALG_HMAC_SHA256: 77f8907bbfSEdison Ai return MBEDTLS_MD_SHA256; 78f8907bbfSEdison Ai #endif 79f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA384) 80f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 81f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 82f8907bbfSEdison Ai case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 83f8907bbfSEdison Ai case TEE_ALG_SHA384: 84f8907bbfSEdison Ai case TEE_ALG_HMAC_SHA384: 85f8907bbfSEdison Ai return MBEDTLS_MD_SHA384; 86f8907bbfSEdison Ai #endif 87f8907bbfSEdison Ai #if defined(CFG_CRYPTO_SHA512) 88f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 89f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 90f8907bbfSEdison Ai case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 91f8907bbfSEdison Ai case TEE_ALG_SHA512: 92f8907bbfSEdison Ai case TEE_ALG_HMAC_SHA512: 93f8907bbfSEdison Ai return MBEDTLS_MD_SHA512; 94f8907bbfSEdison Ai #endif 95f8907bbfSEdison Ai default: 96f8907bbfSEdison Ai return MBEDTLS_MD_NONE; 97f8907bbfSEdison Ai } 98f8907bbfSEdison Ai } 99f8907bbfSEdison Ai 10032b31808SJens Wiklander static TEE_Result rsa_init_and_complete_from_key_pair(mbedtls_rsa_context *rsa, 101f8907bbfSEdison Ai struct rsa_keypair *key) 102f8907bbfSEdison Ai { 10332b31808SJens Wiklander int lmd_res = 0; 10432b31808SJens Wiklander 10532b31808SJens Wiklander mbedtls_rsa_init(rsa); 106f8907bbfSEdison Ai 107f8907bbfSEdison Ai rsa->E = *(mbedtls_mpi *)key->e; 108f8907bbfSEdison Ai rsa->N = *(mbedtls_mpi *)key->n; 109f8907bbfSEdison Ai rsa->D = *(mbedtls_mpi *)key->d; 11032b31808SJens Wiklander rsa->len = mbedtls_mpi_size(&rsa->N); 11132b31808SJens Wiklander 112f8907bbfSEdison Ai if (key->p && crypto_bignum_num_bytes(key->p)) { 113f8907bbfSEdison Ai rsa->P = *(mbedtls_mpi *)key->p; 114f8907bbfSEdison Ai rsa->Q = *(mbedtls_mpi *)key->q; 115f8907bbfSEdison Ai rsa->QP = *(mbedtls_mpi *)key->qp; 116f8907bbfSEdison Ai rsa->DP = *(mbedtls_mpi *)key->dp; 117f8907bbfSEdison Ai rsa->DQ = *(mbedtls_mpi *)key->dq; 11832b31808SJens Wiklander } else { 11932b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->P); 12032b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->Q); 12132b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->QP); 12232b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->DP); 12332b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->DQ); 12432b31808SJens Wiklander 12532b31808SJens Wiklander lmd_res = mbedtls_rsa_deduce_primes(&rsa->N, &rsa->E, &rsa->D, 12632b31808SJens Wiklander &rsa->P, &rsa->Q); 12732b31808SJens Wiklander if (lmd_res) { 12832b31808SJens Wiklander DMSG("mbedtls_rsa_deduce_primes() returned 0x%x", 12932b31808SJens Wiklander -lmd_res); 13032b31808SJens Wiklander goto err; 131f8907bbfSEdison Ai } 132f8907bbfSEdison Ai 13332b31808SJens Wiklander lmd_res = mbedtls_rsa_deduce_crt(&rsa->P, &rsa->Q, &rsa->D, 13432b31808SJens Wiklander &rsa->DP, &rsa->DQ, &rsa->QP); 13532b31808SJens Wiklander if (lmd_res) { 13632b31808SJens Wiklander DMSG("mbedtls_rsa_deduce_crt() returned 0x%x", 13732b31808SJens Wiklander -lmd_res); 13832b31808SJens Wiklander goto err; 13932b31808SJens Wiklander } 14032b31808SJens Wiklander } 14132b31808SJens Wiklander 14232b31808SJens Wiklander return TEE_SUCCESS; 14332b31808SJens Wiklander err: 14432b31808SJens Wiklander mbedtls_mpi_free(&rsa->P); 14532b31808SJens Wiklander mbedtls_mpi_free(&rsa->Q); 14632b31808SJens Wiklander mbedtls_mpi_free(&rsa->QP); 14732b31808SJens Wiklander mbedtls_mpi_free(&rsa->DP); 14832b31808SJens Wiklander mbedtls_mpi_free(&rsa->DQ); 14932b31808SJens Wiklander 15032b31808SJens Wiklander return get_tee_result(lmd_res); 15132b31808SJens Wiklander } 15232b31808SJens Wiklander 15332b31808SJens Wiklander static void mbd_rsa_free(mbedtls_rsa_context *rsa, struct rsa_keypair *key) 154f8907bbfSEdison Ai { 15532b31808SJens Wiklander /* 15632b31808SJens Wiklander * The mpi's in @rsa are initialized from @key, but the primes and 15732b31808SJens Wiklander * CRT part are generated if @key doesn't have them. When freeing 15832b31808SJens Wiklander * we should only free the generated mpi's, the ones copied are 15932b31808SJens Wiklander * reset instead. 16032b31808SJens Wiklander */ 161f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->E); 162f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->N); 163f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->D); 16432b31808SJens Wiklander if (key->p && crypto_bignum_num_bytes(key->p)) { 165f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->P); 166f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->Q); 167f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->QP); 168f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->DP); 169f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->DQ); 170f8907bbfSEdison Ai } 171f8907bbfSEdison Ai mbedtls_rsa_free(rsa); 172f8907bbfSEdison Ai } 173f8907bbfSEdison Ai 174f8907bbfSEdison Ai TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s, 175f8907bbfSEdison Ai size_t key_size_bits) 176eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_alloc_rsa_keypair"); 177eac16613SJorge Ramirez-Ortiz 178eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s, 179eac16613SJorge Ramirez-Ortiz size_t key_size_bits) 180f8907bbfSEdison Ai { 181f8907bbfSEdison Ai memset(s, 0, sizeof(*s)); 182f8907bbfSEdison Ai s->e = crypto_bignum_allocate(key_size_bits); 183f8907bbfSEdison Ai if (!s->e) 184f8907bbfSEdison Ai goto err; 185f8907bbfSEdison Ai s->d = crypto_bignum_allocate(key_size_bits); 186f8907bbfSEdison Ai if (!s->d) 187f8907bbfSEdison Ai goto err; 188f8907bbfSEdison Ai s->n = crypto_bignum_allocate(key_size_bits); 189f8907bbfSEdison Ai if (!s->n) 190f8907bbfSEdison Ai goto err; 191f8907bbfSEdison Ai s->p = crypto_bignum_allocate(key_size_bits); 192f8907bbfSEdison Ai if (!s->p) 193f8907bbfSEdison Ai goto err; 194f8907bbfSEdison Ai s->q = crypto_bignum_allocate(key_size_bits); 195f8907bbfSEdison Ai if (!s->q) 196f8907bbfSEdison Ai goto err; 197f8907bbfSEdison Ai s->qp = crypto_bignum_allocate(key_size_bits); 198f8907bbfSEdison Ai if (!s->qp) 199f8907bbfSEdison Ai goto err; 200f8907bbfSEdison Ai s->dp = crypto_bignum_allocate(key_size_bits); 201f8907bbfSEdison Ai if (!s->dp) 202f8907bbfSEdison Ai goto err; 203f8907bbfSEdison Ai s->dq = crypto_bignum_allocate(key_size_bits); 204f8907bbfSEdison Ai if (!s->dq) 205f8907bbfSEdison Ai goto err; 206f8907bbfSEdison Ai 207f8907bbfSEdison Ai return TEE_SUCCESS; 208f8907bbfSEdison Ai err: 2091ab1ebd8SJerome Forissier crypto_acipher_free_rsa_keypair(s); 210f8907bbfSEdison Ai return TEE_ERROR_OUT_OF_MEMORY; 211f8907bbfSEdison Ai } 212f8907bbfSEdison Ai 213f8907bbfSEdison Ai TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s, 214f8907bbfSEdison Ai size_t key_size_bits) 215eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_alloc_rsa_public_key"); 216eac16613SJorge Ramirez-Ortiz 217eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s, 218eac16613SJorge Ramirez-Ortiz size_t key_size_bits) 219f8907bbfSEdison Ai { 220f8907bbfSEdison Ai memset(s, 0, sizeof(*s)); 221f8907bbfSEdison Ai s->e = crypto_bignum_allocate(key_size_bits); 222f8907bbfSEdison Ai if (!s->e) 223f8907bbfSEdison Ai return TEE_ERROR_OUT_OF_MEMORY; 224f8907bbfSEdison Ai s->n = crypto_bignum_allocate(key_size_bits); 225f8907bbfSEdison Ai if (!s->n) 226f8907bbfSEdison Ai goto err; 227f8907bbfSEdison Ai return TEE_SUCCESS; 228f8907bbfSEdison Ai err: 229e2ec831cSJihwan Park crypto_bignum_free(&s->e); 230f8907bbfSEdison Ai return TEE_ERROR_OUT_OF_MEMORY; 231f8907bbfSEdison Ai } 232f8907bbfSEdison Ai 233f8907bbfSEdison Ai void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s) 234eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_free_rsa_public_key"); 235eac16613SJorge Ramirez-Ortiz 236eac16613SJorge Ramirez-Ortiz void sw_crypto_acipher_free_rsa_public_key(struct rsa_public_key *s) 237f8907bbfSEdison Ai { 238f8907bbfSEdison Ai if (!s) 239f8907bbfSEdison Ai return; 240e2ec831cSJihwan Park crypto_bignum_free(&s->n); 241e2ec831cSJihwan Park crypto_bignum_free(&s->e); 242f8907bbfSEdison Ai } 243f8907bbfSEdison Ai 244a1d5c81fSElias von Däniken void crypto_acipher_free_rsa_keypair(struct rsa_keypair *s) 245eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_free_rsa_keypair"); 246eac16613SJorge Ramirez-Ortiz 247eac16613SJorge Ramirez-Ortiz void sw_crypto_acipher_free_rsa_keypair(struct rsa_keypair *s) 248a1d5c81fSElias von Däniken { 249a1d5c81fSElias von Däniken if (!s) 250a1d5c81fSElias von Däniken return; 251e2ec831cSJihwan Park crypto_bignum_free(&s->e); 252e2ec831cSJihwan Park crypto_bignum_free(&s->d); 253e2ec831cSJihwan Park crypto_bignum_free(&s->n); 254e2ec831cSJihwan Park crypto_bignum_free(&s->p); 255e2ec831cSJihwan Park crypto_bignum_free(&s->q); 256e2ec831cSJihwan Park crypto_bignum_free(&s->qp); 257e2ec831cSJihwan Park crypto_bignum_free(&s->dp); 258e2ec831cSJihwan Park crypto_bignum_free(&s->dq); 259a1d5c81fSElias von Däniken } 260a1d5c81fSElias von Däniken 261eac16613SJorge Ramirez-Ortiz TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key, 262eac16613SJorge Ramirez-Ortiz size_t key_size) 263eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_gen_rsa_key"); 264eac16613SJorge Ramirez-Ortiz 265eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_gen_rsa_key(struct rsa_keypair *key, 266eac16613SJorge Ramirez-Ortiz size_t key_size) 267f8907bbfSEdison Ai { 268f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 269f8907bbfSEdison Ai mbedtls_rsa_context rsa; 2707910f4d8SLars Persson mbedtls_ctr_drbg_context rngctx; 271f8907bbfSEdison Ai int lmd_res = 0; 272f8907bbfSEdison Ai uint32_t e = 0; 273f8907bbfSEdison Ai 2747910f4d8SLars Persson mbedtls_ctr_drbg_init(&rngctx); 2757910f4d8SLars Persson if (mbedtls_ctr_drbg_seed(&rngctx, mbd_rand, NULL, NULL, 0)) 2767910f4d8SLars Persson return TEE_ERROR_BAD_STATE; 2777910f4d8SLars Persson 278f8907bbfSEdison Ai memset(&rsa, 0, sizeof(rsa)); 27932b31808SJens Wiklander mbedtls_rsa_init(&rsa); 280f8907bbfSEdison Ai 281f8907bbfSEdison Ai /* get the public exponent */ 282f8907bbfSEdison Ai mbedtls_mpi_write_binary((mbedtls_mpi *)key->e, 283f8907bbfSEdison Ai (unsigned char *)&e, sizeof(uint32_t)); 284f8907bbfSEdison Ai 285f8907bbfSEdison Ai e = TEE_U32_FROM_BIG_ENDIAN(e); 2867910f4d8SLars Persson lmd_res = mbedtls_rsa_gen_key(&rsa, mbedtls_ctr_drbg_random, &rngctx, 2877910f4d8SLars Persson key_size, (int)e); 2887910f4d8SLars Persson mbedtls_ctr_drbg_free(&rngctx); 289f8907bbfSEdison Ai if (lmd_res != 0) { 290f8907bbfSEdison Ai res = get_tee_result(lmd_res); 291f8907bbfSEdison Ai } else if ((size_t)mbedtls_mpi_bitlen(&rsa.N) != key_size) { 292f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 293f8907bbfSEdison Ai } else { 294f8907bbfSEdison Ai /* Copy the key */ 295f8907bbfSEdison Ai crypto_bignum_copy(key->e, (void *)&rsa.E); 296f8907bbfSEdison Ai crypto_bignum_copy(key->d, (void *)&rsa.D); 297f8907bbfSEdison Ai crypto_bignum_copy(key->n, (void *)&rsa.N); 298f8907bbfSEdison Ai crypto_bignum_copy(key->p, (void *)&rsa.P); 299f8907bbfSEdison Ai 300f8907bbfSEdison Ai crypto_bignum_copy(key->q, (void *)&rsa.Q); 301f8907bbfSEdison Ai crypto_bignum_copy(key->qp, (void *)&rsa.QP); 302f8907bbfSEdison Ai crypto_bignum_copy(key->dp, (void *)&rsa.DP); 303f8907bbfSEdison Ai crypto_bignum_copy(key->dq, (void *)&rsa.DQ); 304f8907bbfSEdison Ai 305f8907bbfSEdison Ai res = TEE_SUCCESS; 306f8907bbfSEdison Ai } 307f8907bbfSEdison Ai 308f8907bbfSEdison Ai mbedtls_rsa_free(&rsa); 309f8907bbfSEdison Ai 310f8907bbfSEdison Ai return res; 311f8907bbfSEdison Ai } 312f8907bbfSEdison Ai 313f8907bbfSEdison Ai TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key, 314eac16613SJorge Ramirez-Ortiz const uint8_t *src, 315eac16613SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst, 316eac16613SJorge Ramirez-Ortiz size_t *dst_len) 317eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsanopad_encrypt"); 318eac16613SJorge Ramirez-Ortiz 319eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key, 320eac16613SJorge Ramirez-Ortiz const uint8_t *src, 321eac16613SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst, 322eac16613SJorge Ramirez-Ortiz size_t *dst_len) 323f8907bbfSEdison Ai { 324f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 325f8907bbfSEdison Ai mbedtls_rsa_context rsa; 326f8907bbfSEdison Ai int lmd_res = 0; 327f8907bbfSEdison Ai uint8_t *buf = NULL; 328f8907bbfSEdison Ai unsigned long blen = 0; 329f8907bbfSEdison Ai unsigned long offset = 0; 330f8907bbfSEdison Ai 331f8907bbfSEdison Ai memset(&rsa, 0, sizeof(rsa)); 33232b31808SJens Wiklander mbedtls_rsa_init(&rsa); 333f8907bbfSEdison Ai 334f8907bbfSEdison Ai rsa.E = *(mbedtls_mpi *)key->e; 335f8907bbfSEdison Ai rsa.N = *(mbedtls_mpi *)key->n; 336f8907bbfSEdison Ai 337f8907bbfSEdison Ai rsa.len = crypto_bignum_num_bytes((void *)&rsa.N); 338f8907bbfSEdison Ai 339f8907bbfSEdison Ai blen = CFG_CORE_BIGNUM_MAX_BITS / 8; 340f8907bbfSEdison Ai buf = malloc(blen); 341f8907bbfSEdison Ai if (!buf) { 342f8907bbfSEdison Ai res = TEE_ERROR_OUT_OF_MEMORY; 343f8907bbfSEdison Ai goto out; 344f8907bbfSEdison Ai } 345f8907bbfSEdison Ai 346f8907bbfSEdison Ai memset(buf, 0, blen); 347f8907bbfSEdison Ai memcpy(buf + rsa.len - src_len, src, src_len); 348f8907bbfSEdison Ai 349f8907bbfSEdison Ai lmd_res = mbedtls_rsa_public(&rsa, buf, buf); 350f8907bbfSEdison Ai if (lmd_res != 0) { 351f8907bbfSEdison Ai FMSG("mbedtls_rsa_public() returned 0x%x", -lmd_res); 352f8907bbfSEdison Ai res = get_tee_result(lmd_res); 353f8907bbfSEdison Ai goto out; 354f8907bbfSEdison Ai } 355f8907bbfSEdison Ai 356f8907bbfSEdison Ai /* Remove the zero-padding (leave one zero if buff is all zeroes) */ 357f8907bbfSEdison Ai offset = 0; 358f8907bbfSEdison Ai while ((offset < rsa.len - 1) && (buf[offset] == 0)) 359f8907bbfSEdison Ai offset++; 360f8907bbfSEdison Ai 361f8907bbfSEdison Ai if (*dst_len < rsa.len - offset) { 362f8907bbfSEdison Ai *dst_len = rsa.len - offset; 363f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 364f8907bbfSEdison Ai goto out; 365f8907bbfSEdison Ai } 366f8907bbfSEdison Ai *dst_len = rsa.len - offset; 367f8907bbfSEdison Ai memcpy(dst, buf + offset, *dst_len); 368f8907bbfSEdison Ai out: 369f8907bbfSEdison Ai free(buf); 370f8907bbfSEdison Ai /* Reset mpi to skip freeing here, those mpis will be freed with key */ 371f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.E); 372f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.N); 373f8907bbfSEdison Ai mbedtls_rsa_free(&rsa); 374f8907bbfSEdison Ai 375f8907bbfSEdison Ai return res; 376f8907bbfSEdison Ai } 377f8907bbfSEdison Ai 378f8907bbfSEdison Ai TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key, 379eac16613SJorge Ramirez-Ortiz const uint8_t *src, 380eac16613SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst, 381eac16613SJorge Ramirez-Ortiz size_t *dst_len) 382eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsanopad_decrypt"); 383eac16613SJorge Ramirez-Ortiz 384eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key, 385eac16613SJorge Ramirez-Ortiz const uint8_t *src, 386eac16613SJorge Ramirez-Ortiz size_t src_len, uint8_t *dst, 387eac16613SJorge Ramirez-Ortiz size_t *dst_len) 388f8907bbfSEdison Ai { 389f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 39032b31808SJens Wiklander mbedtls_rsa_context rsa = { }; 391f8907bbfSEdison Ai int lmd_res = 0; 392f8907bbfSEdison Ai uint8_t *buf = NULL; 393f8907bbfSEdison Ai unsigned long blen = 0; 394f8907bbfSEdison Ai unsigned long offset = 0; 395f8907bbfSEdison Ai 39632b31808SJens Wiklander res = rsa_init_and_complete_from_key_pair(&rsa, key); 39732b31808SJens Wiklander if (res) 39832b31808SJens Wiklander return res; 399f8907bbfSEdison Ai 400f8907bbfSEdison Ai blen = CFG_CORE_BIGNUM_MAX_BITS / 8; 401f8907bbfSEdison Ai buf = malloc(blen); 402f8907bbfSEdison Ai if (!buf) { 403f8907bbfSEdison Ai res = TEE_ERROR_OUT_OF_MEMORY; 404f8907bbfSEdison Ai goto out; 405f8907bbfSEdison Ai } 406f8907bbfSEdison Ai 407f8907bbfSEdison Ai memset(buf, 0, blen); 408f8907bbfSEdison Ai memcpy(buf + rsa.len - src_len, src, src_len); 409f8907bbfSEdison Ai 41032b31808SJens Wiklander lmd_res = mbedtls_rsa_private(&rsa, mbd_rand, NULL, buf, buf); 411f8907bbfSEdison Ai if (lmd_res != 0) { 412f8907bbfSEdison Ai FMSG("mbedtls_rsa_private() returned 0x%x", -lmd_res); 413f8907bbfSEdison Ai res = get_tee_result(lmd_res); 414f8907bbfSEdison Ai goto out; 415f8907bbfSEdison Ai } 416f8907bbfSEdison Ai 417f8907bbfSEdison Ai /* Remove the zero-padding (leave one zero if buff is all zeroes) */ 418f8907bbfSEdison Ai offset = 0; 419f8907bbfSEdison Ai while ((offset < rsa.len - 1) && (buf[offset] == 0)) 420f8907bbfSEdison Ai offset++; 421f8907bbfSEdison Ai 422f8907bbfSEdison Ai if (*dst_len < rsa.len - offset) { 423f8907bbfSEdison Ai *dst_len = rsa.len - offset; 424f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 425f8907bbfSEdison Ai goto out; 426f8907bbfSEdison Ai } 427f8907bbfSEdison Ai *dst_len = rsa.len - offset; 428f8907bbfSEdison Ai memcpy(dst, (char *)buf + offset, *dst_len); 429f8907bbfSEdison Ai out: 430f8907bbfSEdison Ai if (buf) 431f8907bbfSEdison Ai free(buf); 43232b31808SJens Wiklander mbd_rsa_free(&rsa, key); 433f8907bbfSEdison Ai return res; 434f8907bbfSEdison Ai } 435f8907bbfSEdison Ai 436eac16613SJorge Ramirez-Ortiz TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, 437eac16613SJorge Ramirez-Ortiz struct rsa_keypair *key, 438eac16613SJorge Ramirez-Ortiz const uint8_t *label __unused, 439eac16613SJorge Ramirez-Ortiz size_t label_len __unused, 440*86ee543bSSami Tolvanen uint32_t mgf_algo, 441eac16613SJorge Ramirez-Ortiz const uint8_t *src, size_t src_len, 442eac16613SJorge Ramirez-Ortiz uint8_t *dst, size_t *dst_len) 443eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsaes_decrypt"); 444eac16613SJorge Ramirez-Ortiz 445eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo, 446eac16613SJorge Ramirez-Ortiz struct rsa_keypair *key, 447f8907bbfSEdison Ai const uint8_t *label __unused, 448f8907bbfSEdison Ai size_t label_len __unused, 449*86ee543bSSami Tolvanen uint32_t mgf_algo, 450f8907bbfSEdison Ai const uint8_t *src, size_t src_len, 451f8907bbfSEdison Ai uint8_t *dst, size_t *dst_len) 452f8907bbfSEdison Ai { 453f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 454f8907bbfSEdison Ai int lmd_res = 0; 455f8907bbfSEdison Ai int lmd_padding = 0; 456f8907bbfSEdison Ai size_t blen = 0; 457f8907bbfSEdison Ai size_t mod_size = 0; 458f8907bbfSEdison Ai void *buf = NULL; 45932b31808SJens Wiklander mbedtls_rsa_context rsa = { }; 460f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 461f8907bbfSEdison Ai uint32_t md_algo = MBEDTLS_MD_NONE; 462f8907bbfSEdison Ai 46332b31808SJens Wiklander res = rsa_init_and_complete_from_key_pair(&rsa, key); 46432b31808SJens Wiklander if (res) 46532b31808SJens Wiklander return res; 466f8907bbfSEdison Ai 467f8907bbfSEdison Ai /* 468f8907bbfSEdison Ai * Use a temporary buffer since we don't know exactly how large 469f8907bbfSEdison Ai * the required size of the out buffer without doing a partial 470f8907bbfSEdison Ai * decrypt. We know the upper bound though. 471f8907bbfSEdison Ai */ 472f8907bbfSEdison Ai if (algo == TEE_ALG_RSAES_PKCS1_V1_5) { 473f8907bbfSEdison Ai mod_size = crypto_bignum_num_bytes(key->n); 474f8907bbfSEdison Ai blen = mod_size - 11; 475f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 476f8907bbfSEdison Ai } else { 477f8907bbfSEdison Ai /* Decoded message is always shorter than encrypted message */ 478f8907bbfSEdison Ai blen = src_len; 479f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 480f8907bbfSEdison Ai } 481f8907bbfSEdison Ai 482f8907bbfSEdison Ai buf = malloc(blen); 483f8907bbfSEdison Ai if (!buf) { 484f8907bbfSEdison Ai res = TEE_ERROR_OUT_OF_MEMORY; 485f8907bbfSEdison Ai goto out; 486f8907bbfSEdison Ai } 487f8907bbfSEdison Ai 488f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 489f8907bbfSEdison Ai if (!pk_info) { 490f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 491f8907bbfSEdison Ai goto out; 492f8907bbfSEdison Ai } 493f8907bbfSEdison Ai 494f8907bbfSEdison Ai /* 495f8907bbfSEdison Ai * TEE_ALG_RSAES_PKCS1_V1_5 is invalid in hash. But its hash algo will 496f8907bbfSEdison Ai * not be used in rsa, so skip it here. 497f8907bbfSEdison Ai */ 498f8907bbfSEdison Ai if (algo != TEE_ALG_RSAES_PKCS1_V1_5) { 499f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 500f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 501f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 502f8907bbfSEdison Ai goto out; 503f8907bbfSEdison Ai } 504*86ee543bSSami Tolvanen if (md_algo != tee_algo_to_mbedtls_hash_algo(mgf_algo)) { 505*86ee543bSSami Tolvanen DMSG("Using a different MGF1 algorithm is not supported"); 506*86ee543bSSami Tolvanen res = TEE_ERROR_NOT_SUPPORTED; 507*86ee543bSSami Tolvanen goto out; 508*86ee543bSSami Tolvanen } 509f8907bbfSEdison Ai } 510f8907bbfSEdison Ai 511f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 512f8907bbfSEdison Ai 513f8907bbfSEdison Ai lmd_res = pk_info->decrypt_func(&rsa, src, src_len, buf, &blen, 514f8907bbfSEdison Ai blen, mbd_rand, NULL); 515f8907bbfSEdison Ai if (lmd_res != 0) { 516f8907bbfSEdison Ai FMSG("decrypt_func() returned 0x%x", -lmd_res); 517f8907bbfSEdison Ai res = get_tee_result(lmd_res); 518f8907bbfSEdison Ai goto out; 519f8907bbfSEdison Ai } 520f8907bbfSEdison Ai 521f8907bbfSEdison Ai if (*dst_len < blen) { 522f8907bbfSEdison Ai *dst_len = blen; 523f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 524f8907bbfSEdison Ai goto out; 525f8907bbfSEdison Ai } 526f8907bbfSEdison Ai 527f8907bbfSEdison Ai res = TEE_SUCCESS; 528f8907bbfSEdison Ai *dst_len = blen; 529f8907bbfSEdison Ai memcpy(dst, buf, blen); 530f8907bbfSEdison Ai out: 531f8907bbfSEdison Ai if (buf) 532f8907bbfSEdison Ai free(buf); 53332b31808SJens Wiklander mbd_rsa_free(&rsa, key); 534f8907bbfSEdison Ai return res; 535f8907bbfSEdison Ai } 536f8907bbfSEdison Ai 537f8907bbfSEdison Ai TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo, 538f8907bbfSEdison Ai struct rsa_public_key *key, 539f8907bbfSEdison Ai const uint8_t *label __unused, 540f8907bbfSEdison Ai size_t label_len __unused, 541*86ee543bSSami Tolvanen uint32_t mgf_algo, 542f8907bbfSEdison Ai const uint8_t *src, size_t src_len, 543f8907bbfSEdison Ai uint8_t *dst, size_t *dst_len) 544eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsaes_encrypt"); 545eac16613SJorge Ramirez-Ortiz 546eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo, 547eac16613SJorge Ramirez-Ortiz struct rsa_public_key *key, 548eac16613SJorge Ramirez-Ortiz const uint8_t *label __unused, 549eac16613SJorge Ramirez-Ortiz size_t label_len __unused, 550*86ee543bSSami Tolvanen uint32_t mgf_algo, 551eac16613SJorge Ramirez-Ortiz const uint8_t *src, size_t src_len, 552eac16613SJorge Ramirez-Ortiz uint8_t *dst, size_t *dst_len) 553f8907bbfSEdison Ai { 554f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 555f8907bbfSEdison Ai int lmd_res = 0; 556f8907bbfSEdison Ai int lmd_padding = 0; 557f8907bbfSEdison Ai size_t mod_size = 0; 558f8907bbfSEdison Ai mbedtls_rsa_context rsa; 559f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 560f8907bbfSEdison Ai uint32_t md_algo = MBEDTLS_MD_NONE; 561f8907bbfSEdison Ai 562f8907bbfSEdison Ai memset(&rsa, 0, sizeof(rsa)); 56332b31808SJens Wiklander mbedtls_rsa_init(&rsa); 564f8907bbfSEdison Ai 565f8907bbfSEdison Ai rsa.E = *(mbedtls_mpi *)key->e; 566f8907bbfSEdison Ai rsa.N = *(mbedtls_mpi *)key->n; 567f8907bbfSEdison Ai 568f8907bbfSEdison Ai mod_size = crypto_bignum_num_bytes(key->n); 569f8907bbfSEdison Ai if (*dst_len < mod_size) { 570f8907bbfSEdison Ai *dst_len = mod_size; 571f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 572f8907bbfSEdison Ai goto out; 573f8907bbfSEdison Ai } 574f8907bbfSEdison Ai *dst_len = mod_size; 575f8907bbfSEdison Ai rsa.len = mod_size; 576f8907bbfSEdison Ai 577f8907bbfSEdison Ai if (algo == TEE_ALG_RSAES_PKCS1_V1_5) 578f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 579f8907bbfSEdison Ai else 580f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 581f8907bbfSEdison Ai 582f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 583f8907bbfSEdison Ai if (!pk_info) { 584f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 585f8907bbfSEdison Ai goto out; 586f8907bbfSEdison Ai } 587f8907bbfSEdison Ai 588f8907bbfSEdison Ai /* 589f8907bbfSEdison Ai * TEE_ALG_RSAES_PKCS1_V1_5 is invalid in hash. But its hash algo will 590f8907bbfSEdison Ai * not be used in rsa, so skip it here. 591f8907bbfSEdison Ai */ 592f8907bbfSEdison Ai if (algo != TEE_ALG_RSAES_PKCS1_V1_5) { 593f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 594*86ee543bSSami Tolvanen /* Using a different MGF1 algorithm is not supported. */ 595*86ee543bSSami Tolvanen if (md_algo == MBEDTLS_MD_NONE || 596*86ee543bSSami Tolvanen md_algo != tee_algo_to_mbedtls_hash_algo(mgf_algo)) { 597f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 598f8907bbfSEdison Ai goto out; 599f8907bbfSEdison Ai } 600f8907bbfSEdison Ai } 601f8907bbfSEdison Ai 602f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 603f8907bbfSEdison Ai 604f8907bbfSEdison Ai lmd_res = pk_info->encrypt_func(&rsa, src, src_len, dst, dst_len, 605f8907bbfSEdison Ai *dst_len, mbd_rand, NULL); 606f8907bbfSEdison Ai if (lmd_res != 0) { 607f8907bbfSEdison Ai FMSG("encrypt_func() returned 0x%x", -lmd_res); 608f8907bbfSEdison Ai res = get_tee_result(lmd_res); 609f8907bbfSEdison Ai goto out; 610f8907bbfSEdison Ai } 611f8907bbfSEdison Ai res = TEE_SUCCESS; 612f8907bbfSEdison Ai out: 613f8907bbfSEdison Ai /* Reset mpi to skip freeing here, those mpis will be freed with key */ 614f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.E); 615f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.N); 616f8907bbfSEdison Ai mbedtls_rsa_free(&rsa); 617f8907bbfSEdison Ai return res; 618f8907bbfSEdison Ai } 619f8907bbfSEdison Ai 620f8907bbfSEdison Ai TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, 621eac16613SJorge Ramirez-Ortiz int salt_len __unused, 622eac16613SJorge Ramirez-Ortiz const uint8_t *msg, size_t msg_len, 623eac16613SJorge Ramirez-Ortiz uint8_t *sig, size_t *sig_len) 624eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsassa_sign"); 625eac16613SJorge Ramirez-Ortiz 626eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, 627eac16613SJorge Ramirez-Ortiz int salt_len __unused, 628eac16613SJorge Ramirez-Ortiz const uint8_t *msg, size_t msg_len, 629eac16613SJorge Ramirez-Ortiz uint8_t *sig, size_t *sig_len) 630f8907bbfSEdison Ai { 631f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 632f8907bbfSEdison Ai int lmd_res = 0; 633f8907bbfSEdison Ai int lmd_padding = 0; 634f8907bbfSEdison Ai size_t mod_size = 0; 635f8907bbfSEdison Ai size_t hash_size = 0; 63632b31808SJens Wiklander mbedtls_rsa_context rsa = { }; 637f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 638f8907bbfSEdison Ai uint32_t md_algo = 0; 639f8907bbfSEdison Ai 64032b31808SJens Wiklander res = rsa_init_and_complete_from_key_pair(&rsa, key); 64132b31808SJens Wiklander if (res) 64232b31808SJens Wiklander return res; 643f8907bbfSEdison Ai 644f8907bbfSEdison Ai switch (algo) { 645f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 646f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 647f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 648f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 649f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 650f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 651f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 652f8907bbfSEdison Ai break; 653f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5: 654f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 655f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 656f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 657f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 658f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 659f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 660f8907bbfSEdison Ai break; 661f8907bbfSEdison Ai default: 662f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 663f8907bbfSEdison Ai goto err; 664f8907bbfSEdison Ai } 665f8907bbfSEdison Ai 6667c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 667f8907bbfSEdison Ai &hash_size); 668f8907bbfSEdison Ai if (res != TEE_SUCCESS) 669f8907bbfSEdison Ai goto err; 670f8907bbfSEdison Ai 671f8907bbfSEdison Ai if (msg_len != hash_size) { 672f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 673f8907bbfSEdison Ai goto err; 674f8907bbfSEdison Ai } 675f8907bbfSEdison Ai 676f8907bbfSEdison Ai mod_size = crypto_bignum_num_bytes(key->n); 677f8907bbfSEdison Ai if (*sig_len < mod_size) { 678f8907bbfSEdison Ai *sig_len = mod_size; 679f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 680f8907bbfSEdison Ai goto err; 681f8907bbfSEdison Ai } 682f8907bbfSEdison Ai rsa.len = mod_size; 683f8907bbfSEdison Ai 684f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 685f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 686f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 687f8907bbfSEdison Ai goto err; 688f8907bbfSEdison Ai } 689f8907bbfSEdison Ai 690f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 691f8907bbfSEdison Ai if (!pk_info) { 692f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 693f8907bbfSEdison Ai goto err; 694f8907bbfSEdison Ai } 695f8907bbfSEdison Ai 696f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 697f8907bbfSEdison Ai 698f8907bbfSEdison Ai lmd_res = pk_info->sign_func(&rsa, md_algo, msg, msg_len, sig, 69932b31808SJens Wiklander *sig_len, sig_len, mbd_rand, NULL); 700f8907bbfSEdison Ai if (lmd_res != 0) { 701f8907bbfSEdison Ai FMSG("sign_func failed, returned 0x%x", -lmd_res); 702f8907bbfSEdison Ai res = get_tee_result(lmd_res); 703f8907bbfSEdison Ai goto err; 704f8907bbfSEdison Ai } 705f8907bbfSEdison Ai res = TEE_SUCCESS; 706f8907bbfSEdison Ai err: 70732b31808SJens Wiklander mbd_rsa_free(&rsa, key); 708f8907bbfSEdison Ai return res; 709f8907bbfSEdison Ai } 710f8907bbfSEdison Ai 711f8907bbfSEdison Ai TEE_Result crypto_acipher_rsassa_verify(uint32_t algo, 712f8907bbfSEdison Ai struct rsa_public_key *key, 713f8907bbfSEdison Ai int salt_len __unused, 714f8907bbfSEdison Ai const uint8_t *msg, 715f8907bbfSEdison Ai size_t msg_len, const uint8_t *sig, 716f8907bbfSEdison Ai size_t sig_len) 717eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsassa_verify"); 718eac16613SJorge Ramirez-Ortiz 719eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo, 720eac16613SJorge Ramirez-Ortiz struct rsa_public_key *key, 721eac16613SJorge Ramirez-Ortiz int salt_len __unused, 722eac16613SJorge Ramirez-Ortiz const uint8_t *msg, 723eac16613SJorge Ramirez-Ortiz size_t msg_len, const uint8_t *sig, 724eac16613SJorge Ramirez-Ortiz size_t sig_len) 725f8907bbfSEdison Ai { 726f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 727f8907bbfSEdison Ai int lmd_res = 0; 728f8907bbfSEdison Ai int lmd_padding = 0; 729f8907bbfSEdison Ai size_t hash_size = 0; 730f8907bbfSEdison Ai size_t bigint_size = 0; 731f8907bbfSEdison Ai mbedtls_rsa_context rsa; 732f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 733f8907bbfSEdison Ai uint32_t md_algo = 0; 73498ada65eSJens Wiklander struct ftmn ftmn = { }; 73598ada65eSJens Wiklander unsigned long arg_hash = 0; 73698ada65eSJens Wiklander 73798ada65eSJens Wiklander /* 73898ada65eSJens Wiklander * The caller expects to call crypto_acipher_rsassa_verify(), 73998ada65eSJens Wiklander * update the hash as needed. 74098ada65eSJens Wiklander */ 74198ada65eSJens Wiklander FTMN_CALLEE_SWAP_HASH(FTMN_FUNC_HASH("crypto_acipher_rsassa_verify")); 742f8907bbfSEdison Ai 743f8907bbfSEdison Ai memset(&rsa, 0, sizeof(rsa)); 74432b31808SJens Wiklander mbedtls_rsa_init(&rsa); 745f8907bbfSEdison Ai 746f8907bbfSEdison Ai rsa.E = *(mbedtls_mpi *)key->e; 747f8907bbfSEdison Ai rsa.N = *(mbedtls_mpi *)key->n; 748f8907bbfSEdison Ai 7497c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 750f8907bbfSEdison Ai &hash_size); 751f8907bbfSEdison Ai if (res != TEE_SUCCESS) 752f8907bbfSEdison Ai goto err; 753f8907bbfSEdison Ai 754f8907bbfSEdison Ai if (msg_len != hash_size) { 755f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 756f8907bbfSEdison Ai goto err; 757f8907bbfSEdison Ai } 758f8907bbfSEdison Ai 759f8907bbfSEdison Ai bigint_size = crypto_bignum_num_bytes(key->n); 760f8907bbfSEdison Ai if (sig_len < bigint_size) { 761c282ebd6Slubing res = TEE_ERROR_SIGNATURE_INVALID; 762f8907bbfSEdison Ai goto err; 763f8907bbfSEdison Ai } 764f8907bbfSEdison Ai 765f8907bbfSEdison Ai rsa.len = bigint_size; 766f8907bbfSEdison Ai 767f8907bbfSEdison Ai switch (algo) { 768f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 769f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 770f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 771f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 772f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 773f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 77498ada65eSJens Wiklander arg_hash = FTMN_FUNC_HASH("mbedtls_rsa_rsassa_pkcs1_v15_verify"); 775f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 776f8907bbfSEdison Ai break; 777f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5: 778f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 779f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 780f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 781f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 782f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 78398ada65eSJens Wiklander arg_hash = FTMN_FUNC_HASH("mbedtls_rsa_rsassa_pss_verify_ext"); 784f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 785f8907bbfSEdison Ai break; 786f8907bbfSEdison Ai default: 787f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 788f8907bbfSEdison Ai goto err; 789f8907bbfSEdison Ai } 790f8907bbfSEdison Ai 791f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 792f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 793f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 794f8907bbfSEdison Ai goto err; 795f8907bbfSEdison Ai } 796f8907bbfSEdison Ai 797f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 798f8907bbfSEdison Ai if (!pk_info) { 799f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 800f8907bbfSEdison Ai goto err; 801f8907bbfSEdison Ai } 802f8907bbfSEdison Ai 803f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 804f8907bbfSEdison Ai 80598ada65eSJens Wiklander FTMN_PUSH_LINKED_CALL(&ftmn, arg_hash); 806f8907bbfSEdison Ai lmd_res = pk_info->verify_func(&rsa, md_algo, msg, msg_len, 807f8907bbfSEdison Ai sig, sig_len); 80898ada65eSJens Wiklander if (!lmd_res) 80998ada65eSJens Wiklander FTMN_SET_CHECK_RES_FROM_CALL(&ftmn, FTMN_INCR0, lmd_res); 81098ada65eSJens Wiklander FTMN_POP_LINKED_CALL(&ftmn); 811f8907bbfSEdison Ai if (lmd_res != 0) { 812f8907bbfSEdison Ai FMSG("verify_func failed, returned 0x%x", -lmd_res); 813f8907bbfSEdison Ai res = TEE_ERROR_SIGNATURE_INVALID; 814f8907bbfSEdison Ai goto err; 815f8907bbfSEdison Ai } 816f8907bbfSEdison Ai res = TEE_SUCCESS; 81798ada65eSJens Wiklander goto out; 81898ada65eSJens Wiklander 819f8907bbfSEdison Ai err: 82098ada65eSJens Wiklander FTMN_SET_CHECK_RES_NOT_ZERO(&ftmn, FTMN_INCR0, res); 82198ada65eSJens Wiklander out: 82298ada65eSJens Wiklander FTMN_CALLEE_DONE_CHECK(&ftmn, FTMN_INCR0, FTMN_STEP_COUNT(1), res); 823f8907bbfSEdison Ai /* Reset mpi to skip freeing here, those mpis will be freed with key */ 824f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.E); 825f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.N); 826f8907bbfSEdison Ai mbedtls_rsa_free(&rsa); 827f8907bbfSEdison Ai return res; 828f8907bbfSEdison Ai } 829