• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Example ECDHE with Curve25519 program
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  */
7 
8 #if !defined(MBEDTLS_CONFIG_FILE)
9 #include "mbedtls/config.h"
10 #else
11 #include MBEDTLS_CONFIG_FILE
12 #endif
13 
14 #include "mbedtls/platform.h"
15 
16 #if !defined(MBEDTLS_ECDH_C) || \
17     !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
18     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
main(void)19 int main(void)
20 {
21     mbedtls_printf("MBEDTLS_ECDH_C and/or "
22                    "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
23                    "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
24                    "not defined\n");
25     mbedtls_exit(0);
26 }
27 #else
28 
29 #include "mbedtls/entropy.h"
30 #include "mbedtls/ctr_drbg.h"
31 #include "mbedtls/ecdh.h"
32 
33 #include <string.h>
34 
35 
main(int argc,char * argv[])36 int main(int argc, char *argv[])
37 {
38     int ret = 1;
39     int exit_code = MBEDTLS_EXIT_FAILURE;
40     mbedtls_ecdh_context ctx_cli, ctx_srv;
41     mbedtls_entropy_context entropy;
42     mbedtls_ctr_drbg_context ctr_drbg;
43     unsigned char cli_to_srv[36], srv_to_cli[33];
44     const char pers[] = "ecdh";
45 
46     size_t srv_olen;
47     size_t cli_olen;
48     unsigned char secret_cli[32] = { 0 };
49     unsigned char secret_srv[32] = { 0 };
50     const unsigned char *p_cli_to_srv = cli_to_srv;
51 
52     ((void) argc);
53     ((void) argv);
54 
55     mbedtls_ecdh_init(&ctx_cli);
56     mbedtls_ecdh_init(&ctx_srv);
57     mbedtls_ctr_drbg_init(&ctr_drbg);
58 
59     /*
60      * Initialize random number generation
61      */
62     mbedtls_printf("  . Seed the random number generator...");
63     fflush(stdout);
64 
65     mbedtls_entropy_init(&entropy);
66     if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
67                                      &entropy,
68                                      (const unsigned char *) pers,
69                                      sizeof(pers))) != 0) {
70         mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
71                        ret);
72         goto exit;
73     }
74 
75     mbedtls_printf(" ok\n");
76 
77     /*
78      * Client: initialize context and generate keypair
79      */
80     mbedtls_printf("  . Set up client context, generate EC key pair...");
81     fflush(stdout);
82 
83     ret = mbedtls_ecdh_setup(&ctx_cli, MBEDTLS_ECP_DP_CURVE25519);
84     if (ret != 0) {
85         mbedtls_printf(" failed\n  ! mbedtls_ecdh_setup returned %d\n", ret);
86         goto exit;
87     }
88 
89     ret = mbedtls_ecdh_make_params(&ctx_cli, &cli_olen, cli_to_srv,
90                                    sizeof(cli_to_srv),
91                                    mbedtls_ctr_drbg_random, &ctr_drbg);
92     if (ret != 0) {
93         mbedtls_printf(" failed\n  ! mbedtls_ecdh_make_params returned %d\n",
94                        ret);
95         goto exit;
96     }
97 
98     mbedtls_printf(" ok\n");
99 
100     /*
101      * Server: initialize context and generate keypair
102      */
103     mbedtls_printf("  . Server: read params, generate public key...");
104     fflush(stdout);
105 
106     ret = mbedtls_ecdh_read_params(&ctx_srv, &p_cli_to_srv,
107                                    p_cli_to_srv + sizeof(cli_to_srv));
108     if (ret != 0) {
109         mbedtls_printf(" failed\n  ! mbedtls_ecdh_read_params returned %d\n",
110                        ret);
111         goto exit;
112     }
113 
114     ret = mbedtls_ecdh_make_public(&ctx_srv, &srv_olen, srv_to_cli,
115                                    sizeof(srv_to_cli),
116                                    mbedtls_ctr_drbg_random, &ctr_drbg);
117     if (ret != 0) {
118         mbedtls_printf(" failed\n  ! mbedtls_ecdh_make_public returned %d\n",
119                        ret);
120         goto exit;
121     }
122 
123     mbedtls_printf(" ok\n");
124 
125     /*
126      * Client: read public key
127      */
128     mbedtls_printf("  . Client: read public key...");
129     fflush(stdout);
130 
131     ret = mbedtls_ecdh_read_public(&ctx_cli, srv_to_cli,
132                                    sizeof(srv_to_cli));
133     if (ret != 0) {
134         mbedtls_printf(" failed\n  ! mbedtls_ecdh_read_public returned %d\n",
135                        ret);
136         goto exit;
137     }
138 
139     mbedtls_printf(" ok\n");
140 
141     /*
142      * Calculate secrets
143      */
144     mbedtls_printf("  . Calculate secrets...");
145     fflush(stdout);
146 
147     ret = mbedtls_ecdh_calc_secret(&ctx_cli, &cli_olen, secret_cli,
148                                    sizeof(secret_cli),
149                                    mbedtls_ctr_drbg_random, &ctr_drbg);
150     if (ret != 0) {
151         mbedtls_printf(" failed\n  ! mbedtls_ecdh_calc_secret returned %d\n",
152                        ret);
153         goto exit;
154     }
155 
156     ret = mbedtls_ecdh_calc_secret(&ctx_srv, &srv_olen, secret_srv,
157                                    sizeof(secret_srv),
158                                    mbedtls_ctr_drbg_random, &ctr_drbg);
159     if (ret != 0) {
160         mbedtls_printf(" failed\n  ! mbedtls_ecdh_calc_secret returned %d\n",
161                        ret);
162         goto exit;
163     }
164 
165     mbedtls_printf(" ok\n");
166 
167     /*
168      * Verification: are the computed secrets equal?
169      */
170     mbedtls_printf("  . Check if both calculated secrets are equal...");
171     fflush(stdout);
172 
173     ret = memcmp(secret_srv, secret_cli, srv_olen);
174     if (ret != 0 || (cli_olen != srv_olen)) {
175         mbedtls_printf(" failed\n  ! Shared secrets not equal.\n");
176         goto exit;
177     }
178 
179     mbedtls_printf(" ok\n");
180 
181     exit_code = MBEDTLS_EXIT_SUCCESS;
182 
183 exit:
184 
185 #if defined(_WIN32)
186     mbedtls_printf("  + Press Enter to exit this program.\n");
187     fflush(stdout); getchar();
188 #endif
189 
190     mbedtls_ecdh_free(&ctx_srv);
191     mbedtls_ecdh_free(&ctx_cli);
192     mbedtls_ctr_drbg_free(&ctr_drbg);
193     mbedtls_entropy_free(&entropy);
194 
195     mbedtls_exit(exit_code);
196 }
197 #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED &&
198           MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
199