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