blob: bc43016656dc371d9f39461ff650c41f2ebe9b16 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/dhm.h"
Gilles Peskine02db8f42021-03-30 23:28:51 +02003
Gilles Peskine71acc6e2021-05-27 22:50:53 +02004int check_get_value( const mbedtls_dhm_context *ctx,
5 mbedtls_dhm_parameter param,
6 const mbedtls_mpi *expected )
7{
8 mbedtls_mpi actual;
9 int ok = 0;
10 mbedtls_mpi_init( &actual );
11
Gilles Peskinee5702482021-06-11 21:59:08 +020012 TEST_ASSERT( mbedtls_dhm_get_value( ctx, param, &actual ) == 0 );
Gilles Peskine71acc6e2021-05-27 22:50:53 +020013 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual, expected ) == 0 );
14 ok = 1;
15
16exit:
17 mbedtls_mpi_free( &actual );
18 return( ok );
19}
20
Gilles Peskine19e36202021-04-13 22:16:45 +020021/* Sanity checks on a Diffie-Hellman parameter: check the length-value
22 * syntax and check that the value is the expected one (taken from the
23 * DHM context by the caller). */
Gilles Peskine02db8f42021-03-30 23:28:51 +020024static int check_dhm_param_output( const mbedtls_mpi *expected,
25 const unsigned char *buffer,
26 size_t size,
27 size_t *offset )
28{
29 size_t n;
30 mbedtls_mpi actual;
31 int ok = 0;
32 mbedtls_mpi_init( &actual );
33
34 ++mbedtls_test_info.step;
35
36 TEST_ASSERT( size >= *offset + 2 );
37 n = ( buffer[*offset] << 8 ) | buffer[*offset + 1];
38 *offset += 2;
Gilles Peskine03299dc2021-04-13 22:10:24 +020039 /* The DHM param output from Mbed TLS has leading zeros stripped, as
40 * permitted but not required by RFC 5246 \S4.4. */
Gilles Peskine02db8f42021-03-30 23:28:51 +020041 TEST_EQUAL( n, mbedtls_mpi_size( expected ) );
42 TEST_ASSERT( size >= *offset + n );
43 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &actual, buffer + *offset, n ) );
44 TEST_EQUAL( 0, mbedtls_mpi_cmp_mpi( expected, &actual ) );
45 *offset += n;
46
47 ok = 1;
48exit:
49 mbedtls_mpi_free( &actual );
50 return( ok );
51}
52
Gilles Peskine19e36202021-04-13 22:16:45 +020053/* Sanity checks on Diffie-Hellman parameters: syntax, range, and comparison
54 * against the context. */
Gilles Peskine02db8f42021-03-30 23:28:51 +020055static int check_dhm_params( const mbedtls_dhm_context *ctx,
56 size_t x_size,
57 const unsigned char *ske, size_t ske_len )
58{
59 size_t offset = 0;
60
61 /* Check that ctx->X and ctx->GX are within range. */
62 TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->X, 1 ) > 0 );
63 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) < 0 );
64 TEST_ASSERT( mbedtls_mpi_size( &ctx->X ) <= x_size );
65 TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->GX, 1 ) > 0 );
66 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->GX, &ctx->P ) < 0 );
67
68 /* Check ske: it must contain P, G and G^X, each prefixed with a
69 * 2-byte size. */
70 if( !check_dhm_param_output( &ctx->P, ske, ske_len, &offset ) )
71 goto exit;
72 if( !check_dhm_param_output( &ctx->G, ske, ske_len, &offset ) )
73 goto exit;
74 if( !check_dhm_param_output( &ctx->GX, ske, ske_len, &offset ) )
75 goto exit;
76 TEST_EQUAL( offset, ske_len );
77
78 return( 1 );
79exit:
80 return( 0 );
81}
82
Paul Bakker33b43f12013-08-20 11:48:36 +020083/* END_HEADER */
Paul Bakker5c60de22009-07-08 19:47:36 +000084
Paul Bakker33b43f12013-08-20 11:48:36 +020085/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020086 * depends_on:MBEDTLS_DHM_C:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020087 * END_DEPENDENCIES
88 */
Paul Bakker5690efc2011-05-26 13:16:06 +000089
Paul Bakker33b43f12013-08-20 11:48:36 +020090/* BEGIN_CASE */
Gilles Peskine2baf2b02021-03-30 23:44:22 +020091void dhm_do_dhm( int radix_P, char *input_P, int x_size,
Janos Follath4b151fa2017-09-20 13:46:37 +010092 int radix_G, char *input_G, int result )
Paul Bakker5c60de22009-07-08 19:47:36 +000093{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020094 mbedtls_dhm_context ctx_srv;
95 mbedtls_dhm_context ctx_cli;
Paul Bakker5c60de22009-07-08 19:47:36 +000096 unsigned char ske[1000];
97 unsigned char *p = ske;
98 unsigned char pub_cli[1000];
99 unsigned char sec_srv[1000];
100 unsigned char sec_cli[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000101 size_t ske_len = 0;
102 size_t pub_cli_len = 0;
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100103 size_t sec_srv_len;
104 size_t sec_cli_len;
Gilles Peskine2baf2b02021-03-30 23:44:22 +0200105 int i;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200106 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker5c60de22009-07-08 19:47:36 +0000107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 mbedtls_dhm_init( &ctx_srv );
109 mbedtls_dhm_init( &ctx_cli );
Paul Bakker5c60de22009-07-08 19:47:36 +0000110 memset( ske, 0x00, 1000 );
111 memset( pub_cli, 0x00, 1000 );
112 memset( sec_srv, 0x00, 1000 );
113 memset( sec_cli, 0x00, 1000 );
Ronald Cron351f0ee2020-06-10 12:12:18 +0200114 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
Paul Bakker5c60de22009-07-08 19:47:36 +0000115
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200116 /*
117 * Set params
118 */
Gilles Peskine20edee72021-06-10 23:18:39 +0200119 TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.P, radix_P, input_P ) == 0 );
120 TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.G, radix_G, input_G ) == 0 );
Gilles Peskine2baf2b02021-03-30 23:44:22 +0200121 pub_cli_len = mbedtls_mpi_size( &ctx_srv.P );
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200122 TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_P, &ctx_srv.P ) );
123 TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_G, &ctx_srv.G ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200124
125 /*
126 * First key exchange
127 */
Gilles Peskine02db8f42021-03-30 23:28:51 +0200128 mbedtls_test_set_step( 10 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200129 TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
130 &mbedtls_test_rnd_pseudo_rand,
131 &rnd_info ) == result );
Janos Follath4b151fa2017-09-20 13:46:37 +0100132 if ( result != 0 )
133 goto exit;
Gilles Peskine02db8f42021-03-30 23:28:51 +0200134 if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) )
135 goto exit;
Janos Follath4b151fa2017-09-20 13:46:37 +0100136
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200137 ske[ske_len++] = 0;
138 ske[ske_len++] = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139 TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200140 /* The domain parameters must be the same on both side. */
141 TEST_ASSERT( check_get_value( &ctx_cli, MBEDTLS_DHM_PARAM_P, &ctx_srv.P ) );
142 TEST_ASSERT( check_get_value( &ctx_cli, MBEDTLS_DHM_PARAM_G, &ctx_srv.G ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200143
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200144 TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len,
145 &mbedtls_test_rnd_pseudo_rand,
146 &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147 TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200148
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200149 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ),
150 &sec_srv_len,
151 &mbedtls_test_rnd_pseudo_rand,
152 &rnd_info ) == 0 );
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200153 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ),
154 &sec_cli_len,
155 &mbedtls_test_rnd_pseudo_rand,
156 &rnd_info ) == 0 );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200157
158 TEST_ASSERT( sec_srv_len == sec_cli_len );
159 TEST_ASSERT( sec_srv_len != 0 );
160 TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
161
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200162 /* Internal value checks */
163 TEST_ASSERT( check_get_value( &ctx_cli, MBEDTLS_DHM_PARAM_X, &ctx_cli.X ) );
164 TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_X, &ctx_srv.X ) );
165 /* Cross-checks */
166 TEST_ASSERT( check_get_value( &ctx_cli, MBEDTLS_DHM_PARAM_GX, &ctx_srv.GY ) );
167 TEST_ASSERT( check_get_value( &ctx_cli, MBEDTLS_DHM_PARAM_GY, &ctx_srv.GX ) );
168 TEST_ASSERT( check_get_value( &ctx_cli, MBEDTLS_DHM_PARAM_K, &ctx_srv.K ) );
169 TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_GX, &ctx_cli.GY ) );
170 TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_GY, &ctx_cli.GX ) );
171 TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_K, &ctx_cli.K ) );
172
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200173 /* Re-do calc_secret on server a few times to test update of blinding values */
174 for( i = 0; i < 3; i++ )
175 {
Gilles Peskine02db8f42021-03-30 23:28:51 +0200176 mbedtls_test_set_step( 20 + i );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200177 sec_srv_len = 1000;
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200178 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv,
179 sizeof( sec_srv ), &sec_srv_len,
180 &mbedtls_test_rnd_pseudo_rand,
181 &rnd_info ) == 0 );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200182
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200183 TEST_ASSERT( sec_srv_len == sec_cli_len );
184 TEST_ASSERT( sec_srv_len != 0 );
185 TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
186 }
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200187
188 /*
189 * Second key exchange to test change of blinding values on server
190 */
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200191 p = ske;
Paul Bakker5c60de22009-07-08 19:47:36 +0000192
Gilles Peskine02db8f42021-03-30 23:28:51 +0200193 mbedtls_test_set_step( 30 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200194 TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
195 &mbedtls_test_rnd_pseudo_rand,
196 &rnd_info ) == 0 );
Gilles Peskine02db8f42021-03-30 23:28:51 +0200197 if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) )
198 goto exit;
Paul Bakker5c60de22009-07-08 19:47:36 +0000199 ske[ske_len++] = 0;
200 ske[ske_len++] = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201 TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
Paul Bakker5c60de22009-07-08 19:47:36 +0000202
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200203 TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len,
204 &mbedtls_test_rnd_pseudo_rand,
205 &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200206 TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
Paul Bakker5c60de22009-07-08 19:47:36 +0000207
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200208 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ),
209 &sec_srv_len,
210 &mbedtls_test_rnd_pseudo_rand,
211 &rnd_info ) == 0 );
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200212 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ),
213 &sec_cli_len,
214 &mbedtls_test_rnd_pseudo_rand,
215 &rnd_info ) == 0 );
Paul Bakker5c60de22009-07-08 19:47:36 +0000216
217 TEST_ASSERT( sec_srv_len == sec_cli_len );
218 TEST_ASSERT( sec_srv_len != 0 );
219 TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
Paul Bakkerc43481a2011-02-20 16:34:26 +0000220
Paul Bakkerbd51b262014-07-10 15:26:12 +0200221exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222 mbedtls_dhm_free( &ctx_srv );
223 mbedtls_dhm_free( &ctx_cli );
Paul Bakker5c60de22009-07-08 19:47:36 +0000224}
Paul Bakker33b43f12013-08-20 11:48:36 +0200225/* END_CASE */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200226
Chris Jonesd10b3312020-12-02 10:41:50 +0000227/* BEGIN_CASE */
228void dhm_make_public( int P_bytes, int radix_G, char *input_G, int result )
229{
230 mbedtls_mpi P, G;
231 mbedtls_dhm_context ctx;
232 unsigned char output[MBEDTLS_MPI_MAX_SIZE];
233
234 mbedtls_mpi_init( &P );
235 mbedtls_mpi_init( &G );
236 mbedtls_dhm_init( &ctx );
237
238 TEST_ASSERT( mbedtls_mpi_lset( &P, 1 ) == 0 );
239 TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 );
240 TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 );
241
Gilles Peskine20edee72021-06-10 23:18:39 +0200242 TEST_ASSERT( mbedtls_test_read_mpi( &G, radix_G, input_G ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +0000243
244 TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 );
245 TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ),
246 output, sizeof(output),
247 &mbedtls_test_rnd_pseudo_rand,
248 NULL ) == result );
249
250exit:
251 mbedtls_mpi_free( &P );
252 mbedtls_mpi_free( &G );
253 mbedtls_dhm_free( &ctx );
254}
255/* END_CASE */
256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100258void dhm_file( char * filename, char * p, char * g, int len )
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100259{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260 mbedtls_dhm_context ctx;
261 mbedtls_mpi P, G;
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263 mbedtls_dhm_init( &ctx );
264 mbedtls_mpi_init( &P ); mbedtls_mpi_init( &G );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100265
Gilles Peskine20edee72021-06-10 23:18:39 +0200266 TEST_ASSERT( mbedtls_test_read_mpi( &P, 16, p ) == 0 );
267 TEST_ASSERT( mbedtls_test_read_mpi( &G, 16, g ) == 0 );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269 TEST_ASSERT( mbedtls_dhm_parse_dhmfile( &ctx, filename ) == 0 );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100270
Gilles Peskine487bbf62021-05-27 22:17:07 +0200271 TEST_EQUAL( mbedtls_dhm_get_len( &ctx ), (size_t) len );
272 TEST_EQUAL( mbedtls_dhm_get_bitlen( &ctx ), mbedtls_mpi_bitlen( &P ) );
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200273 TEST_ASSERT( check_get_value( &ctx, MBEDTLS_DHM_PARAM_P, &P ) );
274 TEST_ASSERT( check_get_value( &ctx, MBEDTLS_DHM_PARAM_G, &G ) );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100275
Paul Bakkerbd51b262014-07-10 15:26:12 +0200276exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277 mbedtls_mpi_free( &P ); mbedtls_mpi_free( &G );
278 mbedtls_dhm_free( &ctx );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100279}
280/* END_CASE */
281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +0100283void dhm_selftest( )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200284{
Andres AG93012e82016-09-09 09:10:28 +0100285 TEST_ASSERT( mbedtls_dhm_self_test( 1 ) == 0 );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200286}
287/* END_CASE */