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