• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/dhm.h"
3
4/* Sanity checks on a Diffie-Hellman parameter: check the length-value
5 * syntax and check that the value is the expected one (taken from the
6 * DHM context by the caller). */
7static int check_dhm_param_output( const mbedtls_mpi *expected,
8                                   const unsigned char *buffer,
9                                   size_t size,
10                                   size_t *offset )
11{
12    size_t n;
13    mbedtls_mpi actual;
14    int ok = 0;
15    mbedtls_mpi_init( &actual );
16
17    ++mbedtls_test_info.step;
18
19    TEST_ASSERT( size >= *offset + 2 );
20    n = ( buffer[*offset] << 8 ) | buffer[*offset + 1];
21    *offset += 2;
22    /* The DHM param output from Mbed TLS has leading zeros stripped, as
23     * permitted but not required by RFC 5246 \S4.4. */
24    TEST_EQUAL( n, mbedtls_mpi_size( expected ) );
25    TEST_ASSERT( size >= *offset + n );
26    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &actual, buffer + *offset, n ) );
27    TEST_EQUAL( 0, mbedtls_mpi_cmp_mpi( expected, &actual ) );
28    *offset += n;
29
30    ok = 1;
31exit:
32    mbedtls_mpi_free( &actual );
33    return( ok );
34}
35
36/* Sanity checks on Diffie-Hellman parameters: syntax, range, and comparison
37 * against the context. */
38static int check_dhm_params( const mbedtls_dhm_context *ctx,
39                             size_t x_size,
40                             const unsigned char *ske, size_t ske_len )
41{
42    size_t offset = 0;
43
44    /* Check that ctx->X and ctx->GX are within range. */
45    TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->X, 1 ) > 0 );
46    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) < 0 );
47    TEST_ASSERT( mbedtls_mpi_size( &ctx->X ) <= x_size );
48    TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->GX, 1 ) > 0 );
49    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->GX, &ctx->P ) < 0 );
50
51    /* Check ske: it must contain P, G and G^X, each prefixed with a
52     * 2-byte size. */
53    if( !check_dhm_param_output( &ctx->P, ske, ske_len, &offset ) )
54        goto exit;
55    if( !check_dhm_param_output( &ctx->G, ske, ske_len, &offset ) )
56        goto exit;
57    if( !check_dhm_param_output( &ctx->GX, ske, ske_len, &offset ) )
58        goto exit;
59    TEST_EQUAL( offset, ske_len );
60
61    return( 1 );
62exit:
63    return( 0 );
64}
65
66/* END_HEADER */
67
68/* BEGIN_DEPENDENCIES
69 * depends_on:MBEDTLS_DHM_C:MBEDTLS_BIGNUM_C
70 * END_DEPENDENCIES
71 */
72
73/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
74void dhm_invalid_params( )
75{
76    mbedtls_dhm_context ctx;
77    unsigned char buf[42] = { 0 };
78    unsigned char *buf_null = NULL;
79    mbedtls_mpi X;
80    size_t const buflen = sizeof( buf );
81    size_t len;
82
83    TEST_INVALID_PARAM( mbedtls_dhm_init( NULL ) );
84    TEST_VALID_PARAM( mbedtls_dhm_free( NULL ) );
85
86    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
87                            mbedtls_dhm_read_params( NULL,
88                                                     (unsigned char**) &buf,
89                                                     buf ) );
90    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
91                            mbedtls_dhm_read_params( &ctx, &buf_null, buf ) );
92    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
93                            mbedtls_dhm_read_params( &ctx, NULL, buf ) );
94    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
95                            mbedtls_dhm_read_params( &ctx,
96                                                     (unsigned char**) &buf,
97                                                     NULL ) );
98
99    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
100                            mbedtls_dhm_make_params( NULL, buflen,
101                                                     buf, &len,
102                                                     mbedtls_test_rnd_std_rand,
103                                                     NULL ) );
104    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
105                            mbedtls_dhm_make_params( &ctx, buflen,
106                                                     NULL, &len,
107                                                     mbedtls_test_rnd_std_rand,
108                                                     NULL ) );
109    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
110                            mbedtls_dhm_make_params( &ctx, buflen,
111                                                     buf, NULL,
112                                                     mbedtls_test_rnd_std_rand,
113                                                     NULL ) );
114    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
115                            mbedtls_dhm_make_params( &ctx, buflen,
116                                                     buf, &len,
117                                                     NULL,
118                                                     NULL ) );
119
120    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
121                            mbedtls_dhm_set_group( NULL, &X, &X ) );
122    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
123                            mbedtls_dhm_set_group( &ctx, NULL, &X ) );
124    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
125                            mbedtls_dhm_set_group( &ctx, &X, NULL ) );
126
127    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
128                            mbedtls_dhm_read_public( NULL, buf, buflen ) );
129    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
130                            mbedtls_dhm_read_public( &ctx, NULL, buflen ) );
131
132    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
133                            mbedtls_dhm_make_public( NULL, buflen,
134                                                     buf, buflen,
135                                                     mbedtls_test_rnd_std_rand,
136                                                     NULL ) );
137    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
138                            mbedtls_dhm_make_public( &ctx, buflen,
139                                                     NULL, buflen,
140                                                     mbedtls_test_rnd_std_rand,
141                                                     NULL ) );
142    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
143                            mbedtls_dhm_make_public( &ctx, buflen,
144                                                     buf, buflen,
145                                                     NULL,
146                                                     NULL ) );
147
148    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
149                            mbedtls_dhm_calc_secret( NULL, buf, buflen, &len,
150                                                     mbedtls_test_rnd_std_rand,
151                                                     NULL ) );
152    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
153                            mbedtls_dhm_calc_secret( &ctx, NULL, buflen, &len,
154                                                     mbedtls_test_rnd_std_rand,
155                                                     NULL ) );
156    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
157                            mbedtls_dhm_calc_secret( &ctx, buf, buflen, NULL,
158                                                     mbedtls_test_rnd_std_rand,
159                                                     NULL ) );
160
161#if defined(MBEDTLS_ASN1_PARSE_C)
162    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
163                            mbedtls_dhm_parse_dhm( NULL, buf, buflen ) );
164    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
165                            mbedtls_dhm_parse_dhm( &ctx, NULL, buflen ) );
166
167#if defined(MBEDTLS_FS_IO)
168    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
169                            mbedtls_dhm_parse_dhmfile( NULL, "" ) );
170    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
171                            mbedtls_dhm_parse_dhmfile( &ctx, NULL ) );
172#endif /* MBEDTLS_FS_IO */
173#endif /* MBEDTLS_ASN1_PARSE_C */
174
175exit:
176    return;
177}
178/* END_CASE */
179
180/* BEGIN_CASE */
181void dhm_do_dhm( int radix_P, char *input_P, int x_size,
182                 int radix_G, char *input_G, int result )
183{
184    mbedtls_dhm_context ctx_srv;
185    mbedtls_dhm_context ctx_cli;
186    unsigned char ske[1000];
187    unsigned char *p = ske;
188    unsigned char pub_cli[1000];
189    unsigned char sec_srv[1000];
190    unsigned char sec_cli[1000];
191    size_t ske_len = 0;
192    size_t pub_cli_len = 0;
193    size_t sec_srv_len;
194    size_t sec_cli_len;
195    int i;
196    mbedtls_test_rnd_pseudo_info rnd_info;
197
198    mbedtls_dhm_init( &ctx_srv );
199    mbedtls_dhm_init( &ctx_cli );
200    memset( ske, 0x00, 1000 );
201    memset( pub_cli, 0x00, 1000 );
202    memset( sec_srv, 0x00, 1000 );
203    memset( sec_cli, 0x00, 1000 );
204    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
205
206    /*
207     * Set params
208     */
209    TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.P, radix_P, input_P ) == 0 );
210    TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.G, radix_G, input_G ) == 0 );
211    pub_cli_len = mbedtls_mpi_size( &ctx_srv.P );
212
213    /*
214     * First key exchange
215     */
216    mbedtls_test_set_step( 10 );
217    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
218                                          &mbedtls_test_rnd_pseudo_rand,
219                                          &rnd_info ) == result );
220    if ( result != 0 )
221        goto exit;
222    if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) )
223        goto exit;
224
225    ske[ske_len++] = 0;
226    ske[ske_len++] = 0;
227    TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
228
229    TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len,
230                                          &mbedtls_test_rnd_pseudo_rand,
231                                          &rnd_info ) == 0 );
232    TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
233
234    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ),
235                                          &sec_srv_len,
236                                          &mbedtls_test_rnd_pseudo_rand,
237                                          &rnd_info ) == 0 );
238    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 );
239
240    TEST_ASSERT( sec_srv_len == sec_cli_len );
241    TEST_ASSERT( sec_srv_len != 0 );
242    TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
243
244    /* Re-do calc_secret on server a few times to test update of blinding values */
245    for( i = 0; i < 3; i++ )
246    {
247        mbedtls_test_set_step( 20 + i );
248        sec_srv_len = 1000;
249        TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv,
250                                              sizeof( sec_srv ), &sec_srv_len,
251                                              &mbedtls_test_rnd_pseudo_rand,
252                                              &rnd_info ) == 0 );
253
254        TEST_ASSERT( sec_srv_len == sec_cli_len );
255        TEST_ASSERT( sec_srv_len != 0 );
256        TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
257    }
258
259    /*
260     * Second key exchange to test change of blinding values on server
261     */
262    p = ske;
263
264    mbedtls_test_set_step( 30 );
265    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
266                                          &mbedtls_test_rnd_pseudo_rand,
267                                          &rnd_info ) == 0 );
268    if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) )
269        goto exit;
270    ske[ske_len++] = 0;
271    ske[ske_len++] = 0;
272    TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
273
274    TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len,
275                                          &mbedtls_test_rnd_pseudo_rand,
276                                          &rnd_info ) == 0 );
277    TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
278
279    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ),
280                                          &sec_srv_len,
281                                          &mbedtls_test_rnd_pseudo_rand,
282                                          &rnd_info ) == 0 );
283    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 );
284
285    TEST_ASSERT( sec_srv_len == sec_cli_len );
286    TEST_ASSERT( sec_srv_len != 0 );
287    TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
288
289exit:
290    mbedtls_dhm_free( &ctx_srv );
291    mbedtls_dhm_free( &ctx_cli );
292}
293/* END_CASE */
294
295/* BEGIN_CASE */
296void dhm_make_public( int P_bytes, int radix_G, char *input_G, int result )
297{
298    mbedtls_mpi P, G;
299    mbedtls_dhm_context ctx;
300    unsigned char output[MBEDTLS_MPI_MAX_SIZE];
301
302    mbedtls_mpi_init( &P );
303    mbedtls_mpi_init( &G );
304    mbedtls_dhm_init( &ctx );
305
306    TEST_ASSERT( mbedtls_mpi_lset( &P, 1 ) == 0 );
307    TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 );
308    TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 );
309
310    TEST_ASSERT( mbedtls_test_read_mpi( &G, radix_G, input_G ) == 0 );
311
312    TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 );
313    TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ),
314                                          output, sizeof(output),
315                                          &mbedtls_test_rnd_pseudo_rand,
316                                          NULL ) == result );
317
318exit:
319    mbedtls_mpi_free( &P );
320    mbedtls_mpi_free( &G );
321    mbedtls_dhm_free( &ctx );
322}
323/* END_CASE */
324
325/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
326void dhm_file( char * filename, char * p, char * g, int len )
327{
328    mbedtls_dhm_context ctx;
329    mbedtls_mpi P, G;
330
331    mbedtls_dhm_init( &ctx );
332    mbedtls_mpi_init( &P ); mbedtls_mpi_init( &G );
333
334    TEST_ASSERT( mbedtls_test_read_mpi( &P, 16, p ) == 0 );
335    TEST_ASSERT( mbedtls_test_read_mpi( &G, 16, g ) == 0 );
336
337    TEST_ASSERT( mbedtls_dhm_parse_dhmfile( &ctx, filename ) == 0 );
338
339    TEST_ASSERT( ctx.len == (size_t) len );
340    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.P, &P ) == 0 );
341    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.G, &G ) == 0 );
342
343exit:
344    mbedtls_mpi_free( &P ); mbedtls_mpi_free( &G );
345    mbedtls_dhm_free( &ctx );
346}
347/* END_CASE */
348
349/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
350void dhm_selftest(  )
351{
352    TEST_ASSERT( mbedtls_dhm_self_test( 1 ) == 0 );
353}
354/* END_CASE */
355