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" 20*32b31808SJens Wiklander #include "../mbedtls/library/pk_wrap.h" 21*32b31808SJens 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 100*32b31808SJens Wiklander static TEE_Result rsa_init_and_complete_from_key_pair(mbedtls_rsa_context *rsa, 101f8907bbfSEdison Ai struct rsa_keypair *key) 102f8907bbfSEdison Ai { 103*32b31808SJens Wiklander int lmd_res = 0; 104*32b31808SJens Wiklander 105*32b31808SJens 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; 110*32b31808SJens Wiklander rsa->len = mbedtls_mpi_size(&rsa->N); 111*32b31808SJens 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; 118*32b31808SJens Wiklander } else { 119*32b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->P); 120*32b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->Q); 121*32b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->QP); 122*32b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->DP); 123*32b31808SJens Wiklander mbedtls_mpi_init_mempool(&rsa->DQ); 124*32b31808SJens Wiklander 125*32b31808SJens Wiklander lmd_res = mbedtls_rsa_deduce_primes(&rsa->N, &rsa->E, &rsa->D, 126*32b31808SJens Wiklander &rsa->P, &rsa->Q); 127*32b31808SJens Wiklander if (lmd_res) { 128*32b31808SJens Wiklander DMSG("mbedtls_rsa_deduce_primes() returned 0x%x", 129*32b31808SJens Wiklander -lmd_res); 130*32b31808SJens Wiklander goto err; 131f8907bbfSEdison Ai } 132f8907bbfSEdison Ai 133*32b31808SJens Wiklander lmd_res = mbedtls_rsa_deduce_crt(&rsa->P, &rsa->Q, &rsa->D, 134*32b31808SJens Wiklander &rsa->DP, &rsa->DQ, &rsa->QP); 135*32b31808SJens Wiklander if (lmd_res) { 136*32b31808SJens Wiklander DMSG("mbedtls_rsa_deduce_crt() returned 0x%x", 137*32b31808SJens Wiklander -lmd_res); 138*32b31808SJens Wiklander goto err; 139*32b31808SJens Wiklander } 140*32b31808SJens Wiklander } 141*32b31808SJens Wiklander 142*32b31808SJens Wiklander return TEE_SUCCESS; 143*32b31808SJens Wiklander err: 144*32b31808SJens Wiklander mbedtls_mpi_free(&rsa->P); 145*32b31808SJens Wiklander mbedtls_mpi_free(&rsa->Q); 146*32b31808SJens Wiklander mbedtls_mpi_free(&rsa->QP); 147*32b31808SJens Wiklander mbedtls_mpi_free(&rsa->DP); 148*32b31808SJens Wiklander mbedtls_mpi_free(&rsa->DQ); 149*32b31808SJens Wiklander 150*32b31808SJens Wiklander return get_tee_result(lmd_res); 151*32b31808SJens Wiklander } 152*32b31808SJens Wiklander 153*32b31808SJens Wiklander static void mbd_rsa_free(mbedtls_rsa_context *rsa, struct rsa_keypair *key) 154f8907bbfSEdison Ai { 155*32b31808SJens Wiklander /* 156*32b31808SJens Wiklander * The mpi's in @rsa are initialized from @key, but the primes and 157*32b31808SJens Wiklander * CRT part are generated if @key doesn't have them. When freeing 158*32b31808SJens Wiklander * we should only free the generated mpi's, the ones copied are 159*32b31808SJens Wiklander * reset instead. 160*32b31808SJens Wiklander */ 161f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->E); 162f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->N); 163f8907bbfSEdison Ai mbedtls_mpi_init(&rsa->D); 164*32b31808SJens 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)); 279*32b31808SJens 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)); 332*32b31808SJens 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; 390*32b31808SJens 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 396*32b31808SJens Wiklander res = rsa_init_and_complete_from_key_pair(&rsa, key); 397*32b31808SJens Wiklander if (res) 398*32b31808SJens 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 410*32b31808SJens 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); 432*32b31808SJens 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, 440eac16613SJorge Ramirez-Ortiz const uint8_t *src, size_t src_len, 441eac16613SJorge Ramirez-Ortiz uint8_t *dst, size_t *dst_len) 442eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsaes_decrypt"); 443eac16613SJorge Ramirez-Ortiz 444eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo, 445eac16613SJorge Ramirez-Ortiz struct rsa_keypair *key, 446f8907bbfSEdison Ai const uint8_t *label __unused, 447f8907bbfSEdison Ai size_t label_len __unused, 448f8907bbfSEdison Ai const uint8_t *src, size_t src_len, 449f8907bbfSEdison Ai uint8_t *dst, size_t *dst_len) 450f8907bbfSEdison Ai { 451f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 452f8907bbfSEdison Ai int lmd_res = 0; 453f8907bbfSEdison Ai int lmd_padding = 0; 454f8907bbfSEdison Ai size_t blen = 0; 455f8907bbfSEdison Ai size_t mod_size = 0; 456f8907bbfSEdison Ai void *buf = NULL; 457*32b31808SJens Wiklander mbedtls_rsa_context rsa = { }; 458f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 459f8907bbfSEdison Ai uint32_t md_algo = MBEDTLS_MD_NONE; 460f8907bbfSEdison Ai 461*32b31808SJens Wiklander res = rsa_init_and_complete_from_key_pair(&rsa, key); 462*32b31808SJens Wiklander if (res) 463*32b31808SJens Wiklander return res; 464f8907bbfSEdison Ai 465f8907bbfSEdison Ai /* 466f8907bbfSEdison Ai * Use a temporary buffer since we don't know exactly how large 467f8907bbfSEdison Ai * the required size of the out buffer without doing a partial 468f8907bbfSEdison Ai * decrypt. We know the upper bound though. 469f8907bbfSEdison Ai */ 470f8907bbfSEdison Ai if (algo == TEE_ALG_RSAES_PKCS1_V1_5) { 471f8907bbfSEdison Ai mod_size = crypto_bignum_num_bytes(key->n); 472f8907bbfSEdison Ai blen = mod_size - 11; 473f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 474f8907bbfSEdison Ai } else { 475f8907bbfSEdison Ai /* Decoded message is always shorter than encrypted message */ 476f8907bbfSEdison Ai blen = src_len; 477f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 478f8907bbfSEdison Ai } 479f8907bbfSEdison Ai 480f8907bbfSEdison Ai buf = malloc(blen); 481f8907bbfSEdison Ai if (!buf) { 482f8907bbfSEdison Ai res = TEE_ERROR_OUT_OF_MEMORY; 483f8907bbfSEdison Ai goto out; 484f8907bbfSEdison Ai } 485f8907bbfSEdison Ai 486f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 487f8907bbfSEdison Ai if (!pk_info) { 488f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 489f8907bbfSEdison Ai goto out; 490f8907bbfSEdison Ai } 491f8907bbfSEdison Ai 492f8907bbfSEdison Ai /* 493f8907bbfSEdison Ai * TEE_ALG_RSAES_PKCS1_V1_5 is invalid in hash. But its hash algo will 494f8907bbfSEdison Ai * not be used in rsa, so skip it here. 495f8907bbfSEdison Ai */ 496f8907bbfSEdison Ai if (algo != TEE_ALG_RSAES_PKCS1_V1_5) { 497f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 498f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 499f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 500f8907bbfSEdison Ai goto out; 501f8907bbfSEdison Ai } 502f8907bbfSEdison Ai } 503f8907bbfSEdison Ai 504f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 505f8907bbfSEdison Ai 506f8907bbfSEdison Ai lmd_res = pk_info->decrypt_func(&rsa, src, src_len, buf, &blen, 507f8907bbfSEdison Ai blen, mbd_rand, NULL); 508f8907bbfSEdison Ai if (lmd_res != 0) { 509f8907bbfSEdison Ai FMSG("decrypt_func() returned 0x%x", -lmd_res); 510f8907bbfSEdison Ai res = get_tee_result(lmd_res); 511f8907bbfSEdison Ai goto out; 512f8907bbfSEdison Ai } 513f8907bbfSEdison Ai 514f8907bbfSEdison Ai if (*dst_len < blen) { 515f8907bbfSEdison Ai *dst_len = blen; 516f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 517f8907bbfSEdison Ai goto out; 518f8907bbfSEdison Ai } 519f8907bbfSEdison Ai 520f8907bbfSEdison Ai res = TEE_SUCCESS; 521f8907bbfSEdison Ai *dst_len = blen; 522f8907bbfSEdison Ai memcpy(dst, buf, blen); 523f8907bbfSEdison Ai out: 524f8907bbfSEdison Ai if (buf) 525f8907bbfSEdison Ai free(buf); 526*32b31808SJens Wiklander mbd_rsa_free(&rsa, key); 527f8907bbfSEdison Ai return res; 528f8907bbfSEdison Ai } 529f8907bbfSEdison Ai 530f8907bbfSEdison Ai TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo, 531f8907bbfSEdison Ai struct rsa_public_key *key, 532f8907bbfSEdison Ai const uint8_t *label __unused, 533f8907bbfSEdison Ai size_t label_len __unused, 534f8907bbfSEdison Ai const uint8_t *src, size_t src_len, 535f8907bbfSEdison Ai uint8_t *dst, size_t *dst_len) 536eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsaes_encrypt"); 537eac16613SJorge Ramirez-Ortiz 538eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo, 539eac16613SJorge Ramirez-Ortiz struct rsa_public_key *key, 540eac16613SJorge Ramirez-Ortiz const uint8_t *label __unused, 541eac16613SJorge Ramirez-Ortiz size_t label_len __unused, 542eac16613SJorge Ramirez-Ortiz const uint8_t *src, size_t src_len, 543eac16613SJorge Ramirez-Ortiz uint8_t *dst, size_t *dst_len) 544f8907bbfSEdison Ai { 545f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 546f8907bbfSEdison Ai int lmd_res = 0; 547f8907bbfSEdison Ai int lmd_padding = 0; 548f8907bbfSEdison Ai size_t mod_size = 0; 549f8907bbfSEdison Ai mbedtls_rsa_context rsa; 550f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 551f8907bbfSEdison Ai uint32_t md_algo = MBEDTLS_MD_NONE; 552f8907bbfSEdison Ai 553f8907bbfSEdison Ai memset(&rsa, 0, sizeof(rsa)); 554*32b31808SJens Wiklander mbedtls_rsa_init(&rsa); 555f8907bbfSEdison Ai 556f8907bbfSEdison Ai rsa.E = *(mbedtls_mpi *)key->e; 557f8907bbfSEdison Ai rsa.N = *(mbedtls_mpi *)key->n; 558f8907bbfSEdison Ai 559f8907bbfSEdison Ai mod_size = crypto_bignum_num_bytes(key->n); 560f8907bbfSEdison Ai if (*dst_len < mod_size) { 561f8907bbfSEdison Ai *dst_len = mod_size; 562f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 563f8907bbfSEdison Ai goto out; 564f8907bbfSEdison Ai } 565f8907bbfSEdison Ai *dst_len = mod_size; 566f8907bbfSEdison Ai rsa.len = mod_size; 567f8907bbfSEdison Ai 568f8907bbfSEdison Ai if (algo == TEE_ALG_RSAES_PKCS1_V1_5) 569f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 570f8907bbfSEdison Ai else 571f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 572f8907bbfSEdison Ai 573f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 574f8907bbfSEdison Ai if (!pk_info) { 575f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 576f8907bbfSEdison Ai goto out; 577f8907bbfSEdison Ai } 578f8907bbfSEdison Ai 579f8907bbfSEdison Ai /* 580f8907bbfSEdison Ai * TEE_ALG_RSAES_PKCS1_V1_5 is invalid in hash. But its hash algo will 581f8907bbfSEdison Ai * not be used in rsa, so skip it here. 582f8907bbfSEdison Ai */ 583f8907bbfSEdison Ai if (algo != TEE_ALG_RSAES_PKCS1_V1_5) { 584f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 585f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 586f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 587f8907bbfSEdison Ai goto out; 588f8907bbfSEdison Ai } 589f8907bbfSEdison Ai } 590f8907bbfSEdison Ai 591f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 592f8907bbfSEdison Ai 593f8907bbfSEdison Ai lmd_res = pk_info->encrypt_func(&rsa, src, src_len, dst, dst_len, 594f8907bbfSEdison Ai *dst_len, mbd_rand, NULL); 595f8907bbfSEdison Ai if (lmd_res != 0) { 596f8907bbfSEdison Ai FMSG("encrypt_func() returned 0x%x", -lmd_res); 597f8907bbfSEdison Ai res = get_tee_result(lmd_res); 598f8907bbfSEdison Ai goto out; 599f8907bbfSEdison Ai } 600f8907bbfSEdison Ai res = TEE_SUCCESS; 601f8907bbfSEdison Ai out: 602f8907bbfSEdison Ai /* Reset mpi to skip freeing here, those mpis will be freed with key */ 603f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.E); 604f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.N); 605f8907bbfSEdison Ai mbedtls_rsa_free(&rsa); 606f8907bbfSEdison Ai return res; 607f8907bbfSEdison Ai } 608f8907bbfSEdison Ai 609f8907bbfSEdison Ai TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, 610eac16613SJorge Ramirez-Ortiz int salt_len __unused, 611eac16613SJorge Ramirez-Ortiz const uint8_t *msg, size_t msg_len, 612eac16613SJorge Ramirez-Ortiz uint8_t *sig, size_t *sig_len) 613eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsassa_sign"); 614eac16613SJorge Ramirez-Ortiz 615eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, 616eac16613SJorge Ramirez-Ortiz int salt_len __unused, 617eac16613SJorge Ramirez-Ortiz const uint8_t *msg, size_t msg_len, 618eac16613SJorge Ramirez-Ortiz uint8_t *sig, size_t *sig_len) 619f8907bbfSEdison Ai { 620f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 621f8907bbfSEdison Ai int lmd_res = 0; 622f8907bbfSEdison Ai int lmd_padding = 0; 623f8907bbfSEdison Ai size_t mod_size = 0; 624f8907bbfSEdison Ai size_t hash_size = 0; 625*32b31808SJens Wiklander mbedtls_rsa_context rsa = { }; 626f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 627f8907bbfSEdison Ai uint32_t md_algo = 0; 628f8907bbfSEdison Ai 629*32b31808SJens Wiklander res = rsa_init_and_complete_from_key_pair(&rsa, key); 630*32b31808SJens Wiklander if (res) 631*32b31808SJens Wiklander return res; 632f8907bbfSEdison Ai 633f8907bbfSEdison Ai switch (algo) { 634f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 635f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 636f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 637f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 638f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 639f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 640f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 641f8907bbfSEdison Ai break; 642f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5: 643f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 644f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 645f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 646f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 647f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 648f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 649f8907bbfSEdison Ai break; 650f8907bbfSEdison Ai default: 651f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 652f8907bbfSEdison Ai goto err; 653f8907bbfSEdison Ai } 654f8907bbfSEdison Ai 6557c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 656f8907bbfSEdison Ai &hash_size); 657f8907bbfSEdison Ai if (res != TEE_SUCCESS) 658f8907bbfSEdison Ai goto err; 659f8907bbfSEdison Ai 660f8907bbfSEdison Ai if (msg_len != hash_size) { 661f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 662f8907bbfSEdison Ai goto err; 663f8907bbfSEdison Ai } 664f8907bbfSEdison Ai 665f8907bbfSEdison Ai mod_size = crypto_bignum_num_bytes(key->n); 666f8907bbfSEdison Ai if (*sig_len < mod_size) { 667f8907bbfSEdison Ai *sig_len = mod_size; 668f8907bbfSEdison Ai res = TEE_ERROR_SHORT_BUFFER; 669f8907bbfSEdison Ai goto err; 670f8907bbfSEdison Ai } 671f8907bbfSEdison Ai rsa.len = mod_size; 672f8907bbfSEdison Ai 673f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 674f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 675f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 676f8907bbfSEdison Ai goto err; 677f8907bbfSEdison Ai } 678f8907bbfSEdison Ai 679f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 680f8907bbfSEdison Ai if (!pk_info) { 681f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 682f8907bbfSEdison Ai goto err; 683f8907bbfSEdison Ai } 684f8907bbfSEdison Ai 685f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 686f8907bbfSEdison Ai 687f8907bbfSEdison Ai lmd_res = pk_info->sign_func(&rsa, md_algo, msg, msg_len, sig, 688*32b31808SJens Wiklander *sig_len, sig_len, mbd_rand, NULL); 689f8907bbfSEdison Ai if (lmd_res != 0) { 690f8907bbfSEdison Ai FMSG("sign_func failed, returned 0x%x", -lmd_res); 691f8907bbfSEdison Ai res = get_tee_result(lmd_res); 692f8907bbfSEdison Ai goto err; 693f8907bbfSEdison Ai } 694f8907bbfSEdison Ai res = TEE_SUCCESS; 695f8907bbfSEdison Ai err: 696*32b31808SJens Wiklander mbd_rsa_free(&rsa, key); 697f8907bbfSEdison Ai return res; 698f8907bbfSEdison Ai } 699f8907bbfSEdison Ai 700f8907bbfSEdison Ai TEE_Result crypto_acipher_rsassa_verify(uint32_t algo, 701f8907bbfSEdison Ai struct rsa_public_key *key, 702f8907bbfSEdison Ai int salt_len __unused, 703f8907bbfSEdison Ai const uint8_t *msg, 704f8907bbfSEdison Ai size_t msg_len, const uint8_t *sig, 705f8907bbfSEdison Ai size_t sig_len) 706eac16613SJorge Ramirez-Ortiz __weak __alias("sw_crypto_acipher_rsassa_verify"); 707eac16613SJorge Ramirez-Ortiz 708eac16613SJorge Ramirez-Ortiz TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo, 709eac16613SJorge Ramirez-Ortiz struct rsa_public_key *key, 710eac16613SJorge Ramirez-Ortiz int salt_len __unused, 711eac16613SJorge Ramirez-Ortiz const uint8_t *msg, 712eac16613SJorge Ramirez-Ortiz size_t msg_len, const uint8_t *sig, 713eac16613SJorge Ramirez-Ortiz size_t sig_len) 714f8907bbfSEdison Ai { 715f8907bbfSEdison Ai TEE_Result res = TEE_SUCCESS; 716f8907bbfSEdison Ai int lmd_res = 0; 717f8907bbfSEdison Ai int lmd_padding = 0; 718f8907bbfSEdison Ai size_t hash_size = 0; 719f8907bbfSEdison Ai size_t bigint_size = 0; 720f8907bbfSEdison Ai mbedtls_rsa_context rsa; 721f8907bbfSEdison Ai const mbedtls_pk_info_t *pk_info = NULL; 722f8907bbfSEdison Ai uint32_t md_algo = 0; 72398ada65eSJens Wiklander struct ftmn ftmn = { }; 72498ada65eSJens Wiklander unsigned long arg_hash = 0; 72598ada65eSJens Wiklander 72698ada65eSJens Wiklander /* 72798ada65eSJens Wiklander * The caller expects to call crypto_acipher_rsassa_verify(), 72898ada65eSJens Wiklander * update the hash as needed. 72998ada65eSJens Wiklander */ 73098ada65eSJens Wiklander FTMN_CALLEE_SWAP_HASH(FTMN_FUNC_HASH("crypto_acipher_rsassa_verify")); 731f8907bbfSEdison Ai 732f8907bbfSEdison Ai memset(&rsa, 0, sizeof(rsa)); 733*32b31808SJens Wiklander mbedtls_rsa_init(&rsa); 734f8907bbfSEdison Ai 735f8907bbfSEdison Ai rsa.E = *(mbedtls_mpi *)key->e; 736f8907bbfSEdison Ai rsa.N = *(mbedtls_mpi *)key->n; 737f8907bbfSEdison Ai 7387c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 739f8907bbfSEdison Ai &hash_size); 740f8907bbfSEdison Ai if (res != TEE_SUCCESS) 741f8907bbfSEdison Ai goto err; 742f8907bbfSEdison Ai 743f8907bbfSEdison Ai if (msg_len != hash_size) { 744f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 745f8907bbfSEdison Ai goto err; 746f8907bbfSEdison Ai } 747f8907bbfSEdison Ai 748f8907bbfSEdison Ai bigint_size = crypto_bignum_num_bytes(key->n); 749f8907bbfSEdison Ai if (sig_len < bigint_size) { 750c282ebd6Slubing res = TEE_ERROR_SIGNATURE_INVALID; 751f8907bbfSEdison Ai goto err; 752f8907bbfSEdison Ai } 753f8907bbfSEdison Ai 754f8907bbfSEdison Ai rsa.len = bigint_size; 755f8907bbfSEdison Ai 756f8907bbfSEdison Ai switch (algo) { 757f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 758f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 759f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 760f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 761f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 762f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 76398ada65eSJens Wiklander arg_hash = FTMN_FUNC_HASH("mbedtls_rsa_rsassa_pkcs1_v15_verify"); 764f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V15; 765f8907bbfSEdison Ai break; 766f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5: 767f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 768f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 769f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 770f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 771f8907bbfSEdison Ai case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 77298ada65eSJens Wiklander arg_hash = FTMN_FUNC_HASH("mbedtls_rsa_rsassa_pss_verify_ext"); 773f8907bbfSEdison Ai lmd_padding = MBEDTLS_RSA_PKCS_V21; 774f8907bbfSEdison Ai break; 775f8907bbfSEdison Ai default: 776f8907bbfSEdison Ai res = TEE_ERROR_BAD_PARAMETERS; 777f8907bbfSEdison Ai goto err; 778f8907bbfSEdison Ai } 779f8907bbfSEdison Ai 780f8907bbfSEdison Ai md_algo = tee_algo_to_mbedtls_hash_algo(algo); 781f8907bbfSEdison Ai if (md_algo == MBEDTLS_MD_NONE) { 782f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 783f8907bbfSEdison Ai goto err; 784f8907bbfSEdison Ai } 785f8907bbfSEdison Ai 786f8907bbfSEdison Ai pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); 787f8907bbfSEdison Ai if (!pk_info) { 788f8907bbfSEdison Ai res = TEE_ERROR_NOT_SUPPORTED; 789f8907bbfSEdison Ai goto err; 790f8907bbfSEdison Ai } 791f8907bbfSEdison Ai 792f8907bbfSEdison Ai mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo); 793f8907bbfSEdison Ai 79498ada65eSJens Wiklander FTMN_PUSH_LINKED_CALL(&ftmn, arg_hash); 795f8907bbfSEdison Ai lmd_res = pk_info->verify_func(&rsa, md_algo, msg, msg_len, 796f8907bbfSEdison Ai sig, sig_len); 79798ada65eSJens Wiklander if (!lmd_res) 79898ada65eSJens Wiklander FTMN_SET_CHECK_RES_FROM_CALL(&ftmn, FTMN_INCR0, lmd_res); 79998ada65eSJens Wiklander FTMN_POP_LINKED_CALL(&ftmn); 800f8907bbfSEdison Ai if (lmd_res != 0) { 801f8907bbfSEdison Ai FMSG("verify_func failed, returned 0x%x", -lmd_res); 802f8907bbfSEdison Ai res = TEE_ERROR_SIGNATURE_INVALID; 803f8907bbfSEdison Ai goto err; 804f8907bbfSEdison Ai } 805f8907bbfSEdison Ai res = TEE_SUCCESS; 80698ada65eSJens Wiklander goto out; 80798ada65eSJens Wiklander 808f8907bbfSEdison Ai err: 80998ada65eSJens Wiklander FTMN_SET_CHECK_RES_NOT_ZERO(&ftmn, FTMN_INCR0, res); 81098ada65eSJens Wiklander out: 81198ada65eSJens Wiklander FTMN_CALLEE_DONE_CHECK(&ftmn, FTMN_INCR0, FTMN_STEP_COUNT(1), res); 812f8907bbfSEdison Ai /* Reset mpi to skip freeing here, those mpis will be freed with key */ 813f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.E); 814f8907bbfSEdison Ai mbedtls_mpi_init(&rsa.N); 815f8907bbfSEdison Ai mbedtls_rsa_free(&rsa); 816f8907bbfSEdison Ai return res; 817f8907bbfSEdison Ai } 818