1/* BEGIN_HEADER */
2#include "mbedtls/dhm.h"
3/* END_HEADER */
4
5/* BEGIN_DEPENDENCIES
6 * depends_on:MBEDTLS_DHM_C:MBEDTLS_BIGNUM_C
7 * END_DEPENDENCIES
8 */
9
10/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
11void dhm_invalid_params( )
12{
13    mbedtls_dhm_context ctx;
14    unsigned char buf[42] = { 0 };
15    unsigned char *buf_null = NULL;
16    mbedtls_mpi X;
17    size_t const buflen = sizeof( buf );
18    size_t len;
19
20    TEST_INVALID_PARAM( mbedtls_dhm_init( NULL ) );
21    TEST_VALID_PARAM( mbedtls_dhm_free( NULL ) );
22
23    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
24                            mbedtls_dhm_read_params( NULL,
25                                                     (unsigned char**) &buf,
26                                                     buf ) );
27    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
28                            mbedtls_dhm_read_params( &ctx, &buf_null, buf ) );
29    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
30                            mbedtls_dhm_read_params( &ctx, NULL, buf ) );
31    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
32                            mbedtls_dhm_read_params( &ctx,
33                                                     (unsigned char**) &buf,
34                                                     NULL ) );
35
36    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
37                            mbedtls_dhm_make_params( NULL, buflen,
38                                                     buf, &len,
39                                                     mbedtls_test_rnd_std_rand,
40                                                     NULL ) );
41    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
42                            mbedtls_dhm_make_params( &ctx, buflen,
43                                                     NULL, &len,
44                                                     mbedtls_test_rnd_std_rand,
45                                                     NULL ) );
46    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
47                            mbedtls_dhm_make_params( &ctx, buflen,
48                                                     buf, NULL,
49                                                     mbedtls_test_rnd_std_rand,
50                                                     NULL ) );
51    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
52                            mbedtls_dhm_make_params( &ctx, buflen,
53                                                     buf, &len,
54                                                     NULL,
55                                                     NULL ) );
56
57    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
58                            mbedtls_dhm_set_group( NULL, &X, &X ) );
59    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
60                            mbedtls_dhm_set_group( &ctx, NULL, &X ) );
61    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
62                            mbedtls_dhm_set_group( &ctx, &X, NULL ) );
63
64    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
65                            mbedtls_dhm_read_public( NULL, buf, buflen ) );
66    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
67                            mbedtls_dhm_read_public( &ctx, NULL, buflen ) );
68
69    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
70                            mbedtls_dhm_make_public( NULL, buflen,
71                                                     buf, buflen,
72                                                     mbedtls_test_rnd_std_rand,
73                                                     NULL ) );
74    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
75                            mbedtls_dhm_make_public( &ctx, buflen,
76                                                     NULL, buflen,
77                                                     mbedtls_test_rnd_std_rand,
78                                                     NULL ) );
79    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
80                            mbedtls_dhm_make_public( &ctx, buflen,
81                                                     buf, buflen,
82                                                     NULL,
83                                                     NULL ) );
84
85    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
86                            mbedtls_dhm_calc_secret( NULL, buf, buflen, &len,
87                                                     mbedtls_test_rnd_std_rand,
88                                                     NULL ) );
89    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
90                            mbedtls_dhm_calc_secret( &ctx, NULL, buflen, &len,
91                                                     mbedtls_test_rnd_std_rand,
92                                                     NULL ) );
93    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
94                            mbedtls_dhm_calc_secret( &ctx, buf, buflen, NULL,
95                                                     mbedtls_test_rnd_std_rand,
96                                                     NULL ) );
97
98#if defined(MBEDTLS_ASN1_PARSE_C)
99    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
100                            mbedtls_dhm_parse_dhm( NULL, buf, buflen ) );
101    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
102                            mbedtls_dhm_parse_dhm( &ctx, NULL, buflen ) );
103
104#if defined(MBEDTLS_FS_IO)
105    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
106                            mbedtls_dhm_parse_dhmfile( NULL, "" ) );
107    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
108                            mbedtls_dhm_parse_dhmfile( &ctx, NULL ) );
109#endif /* MBEDTLS_FS_IO */
110#endif /* MBEDTLS_ASN1_PARSE_C */
111
112exit:
113    return;
114}
115/* END_CASE */
116
117/* BEGIN_CASE */
118void dhm_do_dhm( int radix_P, char *input_P,
119                 int radix_G, char *input_G, int result )
120{
121    mbedtls_dhm_context ctx_srv;
122    mbedtls_dhm_context ctx_cli;
123    unsigned char ske[1000];
124    unsigned char *p = ske;
125    unsigned char pub_cli[1000];
126    unsigned char sec_srv[1000];
127    unsigned char sec_cli[1000];
128    size_t ske_len = 0;
129    size_t pub_cli_len = 0;
130    size_t sec_srv_len;
131    size_t sec_cli_len;
132    int x_size, i;
133    mbedtls_test_rnd_pseudo_info rnd_info;
134
135    mbedtls_dhm_init( &ctx_srv );
136    mbedtls_dhm_init( &ctx_cli );
137    memset( ske, 0x00, 1000 );
138    memset( pub_cli, 0x00, 1000 );
139    memset( sec_srv, 0x00, 1000 );
140    memset( sec_cli, 0x00, 1000 );
141    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
142
143    /*
144     * Set params
145     */
146    TEST_ASSERT( mbedtls_mpi_read_string( &ctx_srv.P, radix_P, input_P ) == 0 );
147    TEST_ASSERT( mbedtls_mpi_read_string( &ctx_srv.G, radix_G, input_G ) == 0 );
148    x_size = mbedtls_mpi_size( &ctx_srv.P );
149    pub_cli_len = x_size;
150
151    /*
152     * First key exchange
153     */
154    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
155                                          &mbedtls_test_rnd_pseudo_rand,
156                                          &rnd_info ) == result );
157    if ( result != 0 )
158        goto exit;
159
160    ske[ske_len++] = 0;
161    ske[ske_len++] = 0;
162    TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
163
164    TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len,
165                                          &mbedtls_test_rnd_pseudo_rand,
166                                          &rnd_info ) == 0 );
167    TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
168
169    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ),
170                                          &sec_srv_len,
171                                          &mbedtls_test_rnd_pseudo_rand,
172                                          &rnd_info ) == 0 );
173    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 );
174
175    TEST_ASSERT( sec_srv_len == sec_cli_len );
176    TEST_ASSERT( sec_srv_len != 0 );
177    TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
178
179    /* Re-do calc_secret on server a few times to test update of blinding values */
180    for( i = 0; i < 3; i++ )
181    {
182        sec_srv_len = 1000;
183        TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv,
184                                              sizeof( sec_srv ), &sec_srv_len,
185                                              &mbedtls_test_rnd_pseudo_rand,
186                                              &rnd_info ) == 0 );
187
188        TEST_ASSERT( sec_srv_len == sec_cli_len );
189        TEST_ASSERT( sec_srv_len != 0 );
190        TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
191    }
192
193    /*
194     * Second key exchange to test change of blinding values on server
195     */
196    p = ske;
197
198    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
199                                          &mbedtls_test_rnd_pseudo_rand,
200                                          &rnd_info ) == 0 );
201    ske[ske_len++] = 0;
202    ske[ske_len++] = 0;
203    TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
204
205    TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len,
206                                          &mbedtls_test_rnd_pseudo_rand,
207                                          &rnd_info ) == 0 );
208    TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
209
210    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ),
211                                          &sec_srv_len,
212                                          &mbedtls_test_rnd_pseudo_rand,
213                                          &rnd_info ) == 0 );
214    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 );
215
216    TEST_ASSERT( sec_srv_len == sec_cli_len );
217    TEST_ASSERT( sec_srv_len != 0 );
218    TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
219
220exit:
221    mbedtls_dhm_free( &ctx_srv );
222    mbedtls_dhm_free( &ctx_cli );
223}
224/* END_CASE */
225
226/* BEGIN_CASE */
227void dhm_make_public( int P_bytes, int radix_G, char *input_G, int result )
228{
229    mbedtls_mpi P, G;
230    mbedtls_dhm_context ctx;
231    unsigned char output[MBEDTLS_MPI_MAX_SIZE];
232
233    mbedtls_mpi_init( &P );
234    mbedtls_mpi_init( &G );
235    mbedtls_dhm_init( &ctx );
236
237    TEST_ASSERT( mbedtls_mpi_lset( &P, 1 ) == 0 );
238    TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 );
239    TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 );
240
241    TEST_ASSERT( mbedtls_mpi_read_string( &G, radix_G, input_G ) == 0 );
242
243    TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 );
244    TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ),
245                                          output, sizeof(output),
246                                          &mbedtls_test_rnd_pseudo_rand,
247                                          NULL ) == result );
248
249exit:
250    mbedtls_mpi_free( &P );
251    mbedtls_mpi_free( &G );
252    mbedtls_dhm_free( &ctx );
253}
254/* END_CASE */
255
256/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
257void dhm_file( char * filename, char * p, char * g, int len )
258{
259    mbedtls_dhm_context ctx;
260    mbedtls_mpi P, G;
261
262    mbedtls_dhm_init( &ctx );
263    mbedtls_mpi_init( &P ); mbedtls_mpi_init( &G );
264
265    TEST_ASSERT( mbedtls_mpi_read_string( &P, 16, p ) == 0 );
266    TEST_ASSERT( mbedtls_mpi_read_string( &G, 16, g ) == 0 );
267
268    TEST_ASSERT( mbedtls_dhm_parse_dhmfile( &ctx, filename ) == 0 );
269
270    TEST_ASSERT( ctx.len == (size_t) len );
271    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.P, &P ) == 0 );
272    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.G, &G ) == 0 );
273
274exit:
275    mbedtls_mpi_free( &P ); mbedtls_mpi_free( &G );
276    mbedtls_dhm_free( &ctx );
277}
278/* END_CASE */
279
280/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
281void dhm_selftest(  )
282{
283    TEST_ASSERT( mbedtls_dhm_self_test( 1 ) == 0 );
284}
285/* END_CASE */
286