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 "mbd_rand.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) 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 55 memset(&dhm, 0, sizeof(dhm)); 56 mbedtls_dhm_init(&dhm); 57 58 dhm.G = *(mbedtls_mpi *)key->g; 59 dhm.P = *(mbedtls_mpi *)key->p; 60 61 dhm.len = crypto_bignum_num_bytes(key->p); 62 63 if (xbits == 0) 64 xbytes = dhm.len; 65 else 66 xbytes = xbits / 8; 67 68 buf = malloc(dhm.len); 69 if (!buf) { 70 res = TEE_ERROR_OUT_OF_MEMORY; 71 goto out; 72 } 73 lmd_res = mbedtls_dhm_make_public(&dhm, (int)xbytes, buf, 74 dhm.len, mbd_rand, NULL); 75 if (lmd_res != 0) { 76 FMSG("mbedtls_dhm_make_public err, return is 0x%x", -lmd_res); 77 res = TEE_ERROR_BAD_PARAMETERS; 78 } else { 79 crypto_bignum_bin2bn(buf, xbytes, key->y); 80 crypto_bignum_copy(key->x, (void *)&dhm.X); 81 res = TEE_SUCCESS; 82 } 83 out: 84 free(buf); 85 /* Reset mpi to skip freeing here, those mpis will be freed with key */ 86 mbedtls_mpi_init(&dhm.G); 87 mbedtls_mpi_init(&dhm.P); 88 mbedtls_dhm_free(&dhm); 89 return res; 90 } 91 92 TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key, 93 struct bignum *public_key, 94 struct bignum *secret) 95 { 96 TEE_Result res = TEE_SUCCESS; 97 int lmd_res = 0; 98 mbedtls_dhm_context dhm; 99 unsigned char *buf = NULL; 100 size_t olen = 0; 101 102 memset(&dhm, 0, sizeof(dhm)); 103 mbedtls_dhm_init(&dhm); 104 105 dhm.G = *(mbedtls_mpi *)private_key->g; 106 dhm.P = *(mbedtls_mpi *)private_key->p; 107 dhm.GX = *(mbedtls_mpi *)private_key->y; 108 dhm.X = *(mbedtls_mpi *)private_key->x; 109 dhm.GY = *(mbedtls_mpi *)public_key; 110 111 dhm.len = crypto_bignum_num_bytes(private_key->p); 112 113 buf = malloc(dhm.len); 114 if (!buf) { 115 res = TEE_ERROR_OUT_OF_MEMORY; 116 goto out; 117 } 118 119 lmd_res = mbedtls_dhm_calc_secret(&dhm, buf, dhm.len, 120 &olen, mbd_rand, NULL); 121 if (lmd_res != 0) { 122 FMSG("mbedtls_dhm_calc_secret failed, ret is 0x%x", -lmd_res); 123 res = TEE_ERROR_BAD_PARAMETERS; 124 } else { 125 crypto_bignum_bin2bn(buf, olen, secret); 126 res = TEE_SUCCESS; 127 } 128 out: 129 free(buf); 130 /* Reset mpi to skip freeing here, those mpis will be freed with key */ 131 mbedtls_mpi_init(&dhm.G); 132 mbedtls_mpi_init(&dhm.P); 133 mbedtls_mpi_init(&dhm.GX); 134 mbedtls_mpi_init(&dhm.X); 135 mbedtls_mpi_init(&dhm.GY); 136 mbedtls_dhm_free(&dhm); 137 return res; 138 } 139