• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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        TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, NULL, 0));
85    }
86
87    /* Allocate a tight buffer for each update call. This way, if the function
88     * tries to write beyond the advertised required buffer size, this will
89     * count as an overflow for memory sanitizers and static checkers. */
90    ASSERT_ALLOC(output, input->len);
91    olen = 0xdeadbeef;
92    TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, input->len, output, input->len, &olen));
93    TEST_EQUAL(input->len, olen);
94    ASSERT_COMPARE(output, olen, expected_output->x, input->len);
95    mbedtls_free(output);
96    output = NULL;
97
98    ASSERT_ALLOC(output, tag->len);
99    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
100    TEST_EQUAL(0, olen);
101    ASSERT_COMPARE(output, tag->len, tag->x, tag->len);
102
103exit:
104    mbedtls_free(output);
105}
106
107static void check_empty_cipher_with_ad(mbedtls_gcm_context *ctx,
108                                       int mode,
109                                       const data_t *iv,
110                                       const data_t *add,
111                                       const data_t *tag,
112                                       size_t cipher_update_count)
113{
114    size_t olen;
115    size_t n;
116    uint8_t *output_tag = NULL;
117
118    TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, iv->x, iv->len));
119    TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, add->len));
120
121    for (n = 0; n < cipher_update_count; n++) {
122        olen = 0xdeadbeef;
123        TEST_EQUAL(0, mbedtls_gcm_update(ctx, NULL, 0, NULL, 0, &olen));
124        TEST_EQUAL(0, olen);
125    }
126
127    ASSERT_ALLOC(output_tag, tag->len);
128    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen,
129                                     output_tag, tag->len));
130    TEST_EQUAL(0, olen);
131    ASSERT_COMPARE(output_tag, tag->len, tag->x, tag->len);
132
133exit:
134    mbedtls_free(output_tag);
135}
136
137static void check_no_cipher_no_ad(mbedtls_gcm_context *ctx,
138                                  int mode,
139                                  const data_t *iv,
140                                  const data_t *tag)
141{
142    uint8_t *output = NULL;
143    size_t olen = 0;
144
145    TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
146                                     iv->x, iv->len));
147    ASSERT_ALLOC(output, tag->len);
148    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
149    TEST_EQUAL(0, olen);
150    ASSERT_COMPARE(output, tag->len, tag->x, tag->len);
151
152exit:
153    mbedtls_free(output);
154}
155
156/* END_HEADER */
157
158/* BEGIN_DEPENDENCIES
159 * depends_on:MBEDTLS_GCM_C
160 * END_DEPENDENCIES
161 */
162
163/* BEGIN_CASE */
164void gcm_bad_parameters(int cipher_id, int direction,
165                        data_t *key_str, data_t *src_str,
166                        data_t *iv_str, data_t *add_str,
167                        int tag_len_bits, int gcm_result)
168{
169    unsigned char output[128];
170    unsigned char tag_output[16];
171    mbedtls_gcm_context ctx;
172    size_t tag_len = tag_len_bits / 8;
173
174    mbedtls_gcm_init(&ctx);
175
176    memset(output, 0x00, sizeof(output));
177    memset(tag_output, 0x00, sizeof(tag_output));
178
179    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
180    TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, direction, src_str->len, iv_str->x, iv_str->len,
181                                          add_str->x, add_str->len, src_str->x, output, tag_len,
182                                          tag_output) == gcm_result);
183
184exit:
185    mbedtls_gcm_free(&ctx);
186}
187/* END_CASE */
188
189/* BEGIN_CASE */
190void gcm_encrypt_and_tag(int cipher_id, data_t *key_str,
191                         data_t *src_str, data_t *iv_str,
192                         data_t *add_str, data_t *dst,
193                         int tag_len_bits, data_t *tag,
194                         int init_result)
195{
196    unsigned char output[128];
197    unsigned char tag_output[16];
198    mbedtls_gcm_context ctx;
199    size_t tag_len = tag_len_bits / 8;
200    size_t n1;
201    size_t n1_add;
202
203    mbedtls_gcm_init(&ctx);
204
205    memset(output, 0x00, 128);
206    memset(tag_output, 0x00, 16);
207
208
209    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
210    if (init_result == 0) {
211        TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x,
212                                              iv_str->len, add_str->x, add_str->len, src_str->x,
213                                              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            for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) {
220                mbedtls_test_set_step(n1 * 10000 + n1_add);
221                if (!check_multipart(&ctx, MBEDTLS_GCM_ENCRYPT,
222                                     iv_str, add_str, src_str,
223                                     dst, tag,
224                                     n1, n1_add)) {
225                    goto exit;
226                }
227            }
228        }
229    }
230
231exit:
232    mbedtls_gcm_free(&ctx);
233}
234/* END_CASE */
235
236/* BEGIN_CASE */
237void gcm_decrypt_and_verify(int cipher_id, data_t *key_str,
238                            data_t *src_str, data_t *iv_str,
239                            data_t *add_str, int tag_len_bits,
240                            data_t *tag_str, char *result,
241                            data_t *pt_result, int init_result)
242{
243    unsigned char output[128];
244    mbedtls_gcm_context ctx;
245    int ret;
246    size_t tag_len = tag_len_bits / 8;
247    size_t n1;
248    size_t n1_add;
249
250    mbedtls_gcm_init(&ctx);
251
252    memset(output, 0x00, 128);
253
254
255    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
256    if (init_result == 0) {
257        ret = mbedtls_gcm_auth_decrypt(&ctx,
258                                       src_str->len,
259                                       iv_str->x,
260                                       iv_str->len,
261                                       add_str->x,
262                                       add_str->len,
263                                       tag_str->x,
264                                       tag_len,
265                                       src_str->x,
266                                       output);
267
268        if (strcmp("FAIL", result) == 0) {
269            TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED);
270        } else {
271            TEST_ASSERT(ret == 0);
272            ASSERT_COMPARE(output, src_str->len, pt_result->x, pt_result->len);
273
274            for (n1 = 0; n1 <= src_str->len; n1 += 1) {
275                for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) {
276                    mbedtls_test_set_step(n1 * 10000 + n1_add);
277                    if (!check_multipart(&ctx, MBEDTLS_GCM_DECRYPT,
278                                         iv_str, add_str, src_str,
279                                         pt_result, tag_str,
280                                         n1, n1_add)) {
281                        goto exit;
282                    }
283                }
284            }
285        }
286    }
287
288exit:
289    mbedtls_gcm_free(&ctx);
290}
291/* END_CASE */
292
293/* BEGIN_CASE */
294void gcm_decrypt_and_verify_empty_cipher(int cipher_id,
295                                         data_t *key_str,
296                                         data_t *iv_str,
297                                         data_t *add_str,
298                                         data_t *tag_str,
299                                         int cipher_update_calls)
300{
301    mbedtls_gcm_context ctx;
302
303    mbedtls_gcm_init(&ctx);
304
305    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
306    check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_DECRYPT,
307                               iv_str, add_str, tag_str,
308                               cipher_update_calls);
309
310    mbedtls_gcm_free(&ctx);
311}
312/* END_CASE */
313
314/* BEGIN_CASE */
315void gcm_decrypt_and_verify_empty_ad(int cipher_id,
316                                     data_t *key_str,
317                                     data_t *iv_str,
318                                     data_t *src_str,
319                                     data_t *tag_str,
320                                     data_t *pt_result,
321                                     int ad_update_calls)
322{
323    mbedtls_gcm_context ctx;
324
325    mbedtls_gcm_init(&ctx);
326
327    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
328    check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_DECRYPT,
329                               iv_str, src_str, pt_result, tag_str,
330                               ad_update_calls);
331
332    mbedtls_gcm_free(&ctx);
333}
334/* END_CASE */
335
336/* BEGIN_CASE */
337void gcm_decrypt_and_verify_no_ad_no_cipher(int cipher_id,
338                                            data_t *key_str,
339                                            data_t *iv_str,
340                                            data_t *tag_str)
341{
342    mbedtls_gcm_context ctx;
343
344    mbedtls_gcm_init(&ctx);
345
346    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
347    check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_DECRYPT,
348                          iv_str, tag_str);
349
350    mbedtls_gcm_free(&ctx);
351}
352/* END_CASE */
353
354/* BEGIN_CASE */
355void gcm_encrypt_and_tag_empty_cipher(int cipher_id,
356                                      data_t *key_str,
357                                      data_t *iv_str,
358                                      data_t *add_str,
359                                      data_t *tag_str,
360                                      int cipher_update_calls)
361{
362    mbedtls_gcm_context ctx;
363
364    mbedtls_gcm_init(&ctx);
365
366    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
367    check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
368                               iv_str, add_str, tag_str,
369                               cipher_update_calls);
370
371exit:
372    mbedtls_gcm_free(&ctx);
373}
374/* END_CASE */
375
376/* BEGIN_CASE */
377void gcm_encrypt_and_tag_empty_ad(int cipher_id,
378                                  data_t *key_str,
379                                  data_t *iv_str,
380                                  data_t *src_str,
381                                  data_t *dst,
382                                  data_t *tag_str,
383                                  int ad_update_calls)
384{
385    mbedtls_gcm_context ctx;
386
387    mbedtls_gcm_init(&ctx);
388
389    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
390    check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
391                               iv_str, src_str, dst, tag_str,
392                               ad_update_calls);
393
394exit:
395    mbedtls_gcm_free(&ctx);
396}
397/* END_CASE */
398
399/* BEGIN_CASE */
400void gcm_encrypt_and_verify_no_ad_no_cipher(int cipher_id,
401                                            data_t *key_str,
402                                            data_t *iv_str,
403                                            data_t *tag_str)
404{
405    mbedtls_gcm_context ctx;
406
407    mbedtls_gcm_init(&ctx);
408
409    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
410    check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
411                          iv_str, tag_str);
412
413    mbedtls_gcm_free(&ctx);
414}
415/* END_CASE */
416
417/* BEGIN_CASE */
418void gcm_invalid_param()
419{
420    mbedtls_gcm_context ctx;
421    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
422    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
423    int invalid_bitlen = 1;
424
425    mbedtls_gcm_init(&ctx);
426
427    /* mbedtls_gcm_setkey */
428    TEST_EQUAL(
429        MBEDTLS_ERR_GCM_BAD_INPUT,
430        mbedtls_gcm_setkey(&ctx, valid_cipher, valid_buffer, invalid_bitlen));
431
432exit:
433    mbedtls_gcm_free(&ctx);
434}
435/* END_CASE */
436
437/* BEGIN_CASE */
438void gcm_update_output_buffer_too_small(int cipher_id, int mode,
439                                        data_t *key_str, const data_t *input,
440                                        const data_t *iv)
441{
442    mbedtls_gcm_context ctx;
443    uint8_t *output = NULL;
444    size_t olen = 0;
445    size_t output_len = input->len - 1;
446
447    mbedtls_gcm_init(&ctx);
448    TEST_EQUAL(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8), 0);
449    TEST_EQUAL(0, mbedtls_gcm_starts(&ctx, mode, iv->x, iv->len));
450
451    ASSERT_ALLOC(output, output_len);
452    TEST_EQUAL(MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL,
453               mbedtls_gcm_update(&ctx, input->x, input->len, output, output_len, &olen));
454
455exit:
456    mbedtls_free(output);
457    mbedtls_gcm_free(&ctx);
458}
459/* END_CASE */
460
461/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */
462void gcm_selftest()
463{
464    TEST_ASSERT(mbedtls_gcm_self_test(1) == 0);
465}
466/* END_CASE */
467