1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi * Diffie-Hellman-Merkle key exchange (server side)
3*62c56f98SSadaf Ebrahimi *
4*62c56f98SSadaf Ebrahimi * Copyright The Mbed TLS Contributors
5*62c56f98SSadaf Ebrahimi * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*62c56f98SSadaf Ebrahimi */
7*62c56f98SSadaf Ebrahimi
8*62c56f98SSadaf Ebrahimi #include "mbedtls/build_info.h"
9*62c56f98SSadaf Ebrahimi
10*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
11*62c56f98SSadaf Ebrahimi /* md.h is included this early since MD_CAN_XXX macros are defined there. */
12*62c56f98SSadaf Ebrahimi #include "mbedtls/md.h"
13*62c56f98SSadaf Ebrahimi
14*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
15*62c56f98SSadaf Ebrahimi defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \
16*62c56f98SSadaf Ebrahimi defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \
17*62c56f98SSadaf Ebrahimi defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) && \
18*62c56f98SSadaf Ebrahimi defined(MBEDTLS_MD_CAN_SHA1)
19*62c56f98SSadaf Ebrahimi #include "mbedtls/net_sockets.h"
20*62c56f98SSadaf Ebrahimi #include "mbedtls/aes.h"
21*62c56f98SSadaf Ebrahimi #include "mbedtls/dhm.h"
22*62c56f98SSadaf Ebrahimi #include "mbedtls/rsa.h"
23*62c56f98SSadaf Ebrahimi #include "mbedtls/sha1.h"
24*62c56f98SSadaf Ebrahimi #include "mbedtls/entropy.h"
25*62c56f98SSadaf Ebrahimi #include "mbedtls/ctr_drbg.h"
26*62c56f98SSadaf Ebrahimi
27*62c56f98SSadaf Ebrahimi #include <stdio.h>
28*62c56f98SSadaf Ebrahimi #include <string.h>
29*62c56f98SSadaf Ebrahimi #endif
30*62c56f98SSadaf Ebrahimi
31*62c56f98SSadaf Ebrahimi #define SERVER_PORT "11999"
32*62c56f98SSadaf Ebrahimi #define PLAINTEXT "==Hello there!=="
33*62c56f98SSadaf Ebrahimi
34*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \
35*62c56f98SSadaf Ebrahimi !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \
36*62c56f98SSadaf Ebrahimi !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \
37*62c56f98SSadaf Ebrahimi !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) || \
38*62c56f98SSadaf Ebrahimi !defined(MBEDTLS_SHA1_C)
main(void)39*62c56f98SSadaf Ebrahimi int main(void)
40*62c56f98SSadaf Ebrahimi {
41*62c56f98SSadaf Ebrahimi mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C "
42*62c56f98SSadaf Ebrahimi "and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
43*62c56f98SSadaf Ebrahimi "MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or "
44*62c56f98SSadaf Ebrahimi "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n");
45*62c56f98SSadaf Ebrahimi mbedtls_exit(0);
46*62c56f98SSadaf Ebrahimi }
47*62c56f98SSadaf Ebrahimi #else
48*62c56f98SSadaf Ebrahimi
49*62c56f98SSadaf Ebrahimi
main(void)50*62c56f98SSadaf Ebrahimi int main(void)
51*62c56f98SSadaf Ebrahimi {
52*62c56f98SSadaf Ebrahimi FILE *f;
53*62c56f98SSadaf Ebrahimi
54*62c56f98SSadaf Ebrahimi int ret = 1;
55*62c56f98SSadaf Ebrahimi int exit_code = MBEDTLS_EXIT_FAILURE;
56*62c56f98SSadaf Ebrahimi size_t n, buflen;
57*62c56f98SSadaf Ebrahimi mbedtls_net_context listen_fd, client_fd;
58*62c56f98SSadaf Ebrahimi
59*62c56f98SSadaf Ebrahimi unsigned char buf[2048];
60*62c56f98SSadaf Ebrahimi unsigned char hash[32];
61*62c56f98SSadaf Ebrahimi unsigned char buf2[2];
62*62c56f98SSadaf Ebrahimi const char *pers = "dh_server";
63*62c56f98SSadaf Ebrahimi
64*62c56f98SSadaf Ebrahimi mbedtls_entropy_context entropy;
65*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_context ctr_drbg;
66*62c56f98SSadaf Ebrahimi mbedtls_rsa_context rsa;
67*62c56f98SSadaf Ebrahimi mbedtls_dhm_context dhm;
68*62c56f98SSadaf Ebrahimi mbedtls_aes_context aes;
69*62c56f98SSadaf Ebrahimi
70*62c56f98SSadaf Ebrahimi mbedtls_mpi N, P, Q, D, E;
71*62c56f98SSadaf Ebrahimi
72*62c56f98SSadaf Ebrahimi mbedtls_net_init(&listen_fd);
73*62c56f98SSadaf Ebrahimi mbedtls_net_init(&client_fd);
74*62c56f98SSadaf Ebrahimi mbedtls_dhm_init(&dhm);
75*62c56f98SSadaf Ebrahimi mbedtls_aes_init(&aes);
76*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_init(&ctr_drbg);
77*62c56f98SSadaf Ebrahimi
78*62c56f98SSadaf Ebrahimi mbedtls_mpi_init(&N); mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
79*62c56f98SSadaf Ebrahimi mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
80*62c56f98SSadaf Ebrahimi
81*62c56f98SSadaf Ebrahimi /*
82*62c56f98SSadaf Ebrahimi * 1. Setup the RNG
83*62c56f98SSadaf Ebrahimi */
84*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Seeding the random number generator");
85*62c56f98SSadaf Ebrahimi fflush(stdout);
86*62c56f98SSadaf Ebrahimi
87*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&entropy);
88*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
89*62c56f98SSadaf Ebrahimi (const unsigned char *) pers,
90*62c56f98SSadaf Ebrahimi strlen(pers))) != 0) {
91*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
92*62c56f98SSadaf Ebrahimi goto exit;
93*62c56f98SSadaf Ebrahimi }
94*62c56f98SSadaf Ebrahimi
95*62c56f98SSadaf Ebrahimi /*
96*62c56f98SSadaf Ebrahimi * 2a. Read the server's private RSA key
97*62c56f98SSadaf Ebrahimi */
98*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Reading private key from rsa_priv.txt");
99*62c56f98SSadaf Ebrahimi fflush(stdout);
100*62c56f98SSadaf Ebrahimi
101*62c56f98SSadaf Ebrahimi if ((f = fopen("rsa_priv.txt", "rb")) == NULL) {
102*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! Could not open rsa_priv.txt\n" \
103*62c56f98SSadaf Ebrahimi " ! Please run rsa_genkey first\n\n");
104*62c56f98SSadaf Ebrahimi goto exit;
105*62c56f98SSadaf Ebrahimi }
106*62c56f98SSadaf Ebrahimi
107*62c56f98SSadaf Ebrahimi mbedtls_rsa_init(&rsa);
108*62c56f98SSadaf Ebrahimi
109*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_mpi_read_file(&N, 16, f)) != 0 ||
110*62c56f98SSadaf Ebrahimi (ret = mbedtls_mpi_read_file(&E, 16, f)) != 0 ||
111*62c56f98SSadaf Ebrahimi (ret = mbedtls_mpi_read_file(&D, 16, f)) != 0 ||
112*62c56f98SSadaf Ebrahimi (ret = mbedtls_mpi_read_file(&P, 16, f)) != 0 ||
113*62c56f98SSadaf Ebrahimi (ret = mbedtls_mpi_read_file(&Q, 16, f)) != 0) {
114*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_mpi_read_file returned %d\n\n",
115*62c56f98SSadaf Ebrahimi ret);
116*62c56f98SSadaf Ebrahimi fclose(f);
117*62c56f98SSadaf Ebrahimi goto exit;
118*62c56f98SSadaf Ebrahimi }
119*62c56f98SSadaf Ebrahimi fclose(f);
120*62c56f98SSadaf Ebrahimi
121*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_rsa_import(&rsa, &N, &P, &Q, &D, &E)) != 0) {
122*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_rsa_import returned %d\n\n",
123*62c56f98SSadaf Ebrahimi ret);
124*62c56f98SSadaf Ebrahimi goto exit;
125*62c56f98SSadaf Ebrahimi }
126*62c56f98SSadaf Ebrahimi
127*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_rsa_complete(&rsa)) != 0) {
128*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_rsa_complete returned %d\n\n",
129*62c56f98SSadaf Ebrahimi ret);
130*62c56f98SSadaf Ebrahimi goto exit;
131*62c56f98SSadaf Ebrahimi }
132*62c56f98SSadaf Ebrahimi
133*62c56f98SSadaf Ebrahimi /*
134*62c56f98SSadaf Ebrahimi * 2b. Get the DHM modulus and generator
135*62c56f98SSadaf Ebrahimi */
136*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Reading DH parameters from dh_prime.txt");
137*62c56f98SSadaf Ebrahimi fflush(stdout);
138*62c56f98SSadaf Ebrahimi
139*62c56f98SSadaf Ebrahimi if ((f = fopen("dh_prime.txt", "rb")) == NULL) {
140*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! Could not open dh_prime.txt\n" \
141*62c56f98SSadaf Ebrahimi " ! Please run dh_genprime first\n\n");
142*62c56f98SSadaf Ebrahimi goto exit;
143*62c56f98SSadaf Ebrahimi }
144*62c56f98SSadaf Ebrahimi
145*62c56f98SSadaf Ebrahimi if (mbedtls_mpi_read_file(&dhm.MBEDTLS_PRIVATE(P), 16, f) != 0 ||
146*62c56f98SSadaf Ebrahimi mbedtls_mpi_read_file(&dhm.MBEDTLS_PRIVATE(G), 16, f) != 0) {
147*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! Invalid DH parameter file\n\n");
148*62c56f98SSadaf Ebrahimi fclose(f);
149*62c56f98SSadaf Ebrahimi goto exit;
150*62c56f98SSadaf Ebrahimi }
151*62c56f98SSadaf Ebrahimi
152*62c56f98SSadaf Ebrahimi fclose(f);
153*62c56f98SSadaf Ebrahimi
154*62c56f98SSadaf Ebrahimi /*
155*62c56f98SSadaf Ebrahimi * 3. Wait for a client to connect
156*62c56f98SSadaf Ebrahimi */
157*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Waiting for a remote connection");
158*62c56f98SSadaf Ebrahimi fflush(stdout);
159*62c56f98SSadaf Ebrahimi
160*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_net_bind(&listen_fd, NULL, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
161*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_net_bind returned %d\n\n", ret);
162*62c56f98SSadaf Ebrahimi goto exit;
163*62c56f98SSadaf Ebrahimi }
164*62c56f98SSadaf Ebrahimi
165*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_net_accept(&listen_fd, &client_fd,
166*62c56f98SSadaf Ebrahimi NULL, 0, NULL)) != 0) {
167*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_net_accept returned %d\n\n", ret);
168*62c56f98SSadaf Ebrahimi goto exit;
169*62c56f98SSadaf Ebrahimi }
170*62c56f98SSadaf Ebrahimi
171*62c56f98SSadaf Ebrahimi /*
172*62c56f98SSadaf Ebrahimi * 4. Setup the DH parameters (P,G,Ys)
173*62c56f98SSadaf Ebrahimi */
174*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Sending the server's DH parameters");
175*62c56f98SSadaf Ebrahimi fflush(stdout);
176*62c56f98SSadaf Ebrahimi
177*62c56f98SSadaf Ebrahimi memset(buf, 0, sizeof(buf));
178*62c56f98SSadaf Ebrahimi
179*62c56f98SSadaf Ebrahimi if ((ret =
180*62c56f98SSadaf Ebrahimi mbedtls_dhm_make_params(&dhm, (int) mbedtls_mpi_size(&dhm.MBEDTLS_PRIVATE(P)), buf, &n,
181*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
182*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_dhm_make_params returned %d\n\n", ret);
183*62c56f98SSadaf Ebrahimi goto exit;
184*62c56f98SSadaf Ebrahimi }
185*62c56f98SSadaf Ebrahimi
186*62c56f98SSadaf Ebrahimi /*
187*62c56f98SSadaf Ebrahimi * 5. Sign the parameters and send them
188*62c56f98SSadaf Ebrahimi */
189*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_sha1(buf, n, hash)) != 0) {
190*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret);
191*62c56f98SSadaf Ebrahimi goto exit;
192*62c56f98SSadaf Ebrahimi }
193*62c56f98SSadaf Ebrahimi
194*62c56f98SSadaf Ebrahimi buf[n] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len) >> 8);
195*62c56f98SSadaf Ebrahimi buf[n + 1] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len));
196*62c56f98SSadaf Ebrahimi
197*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_MD_SHA256,
198*62c56f98SSadaf Ebrahimi 32, hash, buf + n + 2)) != 0) {
199*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_sign returned %d\n\n", ret);
200*62c56f98SSadaf Ebrahimi goto exit;
201*62c56f98SSadaf Ebrahimi }
202*62c56f98SSadaf Ebrahimi
203*62c56f98SSadaf Ebrahimi buflen = n + 2 + rsa.MBEDTLS_PRIVATE(len);
204*62c56f98SSadaf Ebrahimi buf2[0] = (unsigned char) (buflen >> 8);
205*62c56f98SSadaf Ebrahimi buf2[1] = (unsigned char) (buflen);
206*62c56f98SSadaf Ebrahimi
207*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_net_send(&client_fd, buf2, 2)) != 2 ||
208*62c56f98SSadaf Ebrahimi (ret = mbedtls_net_send(&client_fd, buf, buflen)) != (int) buflen) {
209*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_net_send returned %d\n\n", ret);
210*62c56f98SSadaf Ebrahimi goto exit;
211*62c56f98SSadaf Ebrahimi }
212*62c56f98SSadaf Ebrahimi
213*62c56f98SSadaf Ebrahimi /*
214*62c56f98SSadaf Ebrahimi * 6. Get the client's public value: Yc = G ^ Xc mod P
215*62c56f98SSadaf Ebrahimi */
216*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Receiving the client's public value");
217*62c56f98SSadaf Ebrahimi fflush(stdout);
218*62c56f98SSadaf Ebrahimi
219*62c56f98SSadaf Ebrahimi memset(buf, 0, sizeof(buf));
220*62c56f98SSadaf Ebrahimi
221*62c56f98SSadaf Ebrahimi n = mbedtls_dhm_get_len(&dhm);
222*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_net_recv(&client_fd, buf, n)) != (int) n) {
223*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_net_recv returned %d\n\n", ret);
224*62c56f98SSadaf Ebrahimi goto exit;
225*62c56f98SSadaf Ebrahimi }
226*62c56f98SSadaf Ebrahimi
227*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_dhm_read_public(&dhm, buf, n)) != 0) {
228*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_dhm_read_public returned %d\n\n", ret);
229*62c56f98SSadaf Ebrahimi goto exit;
230*62c56f98SSadaf Ebrahimi }
231*62c56f98SSadaf Ebrahimi
232*62c56f98SSadaf Ebrahimi /*
233*62c56f98SSadaf Ebrahimi * 7. Derive the shared secret: K = Ys ^ Xc mod P
234*62c56f98SSadaf Ebrahimi */
235*62c56f98SSadaf Ebrahimi mbedtls_printf("\n . Shared secret: ");
236*62c56f98SSadaf Ebrahimi fflush(stdout);
237*62c56f98SSadaf Ebrahimi
238*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_dhm_calc_secret(&dhm, buf, sizeof(buf), &n,
239*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
240*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_dhm_calc_secret returned %d\n\n", ret);
241*62c56f98SSadaf Ebrahimi goto exit;
242*62c56f98SSadaf Ebrahimi }
243*62c56f98SSadaf Ebrahimi
244*62c56f98SSadaf Ebrahimi for (n = 0; n < 16; n++) {
245*62c56f98SSadaf Ebrahimi mbedtls_printf("%02x", buf[n]);
246*62c56f98SSadaf Ebrahimi }
247*62c56f98SSadaf Ebrahimi
248*62c56f98SSadaf Ebrahimi /*
249*62c56f98SSadaf Ebrahimi * 8. Setup the AES-256 encryption key
250*62c56f98SSadaf Ebrahimi *
251*62c56f98SSadaf Ebrahimi * This is an overly simplified example; best practice is
252*62c56f98SSadaf Ebrahimi * to hash the shared secret with a random value to derive
253*62c56f98SSadaf Ebrahimi * the keying material for the encryption/decryption keys
254*62c56f98SSadaf Ebrahimi * and MACs.
255*62c56f98SSadaf Ebrahimi */
256*62c56f98SSadaf Ebrahimi mbedtls_printf("...\n . Encrypting and sending the ciphertext");
257*62c56f98SSadaf Ebrahimi fflush(stdout);
258*62c56f98SSadaf Ebrahimi
259*62c56f98SSadaf Ebrahimi ret = mbedtls_aes_setkey_enc(&aes, buf, 256);
260*62c56f98SSadaf Ebrahimi if (ret != 0) {
261*62c56f98SSadaf Ebrahimi goto exit;
262*62c56f98SSadaf Ebrahimi }
263*62c56f98SSadaf Ebrahimi memcpy(buf, PLAINTEXT, 16);
264*62c56f98SSadaf Ebrahimi ret = mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, buf, buf);
265*62c56f98SSadaf Ebrahimi if (ret != 0) {
266*62c56f98SSadaf Ebrahimi goto exit;
267*62c56f98SSadaf Ebrahimi }
268*62c56f98SSadaf Ebrahimi
269*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_net_send(&client_fd, buf, 16)) != 16) {
270*62c56f98SSadaf Ebrahimi mbedtls_printf(" failed\n ! mbedtls_net_send returned %d\n\n", ret);
271*62c56f98SSadaf Ebrahimi goto exit;
272*62c56f98SSadaf Ebrahimi }
273*62c56f98SSadaf Ebrahimi
274*62c56f98SSadaf Ebrahimi mbedtls_printf("\n\n");
275*62c56f98SSadaf Ebrahimi
276*62c56f98SSadaf Ebrahimi exit_code = MBEDTLS_EXIT_SUCCESS;
277*62c56f98SSadaf Ebrahimi
278*62c56f98SSadaf Ebrahimi exit:
279*62c56f98SSadaf Ebrahimi
280*62c56f98SSadaf Ebrahimi mbedtls_mpi_free(&N); mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
281*62c56f98SSadaf Ebrahimi mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
282*62c56f98SSadaf Ebrahimi
283*62c56f98SSadaf Ebrahimi mbedtls_net_free(&client_fd);
284*62c56f98SSadaf Ebrahimi mbedtls_net_free(&listen_fd);
285*62c56f98SSadaf Ebrahimi
286*62c56f98SSadaf Ebrahimi mbedtls_aes_free(&aes);
287*62c56f98SSadaf Ebrahimi mbedtls_rsa_free(&rsa);
288*62c56f98SSadaf Ebrahimi mbedtls_dhm_free(&dhm);
289*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_free(&ctr_drbg);
290*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&entropy);
291*62c56f98SSadaf Ebrahimi
292*62c56f98SSadaf Ebrahimi mbedtls_exit(exit_code);
293*62c56f98SSadaf Ebrahimi }
294*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_AES_C && MBEDTLS_DHM_C && MBEDTLS_ENTROPY_C &&
295*62c56f98SSadaf Ebrahimi MBEDTLS_NET_C && MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA256 &&
296*62c56f98SSadaf Ebrahimi MBEDTLS_FS_IO && MBEDTLS_CTR_DRBG_C */
297