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