1/* BEGIN_HEADER */
2#include "mbedtls/gcm.h"
3
4/* Use the multipart interface to process the encrypted data in two parts
5 * and check that the output matches the expected output.
6 * The context must have been set up with the key. */
7static int check_multipart( mbedtls_gcm_context *ctx,
8                            int mode,
9                            const data_t *iv,
10                            const data_t *add,
11                            const data_t *input,
12                            const data_t *expected_output,
13                            const data_t *tag,
14                            size_t n1,
15                            size_t n1_add)
16{
17    int ok = 0;
18    uint8_t *output = NULL;
19    size_t n2 = input->len - n1;
20    size_t n2_add = add->len - n1_add;
21    size_t olen;
22
23    /* Sanity checks on the test data */
24    TEST_ASSERT( n1 <= input->len );
25    TEST_ASSERT( n1_add <= add->len );
26    TEST_EQUAL( input->len, expected_output->len );
27
28    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
29                                         iv->x, iv->len ) );
30    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, n1_add ) );
31    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x + n1_add, n2_add ) );
32
33    /* Allocate a tight buffer for each update call. This way, if the function
34     * tries to write beyond the advertised required buffer size, this will
35     * count as an overflow for memory sanitizers and static checkers. */
36    ASSERT_ALLOC( output, n1 );
37    olen = 0xdeadbeef;
38    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, n1, output, n1, &olen ) );
39    TEST_EQUAL( n1, olen );
40    ASSERT_COMPARE( output, olen, expected_output->x, n1 );
41    mbedtls_free( output );
42    output = NULL;
43
44    ASSERT_ALLOC( output, n2 );
45    olen = 0xdeadbeef;
46    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x + n1, n2, output, n2, &olen ) );
47    TEST_EQUAL( n2, olen );
48    ASSERT_COMPARE( output, olen, expected_output->x + n1, n2 );
49    mbedtls_free( output );
50    output = NULL;
51
52    ASSERT_ALLOC( output, tag->len );
53    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
54    TEST_EQUAL( 0, olen );
55    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
56    mbedtls_free( output );
57    output = NULL;
58
59    ok = 1;
60exit:
61    mbedtls_free( output );
62    return( ok );
63}
64
65static void check_cipher_with_empty_ad( mbedtls_gcm_context *ctx,
66                                        int mode,
67                                        const data_t *iv,
68                                        const data_t *input,
69                                        const data_t *expected_output,
70                                        const data_t *tag,
71                                        size_t ad_update_count)
72{
73    size_t n;
74    uint8_t *output = NULL;
75    size_t olen;
76
77    /* Sanity checks on the test data */
78    TEST_EQUAL( input->len, expected_output->len );
79
80    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
81                                       iv->x, iv->len ) );
82
83    for( n = 0; n < ad_update_count; n++ )
84    {
85        TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, NULL, 0 ) );
86    }
87
88    /* Allocate a tight buffer for each update call. This way, if the function
89     * tries to write beyond the advertised required buffer size, this will
90     * count as an overflow for memory sanitizers and static checkers. */
91    ASSERT_ALLOC( output, input->len );
92    olen = 0xdeadbeef;
93    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, input->len, output, input->len, &olen ) );
94    TEST_EQUAL( input->len, olen );
95    ASSERT_COMPARE( output, olen, expected_output->x, input->len );
96    mbedtls_free( output );
97    output = NULL;
98
99    ASSERT_ALLOC( output, tag->len );
100    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
101    TEST_EQUAL( 0, olen );
102    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
103
104exit:
105    mbedtls_free( output );
106}
107
108static void check_empty_cipher_with_ad( mbedtls_gcm_context *ctx,
109                                       int mode,
110                                       const data_t *iv,
111                                       const data_t *add,
112                                       const data_t *tag,
113                                       size_t cipher_update_count)
114{
115    size_t olen;
116    size_t n;
117    uint8_t* output_tag = NULL;
118
119    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode, iv->x, iv->len ) );
120    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, add->len ) );
121
122    for( n = 0; n < cipher_update_count; n++ )
123    {
124        olen = 0xdeadbeef;
125        TEST_EQUAL( 0, mbedtls_gcm_update( ctx, NULL, 0, NULL, 0, &olen ) );
126        TEST_EQUAL( 0, olen );
127    }
128
129    ASSERT_ALLOC( output_tag, tag->len );
130    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen,
131                                       output_tag, tag->len ) );
132    TEST_EQUAL( 0, olen );
133    ASSERT_COMPARE( output_tag, tag->len, tag->x, tag->len );
134
135exit:
136    mbedtls_free( output_tag );
137}
138
139static void check_no_cipher_no_ad( mbedtls_gcm_context *ctx,
140                                   int mode,
141                                   const data_t *iv,
142                                   const data_t *tag )
143{
144    uint8_t *output = NULL;
145    size_t olen = 0;
146
147    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
148                                       iv->x, iv->len ) );
149    ASSERT_ALLOC( output, tag->len );
150    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
151    TEST_EQUAL( 0, olen );
152    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
153
154exit:
155    mbedtls_free( output );
156}
157
158/* END_HEADER */
159
160/* BEGIN_DEPENDENCIES
161 * depends_on:MBEDTLS_GCM_C
162 * END_DEPENDENCIES
163 */
164
165/* BEGIN_CASE */
166void gcm_bad_parameters( int cipher_id, int direction,
167                         data_t *key_str, data_t *src_str,
168                         data_t *iv_str, data_t *add_str,
169                         int tag_len_bits, int gcm_result )
170{
171    unsigned char output[128];
172    unsigned char tag_output[16];
173    mbedtls_gcm_context ctx;
174    size_t tag_len = tag_len_bits / 8;
175
176    mbedtls_gcm_init( &ctx );
177
178    memset( output, 0x00, sizeof( output ) );
179    memset( tag_output, 0x00, sizeof( tag_output ) );
180
181    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
182    TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, direction, src_str->len, iv_str->x, iv_str->len,
183                 add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == gcm_result );
184
185exit:
186    mbedtls_gcm_free( &ctx );
187}
188/* END_CASE */
189
190/* BEGIN_CASE */
191void gcm_encrypt_and_tag( int cipher_id, data_t * key_str,
192                          data_t * src_str, data_t * iv_str,
193                          data_t * add_str, data_t * dst,
194                          int tag_len_bits, data_t * tag,
195                          int init_result )
196{
197    unsigned char output[128];
198    unsigned char tag_output[16];
199    mbedtls_gcm_context ctx;
200    size_t tag_len = tag_len_bits / 8;
201    size_t n1;
202    size_t n1_add;
203
204    mbedtls_gcm_init( &ctx );
205
206    memset(output, 0x00, 128);
207    memset(tag_output, 0x00, 16);
208
209
210    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
211    if( init_result == 0 )
212    {
213        TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == 0 );
214
215        ASSERT_COMPARE( output, src_str->len, dst->x, dst->len );
216        ASSERT_COMPARE( tag_output, tag_len, tag->x, tag->len );
217
218        for( n1 = 0; n1 <= src_str->len; n1 += 1 )
219        {
220            for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
221            {
222                mbedtls_test_set_step( n1 * 10000 + n1_add );
223                if( !check_multipart( &ctx, MBEDTLS_GCM_ENCRYPT,
224                                    iv_str, add_str, src_str,
225                                    dst, tag,
226                                    n1, n1_add ) )
227                    goto exit;
228            }
229        }
230    }
231
232exit:
233    mbedtls_gcm_free( &ctx );
234}
235/* END_CASE */
236
237/* BEGIN_CASE */
238void gcm_decrypt_and_verify( int cipher_id, data_t * key_str,
239                             data_t * src_str, data_t * iv_str,
240                             data_t * add_str, int tag_len_bits,
241                             data_t * tag_str, char * result,
242                             data_t * pt_result, int init_result )
243{
244    unsigned char output[128];
245    mbedtls_gcm_context ctx;
246    int ret;
247    size_t tag_len = tag_len_bits / 8;
248    size_t n1;
249    size_t n1_add;
250
251    mbedtls_gcm_init( &ctx );
252
253    memset(output, 0x00, 128);
254
255
256    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
257    if( init_result == 0 )
258    {
259        ret = mbedtls_gcm_auth_decrypt( &ctx, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, tag_str->x, tag_len, src_str->x, output );
260
261        if( strcmp( "FAIL", result ) == 0 )
262        {
263            TEST_ASSERT( ret == MBEDTLS_ERR_GCM_AUTH_FAILED );
264        }
265        else
266        {
267            TEST_ASSERT( ret == 0 );
268            ASSERT_COMPARE( output, src_str->len, pt_result->x, pt_result->len );
269
270            for( n1 = 0; n1 <= src_str->len; n1 += 1 )
271            {
272                for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
273                {
274                    mbedtls_test_set_step( n1 * 10000 + n1_add );
275                    if( !check_multipart( &ctx, MBEDTLS_GCM_DECRYPT,
276                                        iv_str, add_str, src_str,
277                                        pt_result, tag_str,
278                                        n1, n1_add ) )
279                        goto exit;
280                }
281            }
282        }
283    }
284
285exit:
286    mbedtls_gcm_free( &ctx );
287}
288/* END_CASE */
289
290/* BEGIN_CASE */
291void gcm_decrypt_and_verify_empty_cipher( int cipher_id,
292                                          data_t * key_str,
293                                          data_t * iv_str,
294                                          data_t * add_str,
295                                          data_t * tag_str,
296                                          int cipher_update_calls )
297{
298    mbedtls_gcm_context ctx;
299
300    mbedtls_gcm_init( &ctx );
301
302    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
303    check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_DECRYPT,
304                                iv_str, add_str, tag_str,
305                                cipher_update_calls );
306
307    mbedtls_gcm_free( &ctx );
308}
309/* END_CASE */
310
311/* BEGIN_CASE */
312void gcm_decrypt_and_verify_empty_ad( int cipher_id,
313                                      data_t * key_str,
314                                      data_t * iv_str,
315                                      data_t * src_str,
316                                      data_t * tag_str,
317                                      data_t * pt_result,
318                                      int ad_update_calls )
319{
320    mbedtls_gcm_context ctx;
321
322    mbedtls_gcm_init( &ctx );
323
324    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
325    check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_DECRYPT,
326                                iv_str, src_str, pt_result, tag_str,
327                                ad_update_calls );
328
329    mbedtls_gcm_free( &ctx );
330}
331/* END_CASE */
332
333/* BEGIN_CASE */
334void gcm_decrypt_and_verify_no_ad_no_cipher( int cipher_id,
335                                             data_t * key_str,
336                                             data_t * iv_str,
337                                             data_t * tag_str )
338{
339    mbedtls_gcm_context ctx;
340
341    mbedtls_gcm_init( &ctx );
342
343    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
344    check_no_cipher_no_ad( &ctx, MBEDTLS_GCM_DECRYPT,
345                           iv_str, tag_str );
346
347    mbedtls_gcm_free( &ctx );
348}
349/* END_CASE */
350
351/* BEGIN_CASE */
352void gcm_encrypt_and_tag_empty_cipher( int cipher_id,
353                                       data_t * key_str,
354                                       data_t * iv_str,
355                                       data_t * add_str,
356                                       data_t * tag_str,
357                                       int cipher_update_calls )
358{
359    mbedtls_gcm_context ctx;
360
361    mbedtls_gcm_init( &ctx );
362
363    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
364    check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
365                                iv_str, add_str, tag_str,
366                                cipher_update_calls );
367
368exit:
369    mbedtls_gcm_free( &ctx );
370}
371/* END_CASE */
372
373/* BEGIN_CASE */
374void gcm_encrypt_and_tag_empty_ad( int cipher_id,
375                                   data_t * key_str,
376                                   data_t * iv_str,
377                                   data_t * src_str,
378                                   data_t * dst,
379                                   data_t * tag_str,
380                                   int ad_update_calls )
381{
382    mbedtls_gcm_context ctx;
383
384    mbedtls_gcm_init( &ctx );
385
386    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
387    check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
388                                iv_str, src_str, dst, tag_str,
389                                ad_update_calls );
390
391exit:
392    mbedtls_gcm_free( &ctx );
393}
394/* END_CASE */
395
396/* BEGIN_CASE */
397void gcm_encrypt_and_verify_no_ad_no_cipher( int cipher_id,
398                                             data_t * key_str,
399                                             data_t * iv_str,
400                                             data_t * tag_str )
401{
402    mbedtls_gcm_context ctx;
403
404    mbedtls_gcm_init( &ctx );
405
406    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
407    check_no_cipher_no_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
408                           iv_str, tag_str );
409
410    mbedtls_gcm_free( &ctx );
411}
412/* END_CASE */
413
414/* BEGIN_CASE depends_on:NOT_DEFINED */
415void gcm_invalid_param( )
416{
417    mbedtls_gcm_context ctx;
418    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
419    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
420    int invalid_bitlen = 1;
421
422    mbedtls_gcm_init( &ctx );
423
424    /* mbedtls_gcm_setkey */
425    TEST_EQUAL(
426        MBEDTLS_ERR_GCM_BAD_INPUT,
427        mbedtls_gcm_setkey( &ctx, valid_cipher, valid_buffer, invalid_bitlen ) );
428
429exit:
430    mbedtls_gcm_free( &ctx );
431}
432/* END_CASE */
433
434/* BEGIN_CASE */
435void gcm_update_output_buffer_too_small( int cipher_id, int mode,
436                                         data_t * key_str, const data_t *input,
437                                         const data_t *iv )
438{
439    mbedtls_gcm_context ctx;
440    uint8_t *output = NULL;
441    size_t olen = 0;
442    size_t output_len = input->len - 1;
443
444    mbedtls_gcm_init( &ctx );
445    TEST_EQUAL( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ), 0 );
446    TEST_EQUAL( 0, mbedtls_gcm_starts( &ctx, mode, iv->x, iv->len ) );
447
448    ASSERT_ALLOC( output, output_len );
449    TEST_EQUAL( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL, mbedtls_gcm_update( &ctx, input->x, input->len, output, output_len, &olen ) );
450
451exit:
452    mbedtls_free( output );
453    mbedtls_gcm_free( &ctx );
454}
455/* END_CASE */
456
457/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
458void gcm_selftest(  )
459{
460    TEST_ASSERT( mbedtls_gcm_self_test( 1 ) == 0 );
461}
462/* END_CASE */
463