Skip to content

Commit f66346e

Browse files
gilles-peskine-armronald-cron-arm
authored andcommitted
Revert "Remove Diffie-Hellman examples"
This reverts commit bea98b4. Conflicts: * programs/Makefile: * APPS: the layout of the definition has changed. re-add dh_client and dh_server appropriately. Run scripts/generate_visualc_files.pl to account for the added programs.
1 parent 1bc9c13 commit f66346e

File tree

9 files changed

+1074
-1
lines changed

9 files changed

+1074
-1
lines changed

programs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ hash/hello
99
hash/md5sum
1010
hash/sha1sum
1111
hash/sha2sum
12+
pkey/dh_client
1213
pkey/dh_genprime
14+
pkey/dh_server
1315
pkey/ecdsa
1416
pkey/ecdh_curve25519
1517
pkey/gen_key

programs/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ APPS = \
5555
aes/crypt_and_hash$(EXEXT) \
5656
hash/hello$(EXEXT) \
5757
hash/generic_sum$(EXEXT) \
58+
pkey/dh_client$(EXEXT) \
5859
pkey/dh_genprime$(EXEXT) \
60+
pkey/dh_server$(EXEXT) \
5961
pkey/ecdh_curve25519$(EXEXT) \
6062
pkey/ecdsa$(EXEXT) \
6163
pkey/gen_key$(EXEXT) \
@@ -147,10 +149,18 @@ hash/generic_sum$(EXEXT): hash/generic_sum.c $(DEP)
147149
echo " CC hash/generic_sum.c"
148150
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/generic_sum.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
149151

152+
pkey/dh_client$(EXEXT): pkey/dh_client.c $(DEP)
153+
echo " CC pkey/dh_client.c"
154+
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/dh_client.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
155+
150156
pkey/dh_genprime$(EXEXT): pkey/dh_genprime.c $(DEP)
151157
echo " CC pkey/dh_genprime.c"
152158
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/dh_genprime.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
153159

160+
pkey/dh_server$(EXEXT): pkey/dh_server.c $(DEP)
161+
echo " CC pkey/dh_server.c"
162+
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/dh_server.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
163+
154164
pkey/ecdh_curve25519$(EXEXT): pkey/ecdh_curve25519.c $(DEP)
155165
echo " CC pkey/ecdh_curve25519.c"
156166
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/ecdh_curve25519.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@

programs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ This subdirectory mostly contains sample programs that illustrate specific featu
4444

4545
### Diffie-Hellman key exchange examples
4646

47+
* [`pkey/dh_client.c`](pkey/dh_client.c), [`pkey/dh_server.c`](pkey/dh_server.c): secure channel demonstrators (client, server). This pair of programs illustrates how to set up a secure channel using RSA for authentication and Diffie-Hellman to generate a shared AES session key.
48+
4749
* [`pkey/ecdh_curve25519.c`](pkey/ecdh_curve25519.c): demonstration of a elliptic curve Diffie-Hellman (ECDH) key agreement.
4850

4951
### Bignum (`mpi`) usage examples

programs/pkey/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
add_executable(dh_client dh_client.c)
2+
target_link_libraries(dh_client mbedtls)
3+
14
add_executable(dh_genprime dh_genprime.c)
25
target_link_libraries(dh_genprime mbedtls)
36

7+
add_executable(dh_server dh_server.c)
8+
target_link_libraries(dh_server mbedtls)
9+
410
add_executable(ecdh_curve25519 ecdh_curve25519.c)
511
target_link_libraries(ecdh_curve25519 mbedtls)
612

@@ -52,6 +58,6 @@ target_link_libraries(pk_encrypt mbedtls)
5258
add_executable(pk_decrypt pk_decrypt.c)
5359
target_link_libraries(pk_decrypt mbedtls)
5460

