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