1 /*
2 * Example ECDHE with Curve25519 program
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
24 #else
25 #include MBEDTLS_CONFIG_FILE
26 #endif
27
28 #if defined(MBEDTLS_PLATFORM_C)
29 #include "mbedtls/platform.h"
30 #else
31 #include <stdio.h>
32 #include <stdlib.h>
33 #define mbedtls_printf printf
34 #define mbedtls_exit exit
35 #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
36 #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
37 #endif /* MBEDTLS_PLATFORM_C */
38
39 #if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
40 !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
41 !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
main(void)42 int main( void )
43 {
44 mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
45 "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
46 "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
47 "not defined\n" );
48 return( 0 );
49 }
50 #else
51
52 #include "mbedtls/entropy.h"
53 #include "mbedtls/ctr_drbg.h"
54 #include "mbedtls/ecdh.h"
55
56 #if defined(MBEDTLS_CHECK_PARAMS)
57 #include "mbedtls/platform_util.h"
mbedtls_param_failed(const char * failure_condition,const char * file,int line)58 void mbedtls_param_failed( const char *failure_condition,
59 const char *file,
60 int line )
61 {
62 mbedtls_printf( "%s:%i: Input param failed - %s\n",
63 file, line, failure_condition );
64 mbedtls_exit( MBEDTLS_EXIT_FAILURE );
65 }
66 #endif
67
main(int argc,char * argv[])68 int main( int argc, char *argv[] )
69 {
70 int ret = 1;
71 int exit_code = MBEDTLS_EXIT_FAILURE;
72 mbedtls_ecdh_context ctx_cli, ctx_srv;
73 mbedtls_entropy_context entropy;
74 mbedtls_ctr_drbg_context ctr_drbg;
75 unsigned char cli_to_srv[32], srv_to_cli[32];
76 const char pers[] = "ecdh";
77 ((void) argc);
78 ((void) argv);
79
80 mbedtls_ecdh_init( &ctx_cli );
81 mbedtls_ecdh_init( &ctx_srv );
82 mbedtls_ctr_drbg_init( &ctr_drbg );
83
84 /*
85 * Initialize random number generation
86 */
87 mbedtls_printf( " . Seeding the random number generator..." );
88 fflush( stdout );
89
90 mbedtls_entropy_init( &entropy );
91 if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
92 (const unsigned char *) pers,
93 sizeof pers ) ) != 0 )
94 {
95 mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
96 goto exit;
97 }
98
99 mbedtls_printf( " ok\n" );
100
101 /*
102 * Client: inialize context and generate keypair
103 */
104 mbedtls_printf( " . Setting up client context..." );
105 fflush( stdout );
106
107 ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 );
108 if( ret != 0 )
109 {
110 mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
111 goto exit;
112 }
113
114 ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
115 mbedtls_ctr_drbg_random, &ctr_drbg );
116 if( ret != 0 )
117 {
118 mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
119 goto exit;
120 }
121
122 ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 );
123 if( ret != 0 )
124 {
125 mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
126 goto exit;
127 }
128
129 mbedtls_printf( " ok\n" );
130
131 /*
132 * Server: initialize context and generate keypair
133 */
134 mbedtls_printf( " . Setting up server context..." );
135 fflush( stdout );
136
137 ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 );
138 if( ret != 0 )
139 {
140 mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
141 goto exit;
142 }
143
144 ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q,
145 mbedtls_ctr_drbg_random, &ctr_drbg );
146 if( ret != 0 )
147 {
148 mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
149 goto exit;
150 }
151
152 ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 );
153 if( ret != 0 )
154 {
155 mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
156 goto exit;
157 }
158
159 mbedtls_printf( " ok\n" );
160
161 /*
162 * Server: read peer's key and generate shared secret
163 */
164 mbedtls_printf( " . Server reading client key and computing secret..." );
165 fflush( stdout );
166
167 ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 );
168 if( ret != 0 )
169 {
170 mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
171 goto exit;
172 }
173
174 ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 );
175 if( ret != 0 )
176 {
177 mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
178 goto exit;
179 }
180
181 ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z,
182 &ctx_srv.Qp, &ctx_srv.d,
183 mbedtls_ctr_drbg_random, &ctr_drbg );
184 if( ret != 0 )
185 {
186 mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
187 goto exit;
188 }
189
190 mbedtls_printf( " ok\n" );
191
192 /*
193 * Client: read peer's key and generate shared secret
194 */
195 mbedtls_printf( " . Client reading server key and computing secret..." );
196 fflush( stdout );
197
198 ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 );
199 if( ret != 0 )
200 {
201 mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
202 goto exit;
203 }
204
205 ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 );
206 if( ret != 0 )
207 {
208 mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
209 goto exit;
210 }
211
212 ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z,
213 &ctx_cli.Qp, &ctx_cli.d,
214 mbedtls_ctr_drbg_random, &ctr_drbg );
215 if( ret != 0 )
216 {
217 mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
218 goto exit;
219 }
220
221 mbedtls_printf( " ok\n" );
222
223 /*
224 * Verification: are the computed secrets equal?
225 */
226 mbedtls_printf( " . Checking if both computed secrets are equal..." );
227 fflush( stdout );
228
229 ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z );
230 if( ret != 0 )
231 {
232 mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
233 goto exit;
234 }
235
236 mbedtls_printf( " ok\n" );
237
238 exit_code = MBEDTLS_EXIT_SUCCESS;
239
240 exit:
241
242 #if defined(_WIN32)
243 mbedtls_printf( " + Press Enter to exit this program.\n" );
244 fflush( stdout ); getchar();
245 #endif
246
247 mbedtls_ecdh_free( &ctx_srv );
248 mbedtls_ecdh_free( &ctx_cli );
249 mbedtls_ctr_drbg_free( &ctr_drbg );
250 mbedtls_entropy_free( &entropy );
251
252 return( exit_code );
253 }
254 #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED &&
255 MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
256