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
crypto_acipher_alloc_dh_keypair(struct dh_keypair * s,size_t key_size_bits)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
crypto_acipher_gen_dh_key(struct dh_keypair * key,struct bignum * q __unused,size_t xbits,size_t key_size)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
crypto_acipher_dh_shared_secret(struct dh_keypair * private_key,struct bignum * public_key,struct bignum * secret)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