55-
install(TARGETS dh_genprime key_app mpi_demo rsa_genkey rsa_sign rsa_verify rsa_encrypt rsa_decrypt pk_encrypt pk_decrypt pk_sign pk_verify gen_key
61+
install(TARGETS dh_client dh_genprime dh_server key_app mpi_demo rsa_genkey rsa_sign rsa_verify rsa_encrypt rsa_decrypt pk_encrypt pk_decrypt pk_sign pk_verify gen_key
5662
DESTINATION "bin"
5763
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

programs/pkey/dh_client.c

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
/*
2+
* Diffie-Hellman-Merkle key exchange (client side)
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_time_t time_t
35+
#define mbedtls_exit exit
36+
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
37+
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
38+
#endif /* MBEDTLS_PLATFORM_C */
39+
40+
#if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
41+
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \
42+
defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) && \
43+
defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) && \
44+
defined(MBEDTLS_SHA1_C)
45+
#include "mbedtls/net_sockets.h"
46+
#include "mbedtls/aes.h"
47+
#include "mbedtls/dhm.h"
48+
#include "mbedtls/rsa.h"
49+
#include "mbedtls/sha1.h"
50+
#include "mbedtls/entropy.h"
51+
#include "mbedtls/ctr_drbg.h"
52+
53+
#include <stdio.h>
54+
#include <string.h>
55+
#endif
56+
57+
#define SERVER_NAME "localhost"
58+
#define SERVER_PORT "11999"
59+
60+
#if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \
61+
!defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \
62+
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_SHA256_C) || \
63+
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) || \
64+
!defined(MBEDTLS_SHA1_C)
65+
int main( void )
66+
{
67+
mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C "
68+
"and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
69+
"MBEDTLS_SHA256_C and/or MBEDTLS_FS_IO and/or "
70+
"MBEDTLS_CTR_DRBG_C not defined.\n");
71+
return( 0 );
72+
}
73+
#else
74+
75+
#if defined(MBEDTLS_CHECK_PARAMS)
76+
#include "mbedtls/platform_util.h"
77+
void mbedtls_param_failed( const char *failure_condition,
78+
const char *file,
79+
int line )
80+
{
81+
mbedtls_printf( "%s:%i: Input param failed - %s\n",
82+
file, line, failure_condition );
83+
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
84+
}
85+
#endif
86+
87+
int main( void )
88+
{
89+
FILE *f;
90+
91+
int ret = 1;
92+
int exit_code = MBEDTLS_EXIT_FAILURE;
93+
size_t n, buflen;
94+
mbedtls_net_context server_fd;
95+
96+
unsigned char *p, *end;
97+
unsigned char buf[2048];
98+
unsigned char hash[32];
99+
const char *pers = "dh_client";
100+
101+
mbedtls_entropy_context entropy;
102+
mbedtls_ctr_drbg_context ctr_drbg;
103+
mbedtls_rsa_context rsa;
104+
mbedtls_dhm_context dhm;
105+
mbedtls_aes_context aes;
106+
107+
mbedtls_net_init( &server_fd );
108+
mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256 );
109+
mbedtls_dhm_init( &dhm );
110+
mbedtls_aes_init( &aes );
111+
mbedtls_ctr_drbg_init( &ctr_drbg );
112+
113+
/*
114+
* 1. Setup the RNG
115+
*/
116+
mbedtls_printf( "\n . Seeding the random number generator" );
117+
fflush( stdout );
118+
119+
mbedtls_entropy_init( &entropy );
120+
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
121+
(const unsigned char *) pers,
122+
strlen( pers ) ) ) != 0 )
123+
{
124+
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
125+
goto exit;
126+
}
127+
128+
/*
129+
* 2. Read the server's public RSA key
130+
*/
131+
mbedtls_printf( "\n . Reading public key from rsa_pub.txt" );
132+
fflush( stdout );
133+
134+
if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
135+
{
136+
mbedtls_printf( " failed\n ! Could not open rsa_pub.txt\n" \
137+
" ! Please run rsa_genkey first\n\n" );
138+
goto exit;
139+
}
140+
141+
mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
142+
143+
if( ( ret = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
144+
( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
145+
{
146+
mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret );
147+
fclose( f );
148+
goto exit;
149+
}
150+
151+
rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3;
152+
153+
fclose( f );
154+
155+
/*
156+
* 3. Initiate the connection
157+
*/
158+
mbedtls_printf( "\n . Connecting to tcp/%s/%s", SERVER_NAME,
159+
SERVER_PORT );
160+
fflush( stdout );
161+
162+
if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
163+
SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
164+
{
165+
mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
166+
goto exit;
167+
}
168+
169+
/*
170+
* 4a. First get the buffer length
171+
*/
172+
mbedtls_printf( "\n . Receiving the server's DH parameters" );
173+
fflush( stdout );
174+
175+
memset( buf, 0, sizeof( buf ) );
176+
177+
if( ( ret = mbedtls_net_recv( &server_fd, buf, 2 ) ) != 2 )
178+
{
179+
mbedtls_printf( " failed\n ! mbedtls_net_recv returned %d\n\n", ret );
180+
goto exit;
181+
}
182+
183+
n = buflen = ( buf[0] << 8 ) | buf[1];
184+
if( buflen < 1 || buflen > sizeof( buf ) )
185+
{
186+
mbedtls_printf( " failed\n ! Got an invalid buffer length\n\n" );
187+
goto exit;
188+
}
189+
190+
/*
191+
* 4b. Get the DHM parameters: P, G and Ys = G^Xs mod P
192+
*/
193+
memset( buf, 0, sizeof( buf ) );
194+
195+
if( ( ret = mbedtls_net_recv( &server_fd, buf, n ) ) != (int) n )
196+
{
197+
mbedtls_printf( " failed\n ! mbedtls_net_recv returned %d\n\n", ret );
198+
goto exit;
199+
}
200+
201+
p = buf, end = buf + buflen;
202+
203+
if( ( ret = mbedtls_dhm_read_params( &dhm, &p, end ) ) != 0 )
204+
{
205+
mbedtls_printf( " failed\n ! mbedtls_dhm_read_params returned %d\n\n", ret );
206+
goto exit;
207+
}
208+
209+
if( dhm.len < 64 || dhm.len > 512 )
210+
{
211+
mbedtls_printf( " failed\n ! Invalid DHM modulus size\n\n" );
212+
goto exit;
213+
}
214+
215+
/*
216+
* 5. Check that the server's RSA signature matches
217+
* the SHA-256 hash of (P,G,Ys)
218+
*/
219+
mbedtls_printf( "\n . Verifying the server's RSA signature" );
220+
fflush( stdout );
221+
222+
p += 2;
223+
224+
if( ( n = (size_t) ( end - p ) ) != rsa.len )
225+
{
226+
mbedtls_printf( " failed\n ! Invalid RSA signature size\n\n" );
227+
goto exit;
228+
}
229+
230+
if( ( ret = mbedtls_sha1_ret( buf, (int)( p - 2 - buf ), hash ) ) != 0 )
231+
{
232+
mbedtls_printf( " failed\n ! mbedtls_sha1_ret returned %d\n\n", ret );
233+
goto exit;
234+
}
235+
236+
if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC,
237+
MBEDTLS_MD_SHA256, 0, hash, p ) ) != 0 )
238+
{
239+
mbedtls_printf( " failed\n ! mbedtls_rsa_pkcs1_verify returned %d\n\n", ret );
240+
goto exit;
241+
}
242+
243+
/*
244+
* 6. Send our public value: Yc = G ^ Xc mod P
245+
*/
246+
mbedtls_printf( "\n . Sending own public value to server" );
247+
fflush( stdout );
248+
249+
n = dhm.len;
250+
if( ( ret = mbedtls_dhm_make_public( &dhm, (int) dhm.len, buf, n,
251+
mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
252+
{
253+
mbedtls_printf( " failed\n ! mbedtls_dhm_make_public returned %d\n\n", ret );
254+
goto exit;
255+
}
256+
257+
if( ( ret = mbedtls_net_send( &server_fd, buf, n ) ) != (int) n )
258+
{
259+
mbedtls_printf( " failed\n ! mbedtls_net_send returned %d\n\n", ret );
260+
goto exit;
261+
}
262+
263+
/*
264+
* 7. Derive the shared secret: K = Ys ^ Xc mod P
265+
*/
266+
mbedtls_printf( "\n . Shared secret: " );
267+
fflush( stdout );
268+
269+
if( ( ret = mbedtls_dhm_calc_secret( &dhm, buf, sizeof( buf ), &n,
270+
mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
271+
{
272+
mbedtls_printf( " failed\n ! mbedtls_dhm_calc_secret returned %d\n\n", ret );
273+
goto exit;
274+
}
275+
276+
for( n = 0; n < 16; n++ )
277+
mbedtls_printf( "%02x", buf[n] );
278+
279+
/*
280+
* 8. Setup the AES-256 decryption key
281+
*
282+
* This is an overly simplified example; best practice is
283+
* to hash the shared secret with a random value to derive
284+
* the keying material for the encryption/decryption keys,
285+
* IVs and MACs.
286+
*/
287+
mbedtls_printf( "...\n . Receiving and decrypting the ciphertext" );
288+
fflush( stdout );
289+
290+
mbedtls_aes_setkey_dec( &aes, buf, 256 );
291+
292+
memset( buf, 0, sizeof( buf ) );
293+
294+
if( ( ret = mbedtls_net_recv( &server_fd, buf, 16 ) ) != 16 )
295+
{
296+
mbedtls_printf( " failed\n ! mbedtls_net_recv returned %d\n\n", ret );
297+
goto exit;
298+
}
299+
300+
mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
301+
buf[16] = '\0';
302+
mbedtls_printf( "\n . Plaintext is \"%s\"\n\n", (char *) buf );
303+
304+
exit_code = MBEDTLS_EXIT_SUCCESS;
305+
306+
exit:
307+
308+
mbedtls_net_free( &server_fd );
309+
310+
mbedtls_aes_free( &aes );
311+
mbedtls_rsa_free( &rsa );
312+
mbedtls_dhm_free( &dhm );
313+
mbedtls_ctr_drbg_free( &ctr_drbg );
314+
mbedtls_entropy_free( &entropy );
315+
316+
#if defined(_WIN32)
317+
mbedtls_printf( " + Press Enter to exit this program.\n" );
318+
fflush( stdout ); getchar();
319+
#endif
320+
321+
return( exit_code );
322+
}
323+
#endif /* MBEDTLS_AES_C && MBEDTLS_DHM_C && MBEDTLS_ENTROPY_C &&
324+
MBEDTLS_NET_C && MBEDTLS_RSA_C && MBEDTLS_SHA256_C &&
325+
MBEDTLS_FS_IO && MBEDTLS_CTR_DRBG_C */

0 commit comments

Comments
 (0)