• 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
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8  *  not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  */
19 
20 #include "mbedtls/build_info.h"
21 
22 #include "mbedtls/platform.h"
23 
24 #if !defined(MBEDTLS_ECDH_C) || \
25     !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
26     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
main(void)27 int main(void)
28 {
29     mbedtls_printf("MBEDTLS_ECDH_C and/or "
30                    "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
31                    "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
32                    "not defined\n");
33     mbedtls_exit(0);
34 }
35 #else
36 
37 #include "mbedtls/entropy.h"
38 #include "mbedtls/ctr_drbg.h"
39 #include "mbedtls/ecdh.h"
40 
41 #include <string.h>
42 
43 
main(int argc,char * argv[])44 int main(int argc, char *argv[])
45 {
46     int ret = 1;
47     int exit_code = MBEDTLS_EXIT_FAILURE;
48     mbedtls_ecdh_context ctx_cli, ctx_srv;
49     mbedtls_entropy_context entropy;
50     mbedtls_ctr_drbg_context ctr_drbg;
51     unsigned char cli_to_srv[36], srv_to_cli[33];
52     const char pers[] = "ecdh";
53 
54     size_t srv_olen;
55     size_t cli_olen;
56     unsigned char secret_cli[32] = { 0 };
57     unsigned char secret_srv[32] = { 0 };
58     const unsigned char *p_cli_to_srv = cli_to_srv;
59 
60     ((void) argc);
61     ((void) argv);
62 
63     mbedtls_ecdh_init(&ctx_cli);
64     mbedtls_ecdh_init(&ctx_srv);
65     mbedtls_ctr_drbg_init(&ctr_drbg);
66 
67     /*
68      * Initialize random number generation
69      */
70     mbedtls_printf("  . Seed the random number generator...");
71     fflush(stdout);
72 
73     mbedtls_entropy_init(&entropy);
74     if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
75                                      &entropy,
76                                      (const unsigned char *) pers,
77                                      sizeof(pers))) != 0) {
78         mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
79                        ret);
80         goto exit;
81     }
82 
83     mbedtls_printf(" ok\n");
84 
85     /*
86      * Client: initialize context and generate keypair
87      */
88     mbedtls_printf("  . Set up client context, generate EC key pair...");
89     fflush(stdout);
90 
91     ret = mbedtls_ecdh_setup(&ctx_cli, MBEDTLS_ECP_DP_CURVE25519);
92     if (ret != 0) {
93         mbedtls_printf(" failed\n  ! mbedtls_ecdh_setup returned %d\n", ret);
94         goto exit;
95     }
96 
97     ret = mbedtls_ecdh_make_params(&ctx_cli, &cli_olen, cli_to_srv,
98                                    sizeof(cli_to_srv),
99                                    mbedtls_ctr_drbg_random, &ctr_drbg);
100     if (ret != 0) {
101         mbedtls_printf(" failed\n  ! mbedtls_ecdh_make_params returned %d\n",
102                        ret);
103         goto exit;
104     }
105 
106     mbedtls_printf(" ok\n");
107 
108     /*
109      * Server: initialize context and generate keypair
110      */
111     mbedtls_printf("  . Server: read params, generate public key...");
112     fflush(stdout);
113 
114     ret = mbedtls_ecdh_read_params(&ctx_srv, &p_cli_to_srv,
115                                    p_cli_to_srv + sizeof(cli_to_srv));
116     if (ret != 0) {
117         mbedtls_printf(" failed\n  ! mbedtls_ecdh_read_params returned %d\n",
118                        ret);
119         goto exit;
120     }
121 
122     ret = mbedtls_ecdh_make_public(&ctx_srv, &srv_olen, srv_to_cli,
123                                    sizeof(srv_to_cli),
124                                    mbedtls_ctr_drbg_random, &ctr_drbg);
125     if (ret != 0) {
126         mbedtls_printf(" failed\n  ! mbedtls_ecdh_make_public returned %d\n",
127                        ret);
128         goto exit;
129     }
130 
131     mbedtls_printf(" ok\n");
132 
133     /*
134      * Client: read public key
135      */
136     mbedtls_printf("  . Client: read public key...");
137     fflush(stdout);
138 
139     ret = mbedtls_ecdh_read_public(&ctx_cli, srv_to_cli,
140                                    sizeof(srv_to_cli));
141     if (ret != 0) {
142         mbedtls_printf(" failed\n  ! mbedtls_ecdh_read_public returned %d\n",
143                        ret);
144         goto exit;
145     }
146 
147     mbedtls_printf(" ok\n");
148 
149     /*
150      * Calculate secrets
151      */
152     mbedtls_printf("  . Calculate secrets...");
153     fflush(stdout);
154 
155     ret = mbedtls_ecdh_calc_secret(&ctx_cli, &cli_olen, secret_cli,
156                                    sizeof(secret_cli),
157                                    mbedtls_ctr_drbg_random, &ctr_drbg);
158     if (ret != 0) {
159         mbedtls_printf(" failed\n  ! mbedtls_ecdh_calc_secret returned %d\n",
160                        ret);
161         goto exit;
162     }
163 
164     ret = mbedtls_ecdh_calc_secret(&ctx_srv, &srv_olen, secret_srv,
165                                    sizeof(secret_srv),
166                                    mbedtls_ctr_drbg_random, &ctr_drbg);
167     if (ret != 0) {
168         mbedtls_printf(" failed\n  ! mbedtls_ecdh_calc_secret returned %d\n",
169                        ret);
170         goto exit;
171     }
172 
173     mbedtls_printf(" ok\n");
174 
175     /*
176      * Verification: are the computed secrets equal?
177      */
178     mbedtls_printf("  . Check if both calculated secrets are equal...");
179     fflush(stdout);
180 
181     ret = memcmp(secret_srv, secret_cli, srv_olen);
182     if (ret != 0 || (cli_olen != srv_olen)) {
183         mbedtls_printf(" failed\n  ! Shared secrets not equal.\n");
184         goto exit;
185     }
186 
187     mbedtls_printf(" ok\n");
188 
189     exit_code = MBEDTLS_EXIT_SUCCESS;
190 
191 exit:
192 
193     mbedtls_ecdh_free(&ctx_srv);
194     mbedtls_ecdh_free(&ctx_cli);
195     mbedtls_ctr_drbg_free(&ctr_drbg);
196     mbedtls_entropy_free(&entropy);
197 
198     mbedtls_exit(exit_code);
199 }
200 #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED &&
201           MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
202