1/* BEGIN_HEADER */
2#include "mbedtls/chachapoly.h"
3/* END_HEADER */
4
5/* BEGIN_DEPENDENCIES
6 * depends_on:MBEDTLS_CHACHAPOLY_C
7 * END_DEPENDENCIES
8 */
9
10/* BEGIN_CASE */
11void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string )
12{
13    unsigned char key_str[32]; /* size set by the standard */
14    unsigned char nonce_str[12]; /* size set by the standard */
15    unsigned char aad_str[12]; /* max size of test data so far */
16    unsigned char input_str[265]; /* max size of binary input/output so far */
17    unsigned char output_str[265];
18    unsigned char output[265];
19    unsigned char mac_str[16]; /* size set by the standard */
20    unsigned char mac[16]; /* size set by the standard */
21    size_t input_len;
22    size_t output_len;
23    size_t aad_len;
24    size_t key_len;
25    size_t nonce_len;
26    size_t mac_len;
27    mbedtls_chachapoly_context ctx;
28
29    memset( key_str,    0x00, sizeof( key_str ) );
30    memset( nonce_str,  0x00, sizeof( nonce_str ) );
31    memset( aad_str,    0x00, sizeof( aad_str ) );
32    memset( input_str,  0x00, sizeof( input_str ) );
33    memset( output_str, 0x00, sizeof( output_str ) );
34    memset( mac_str,    0x00, sizeof( mac_str ) );
35
36    aad_len    = unhexify( aad_str,    hex_aad_string    );
37    input_len  = unhexify( input_str,  hex_input_string  );
38    output_len = unhexify( output_str, hex_output_string );
39    key_len    = unhexify( key_str,    hex_key_string    );
40    nonce_len  = unhexify( nonce_str,  hex_nonce_string  );
41    mac_len    = unhexify( mac_str,    hex_mac_string    );
42
43    TEST_ASSERT( key_len   == 32 );
44    TEST_ASSERT( nonce_len == 12 );
45    TEST_ASSERT( mac_len   == 16 );
46
47    mbedtls_chachapoly_init( &ctx );
48
49    TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key_str ) == 0 );
50
51    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
52                                      input_len, nonce_str,
53                                      aad_str, aad_len,
54                                      input_str, output, mac ) == 0 );
55
56    TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 );
57    TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 );
58
59exit:
60    mbedtls_chachapoly_free( &ctx );
61}
62/* END_CASE */
63
64/* BEGIN_CASE */
65void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string, int ret_exp )
66{
67    unsigned char key_str[32]; /* size set by the standard */
68    unsigned char nonce_str[12]; /* size set by the standard */
69    unsigned char aad_str[12]; /* max size of test data so far */
70    unsigned char input_str[265]; /* max size of binary input/output so far */
71    unsigned char output_str[265];
72    unsigned char output[265];
73    unsigned char mac_str[16]; /* size set by the standard */
74    size_t input_len;
75    size_t output_len;
76    size_t aad_len;
77    size_t key_len;
78    size_t nonce_len;
79    size_t mac_len;
80    int ret;
81    mbedtls_chachapoly_context ctx;
82
83    memset( key_str,    0x00, sizeof( key_str ) );
84    memset( nonce_str,  0x00, sizeof( nonce_str ) );
85    memset( aad_str,    0x00, sizeof( aad_str ) );
86    memset( input_str,  0x00, sizeof( input_str ) );
87    memset( output_str, 0x00, sizeof( output_str ) );
88    memset( mac_str,    0x00, sizeof( mac_str ) );
89
90    aad_len    = unhexify( aad_str,    hex_aad_string    );
91    input_len  = unhexify( input_str,  hex_input_string  );
92    output_len = unhexify( output_str, hex_output_string );
93    key_len    = unhexify( key_str,    hex_key_string    );
94    nonce_len  = unhexify( nonce_str,  hex_nonce_string  );
95    mac_len    = unhexify( mac_str,    hex_mac_string    );
96
97    TEST_ASSERT( key_len   == 32 );
98    TEST_ASSERT( nonce_len == 12 );
99    TEST_ASSERT( mac_len   == 16 );
100
101    mbedtls_chachapoly_init( &ctx );
102
103    TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key_str ) == 0 );
104
105    ret = mbedtls_chachapoly_auth_decrypt( &ctx,
106                                           input_len, nonce_str,
107                                           aad_str, aad_len,
108                                           mac_str, input_str, output );
109
110    TEST_ASSERT( ret == ret_exp );
111    if( ret_exp == 0 )
112    {
113        TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 );
114    }
115
116exit:
117    mbedtls_chachapoly_free( &ctx );
118}
119/* END_CASE */
120
121/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
122void chachapoly_bad_params()
123{
124    unsigned char key[32];
125    unsigned char nonce[12];
126    unsigned char aad[1];
127    unsigned char input[1];
128    unsigned char output[1];
129    unsigned char mac[16];
130    size_t input_len = sizeof( input );
131    size_t aad_len = sizeof( aad );
132    mbedtls_chachapoly_context ctx;
133
134    memset( key,    0x00, sizeof( key ) );
135    memset( nonce,  0x00, sizeof( nonce ) );
136    memset( aad,    0x00, sizeof( aad ) );
137    memset( input,  0x00, sizeof( input ) );
138    memset( output, 0x00, sizeof( output ) );
139    memset( mac,    0x00, sizeof( mac ) );
140
141    TEST_INVALID_PARAM( mbedtls_chachapoly_init( NULL ) );
142    TEST_VALID_PARAM( mbedtls_chachapoly_free( NULL ) );
143
144    /* setkey */
145    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
146                            mbedtls_chachapoly_setkey( NULL, key ) );
147    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
148                            mbedtls_chachapoly_setkey( &ctx, NULL ) );
149
150    /* encrypt_and_tag */
151    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
152                            mbedtls_chachapoly_encrypt_and_tag( NULL,
153                                      0, nonce,
154                                      aad, 0,
155                                      input, output, mac ) );
156    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
157                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
158                                      0, NULL,
159                                      aad, 0,
160                                      input, output, mac ) );
161    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
162                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
163                                      0, nonce,
164                                      NULL, aad_len,
165                                      input, output, mac ) );
166    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
167                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
168                                      input_len, nonce,
169                                      aad, 0,
170                                      NULL, output, mac ) );
171    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
172                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
173                                      input_len, nonce,
174                                      aad, 0,
175                                      input, NULL, mac ) );
176    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
177                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
178                                      0, nonce,
179                                      aad, 0,
180                                      input, output, NULL ) );
181
182    /* auth_decrypt */
183    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
184                            mbedtls_chachapoly_auth_decrypt( NULL,
185                                           0, nonce,
186                                           aad, 0,
187                                           mac, input, output ) );
188    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
189                            mbedtls_chachapoly_auth_decrypt( &ctx,
190                                           0, NULL,
191                                           aad, 0,
192                                           mac, input, output ) );
193    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
194                            mbedtls_chachapoly_auth_decrypt( &ctx,
195                                           0, nonce,
196                                           NULL, aad_len,
197                                           mac, input, output ) );
198    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
199                            mbedtls_chachapoly_auth_decrypt( &ctx,
200                                           0, nonce,
201                                           aad, 0,
202                                           NULL, input, output ) );
203    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
204                            mbedtls_chachapoly_auth_decrypt( &ctx,
205                                           input_len, nonce,
206                                           aad, 0,
207                                           mac, NULL, output ) );
208    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
209                            mbedtls_chachapoly_auth_decrypt( &ctx,
210                                           input_len, nonce,
211                                           aad, 0,
212                                           mac, input, NULL ) );
213
214    /* starts */
215    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
216                            mbedtls_chachapoly_starts( NULL, nonce,
217                                               MBEDTLS_CHACHAPOLY_ENCRYPT ) );
218    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
219                            mbedtls_chachapoly_starts( &ctx, NULL,
220                                               MBEDTLS_CHACHAPOLY_ENCRYPT ) );
221
222    /* update_aad */
223    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
224                            mbedtls_chachapoly_update_aad( NULL, aad,
225                                                           aad_len ) );
226    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
227                            mbedtls_chachapoly_update_aad( &ctx, NULL,
228                                                           aad_len ) );
229
230    /* update */
231    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
232                            mbedtls_chachapoly_update( NULL, input_len,
233                                                       input, output ) );
234    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
235                            mbedtls_chachapoly_update( &ctx, input_len,
236                                                       NULL, output ) );
237    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
238                            mbedtls_chachapoly_update( &ctx, input_len,
239                                                       input, NULL ) );
240
241    /* finish */
242    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
243                            mbedtls_chachapoly_finish( NULL, mac ) );
244    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
245                            mbedtls_chachapoly_finish( &ctx, NULL ) );
246
247exit:
248    return;
249}
250/* END_CASE */
251
252/* BEGIN_CASE */
253void chachapoly_state()
254{
255    unsigned char key[32];
256    unsigned char nonce[12];
257    unsigned char aad[1];
258    unsigned char input[1];
259    unsigned char output[1];
260    unsigned char mac[16];
261    size_t input_len = sizeof( input );
262    size_t aad_len = sizeof( aad );
263    mbedtls_chachapoly_context ctx;
264
265    memset( key,    0x00, sizeof( key ) );
266    memset( nonce,  0x00, sizeof( nonce ) );
267    memset( aad,    0x00, sizeof( aad ) );
268    memset( input,  0x00, sizeof( input ) );
269    memset( output, 0x00, sizeof( output ) );
270    memset( mac,    0x00, sizeof( mac ) );
271
272    /* Initial state: finish, update, update_aad forbidden */
273    mbedtls_chachapoly_init( &ctx );
274
275    TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac )
276                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
277    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output )
278                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
279    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len )
280                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
281
282    /* Still initial state: finish, update, update_aad forbidden */
283    TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key )
284                 == 0 );
285
286    TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac )
287                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
288    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output )
289                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
290    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len )
291                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
292
293    /* Starts -> finish OK */
294    TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT )
295                 == 0 );
296    TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac )
297                 == 0 );
298
299    /* After finish: update, update_aad forbidden */
300    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output )
301                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
302    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len )
303                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
304
305    /* Starts -> update* OK */
306    TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT )
307                 == 0 );
308    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output )
309                 == 0 );
310    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output )
311                 == 0 );
312
313    /* After update: update_aad forbidden */
314    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len )
315                 == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
316
317    /* Starts -> update_aad* -> finish OK */
318    TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT )
319                 == 0 );
320    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len )
321                 == 0 );
322    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len )
323                 == 0 );
324    TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac )
325                 == 0 );
326
327exit:
328    mbedtls_chachapoly_free( &ctx );
329}
330/* END_CASE */
331
332/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
333void chachapoly_selftest()
334{
335    TEST_ASSERT( mbedtls_chachapoly_self_test( 1 ) == 0 );
336}
337/* END_CASE */
338