1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2018, ARM Limited 4 * Copyright (C) 2019, Linaro Limited 5 */ 6 7 #include <assert.h> 8 #include <crypto/crypto.h> 9 #include <mbedtls/ctr_drbg.h> 10 #include <mbedtls/entropy.h> 11 #include <mbedtls/dhm.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include "mbed_helpers.h" 16 17 TEE_Result crypto_acipher_alloc_dh_keypair(struct dh_keypair *s, 18 size_t key_size_bits) 19 { 20 memset(s, 0, sizeof(*s)); 21 s->g = crypto_bignum_allocate(key_size_bits); 22 if (!s->g) 23 goto err; 24 s->p = crypto_bignum_allocate(key_size_bits); 25 if (!s->p) 26 goto err; 27 s->y = crypto_bignum_allocate(key_size_bits); 28 if (!s->y) 29 goto err; 30 s->x = crypto_bignum_allocate(key_size_bits); 31 if (!s->x) 32 goto err; 33 s->q = crypto_bignum_allocate(key_size_bits); 34 if (!s->q) 35 goto err; 36 return TEE_SUCCESS; 37 err: 38 crypto_bignum_free(&s->g); 39 crypto_bignum_free(&s->p); 40 crypto_bignum_free(&s->y); 41 crypto_bignum_free(&s->x); 42 return TEE_ERROR_OUT_OF_MEMORY; 43 } 44 45 TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key, 46 struct bignum *q __unused, 47 size_t xbits, size_t key_size) 48 { 49 TEE_Result res = TEE_SUCCESS; 50 int lmd_res = 0; 51 mbedtls_dhm_context dhm; 52 unsigned char *buf = NULL; 53 size_t xbytes = 0; 54 size_t len = 0; 55 56 memset(&dhm, 0, sizeof(dhm)); 57 mbedtls_dhm_init(&dhm); 58 59 dhm.G = *(mbedtls_mpi *)key->g; 60 dhm.P = *(mbedtls_mpi *)key->p; 61 62 len = mbedtls_dhm_get_len(&dhm); 63 if (key_size != 8 * len) { 64 res = TEE_ERROR_BAD_PARAMETERS; 65 goto out; 66 } 67 68 if (xbits == 0) 69 xbytes = len; 70 else 71 xbytes = xbits / 8; 72 73 buf = malloc(len); 74 if (!buf) { 75 res = TEE_ERROR_OUT_OF_MEMORY; 76 goto out; 77 } 78 lmd_res = mbedtls_dhm_make_public(&dhm, (int)xbytes, buf, 79 len, mbd_rand, NULL); 80 if (lmd_res != 0) { 81 FMSG("mbedtls_dhm_make_public err, return is 0x%x", -lmd_res); 82 res = TEE_ERROR_BAD_PARAMETERS; 83 } else { 84 crypto_bignum_bin2bn(buf, xbytes, key->y); 85 crypto_bignum_copy(key->x, (void *)&dhm.X); 86 res = TEE_SUCCESS; 87 } 88 out: 89 free(buf); 90 /* Reset mpi to skip freeing here, those mpis will be freed with key */ 91 mbedtls_mpi_init(&dhm.G); 92 mbedtls_mpi_init(&dhm.P); 93 mbedtls_dhm_free(&dhm); 94 return res; 95 } 96 97 TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key, 98 struct bignum *public_key, 99 struct bignum *secret) 100 { 101 TEE_Result res = TEE_SUCCESS; 102 int lmd_res = 0; 103 mbedtls_dhm_context dhm; 104 unsigned char *buf = NULL; 105 size_t olen = 0; 106 size_t len = 0; 107 108 memset(&dhm, 0, sizeof(dhm)); 109 mbedtls_dhm_init(&dhm); 110 111 dhm.G = *(mbedtls_mpi *)private_key->g; 112 dhm.P = *(mbedtls_mpi *)private_key->p; 113 dhm.GX = *(mbedtls_mpi *)private_key->y; 114 dhm.X = *(mbedtls_mpi *)private_key->x; 115 dhm.GY = *(mbedtls_mpi *)public_key; 116 117 len = mbedtls_dhm_get_len(&dhm); 118 119 buf = malloc(len); 120 if (!buf) { 121 res = TEE_ERROR_OUT_OF_MEMORY; 122 goto out; 123 } 124 125 lmd_res = mbedtls_dhm_calc_secret(&dhm, buf, len, 126 &olen, mbd_rand, NULL); 127 if (lmd_res != 0) { 128 FMSG("mbedtls_dhm_calc_secret failed, ret is 0x%x", -lmd_res); 129 res = TEE_ERROR_BAD_PARAMETERS; 130 } else { 131 crypto_bignum_bin2bn(buf, olen, secret); 132 res = TEE_SUCCESS; 133 } 134 out: 135 free(buf); 136 /* Reset mpi to skip freeing here, those mpis will be freed with key */ 137 mbedtls_mpi_init(&dhm.G); 138 mbedtls_mpi_init(&dhm.P); 139 mbedtls_mpi_init(&dhm.GX); 140 mbedtls_mpi_init(&dhm.X); 141 mbedtls_mpi_init(&dhm.GY); 142 mbedtls_dhm_free(&dhm); 143 return res; 144 } 145