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 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
crypto_acipher_dh_shared_secret(struct dh_keypair * private_key,struct bignum * public_key,struct bignum * secret)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