1a8e1175bSopenharmony_ci/* BEGIN_HEADER */
2a8e1175bSopenharmony_ci#include "mbedtls/gcm.h"
3a8e1175bSopenharmony_ci
4a8e1175bSopenharmony_ci/* Use the multipart interface to process the encrypted data in two parts
5a8e1175bSopenharmony_ci * and check that the output matches the expected output.
6a8e1175bSopenharmony_ci * The context must have been set up with the key. */
7a8e1175bSopenharmony_cistatic int check_multipart(mbedtls_gcm_context *ctx,
8a8e1175bSopenharmony_ci                           int mode,
9a8e1175bSopenharmony_ci                           const data_t *iv,
10a8e1175bSopenharmony_ci                           const data_t *add,
11a8e1175bSopenharmony_ci                           const data_t *input,
12a8e1175bSopenharmony_ci                           const data_t *expected_output,
13a8e1175bSopenharmony_ci                           const data_t *tag,
14a8e1175bSopenharmony_ci                           size_t n1,
15a8e1175bSopenharmony_ci                           size_t n1_add)
16a8e1175bSopenharmony_ci{
17a8e1175bSopenharmony_ci    int ok = 0;
18a8e1175bSopenharmony_ci    uint8_t *output = NULL;
19a8e1175bSopenharmony_ci    size_t n2 = input->len - n1;
20a8e1175bSopenharmony_ci    size_t n2_add = add->len - n1_add;
21a8e1175bSopenharmony_ci    size_t olen;
22a8e1175bSopenharmony_ci
23a8e1175bSopenharmony_ci    /* Sanity checks on the test data */
24a8e1175bSopenharmony_ci    TEST_ASSERT(n1 <= input->len);
25a8e1175bSopenharmony_ci    TEST_ASSERT(n1_add <= add->len);
26a8e1175bSopenharmony_ci    TEST_EQUAL(input->len, expected_output->len);
27a8e1175bSopenharmony_ci
28a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
29a8e1175bSopenharmony_ci                                     iv->x, iv->len));
30a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, n1_add));
31a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x + n1_add, n2_add));
32a8e1175bSopenharmony_ci
33a8e1175bSopenharmony_ci    /* Allocate a tight buffer for each update call. This way, if the function
34a8e1175bSopenharmony_ci     * tries to write beyond the advertised required buffer size, this will
35a8e1175bSopenharmony_ci     * count as an overflow for memory sanitizers and static checkers. */
36a8e1175bSopenharmony_ci    TEST_CALLOC(output, n1);
37a8e1175bSopenharmony_ci    olen = 0xdeadbeef;
38a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, n1, output, n1, &olen));
39a8e1175bSopenharmony_ci    TEST_EQUAL(n1, olen);
40a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output, olen, expected_output->x, n1);
41a8e1175bSopenharmony_ci    mbedtls_free(output);
42a8e1175bSopenharmony_ci    output = NULL;
43a8e1175bSopenharmony_ci
44a8e1175bSopenharmony_ci    TEST_CALLOC(output, n2);
45a8e1175bSopenharmony_ci    olen = 0xdeadbeef;
46a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x + n1, n2, output, n2, &olen));
47a8e1175bSopenharmony_ci    TEST_EQUAL(n2, olen);
48a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output, olen, expected_output->x + n1, n2);
49a8e1175bSopenharmony_ci    mbedtls_free(output);
50a8e1175bSopenharmony_ci    output = NULL;
51a8e1175bSopenharmony_ci
52a8e1175bSopenharmony_ci    TEST_CALLOC(output, tag->len);
53a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
54a8e1175bSopenharmony_ci    TEST_EQUAL(0, olen);
55a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len);
56a8e1175bSopenharmony_ci    mbedtls_free(output);
57a8e1175bSopenharmony_ci    output = NULL;
58a8e1175bSopenharmony_ci
59a8e1175bSopenharmony_ci    ok = 1;
60a8e1175bSopenharmony_ciexit:
61a8e1175bSopenharmony_ci    mbedtls_free(output);
62a8e1175bSopenharmony_ci    return ok;
63a8e1175bSopenharmony_ci}
64a8e1175bSopenharmony_ci
65a8e1175bSopenharmony_cistatic void check_cipher_with_empty_ad(mbedtls_gcm_context *ctx,
66a8e1175bSopenharmony_ci                                       int mode,
67a8e1175bSopenharmony_ci                                       const data_t *iv,
68a8e1175bSopenharmony_ci                                       const data_t *input,
69a8e1175bSopenharmony_ci                                       const data_t *expected_output,
70a8e1175bSopenharmony_ci                                       const data_t *tag,
71a8e1175bSopenharmony_ci                                       size_t ad_update_count)
72a8e1175bSopenharmony_ci{
73a8e1175bSopenharmony_ci    size_t n;
74a8e1175bSopenharmony_ci    uint8_t *output = NULL;
75a8e1175bSopenharmony_ci    size_t olen;
76a8e1175bSopenharmony_ci
77a8e1175bSopenharmony_ci    /* Sanity checks on the test data */
78a8e1175bSopenharmony_ci    TEST_EQUAL(input->len, expected_output->len);
79a8e1175bSopenharmony_ci
80a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
81a8e1175bSopenharmony_ci                                     iv->x, iv->len));
82a8e1175bSopenharmony_ci
83a8e1175bSopenharmony_ci    for (n = 0; n < ad_update_count; n++) {
84a8e1175bSopenharmony_ci        TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, NULL, 0));
85a8e1175bSopenharmony_ci    }
86a8e1175bSopenharmony_ci
87a8e1175bSopenharmony_ci    /* Allocate a tight buffer for each update call. This way, if the function
88a8e1175bSopenharmony_ci     * tries to write beyond the advertised required buffer size, this will
89a8e1175bSopenharmony_ci     * count as an overflow for memory sanitizers and static checkers. */
90a8e1175bSopenharmony_ci    TEST_CALLOC(output, input->len);
91a8e1175bSopenharmony_ci    olen = 0xdeadbeef;
92a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, input->len, output, input->len, &olen));
93a8e1175bSopenharmony_ci    TEST_EQUAL(input->len, olen);
94a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output, olen, expected_output->x, input->len);
95a8e1175bSopenharmony_ci    mbedtls_free(output);
96a8e1175bSopenharmony_ci    output = NULL;
97a8e1175bSopenharmony_ci
98a8e1175bSopenharmony_ci    TEST_CALLOC(output, tag->len);
99a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
100a8e1175bSopenharmony_ci    TEST_EQUAL(0, olen);
101a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len);
102a8e1175bSopenharmony_ci
103a8e1175bSopenharmony_ciexit:
104a8e1175bSopenharmony_ci    mbedtls_free(output);
105a8e1175bSopenharmony_ci}
106a8e1175bSopenharmony_ci
107a8e1175bSopenharmony_cistatic void check_empty_cipher_with_ad(mbedtls_gcm_context *ctx,
108a8e1175bSopenharmony_ci                                       int mode,
109a8e1175bSopenharmony_ci                                       const data_t *iv,
110a8e1175bSopenharmony_ci                                       const data_t *add,
111a8e1175bSopenharmony_ci                                       const data_t *tag,
112a8e1175bSopenharmony_ci                                       size_t cipher_update_count)
113a8e1175bSopenharmony_ci{
114a8e1175bSopenharmony_ci    size_t olen;
115a8e1175bSopenharmony_ci    size_t n;
116a8e1175bSopenharmony_ci    uint8_t *output_tag = NULL;
117a8e1175bSopenharmony_ci
118a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, iv->x, iv->len));
119a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, add->len));
120a8e1175bSopenharmony_ci
121a8e1175bSopenharmony_ci    for (n = 0; n < cipher_update_count; n++) {
122a8e1175bSopenharmony_ci        olen = 0xdeadbeef;
123a8e1175bSopenharmony_ci        TEST_EQUAL(0, mbedtls_gcm_update(ctx, NULL, 0, NULL, 0, &olen));
124a8e1175bSopenharmony_ci        TEST_EQUAL(0, olen);
125a8e1175bSopenharmony_ci    }
126a8e1175bSopenharmony_ci
127a8e1175bSopenharmony_ci    TEST_CALLOC(output_tag, tag->len);
128a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen,
129a8e1175bSopenharmony_ci                                     output_tag, tag->len));
130a8e1175bSopenharmony_ci    TEST_EQUAL(0, olen);
131a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output_tag, tag->len, tag->x, tag->len);
132a8e1175bSopenharmony_ci
133a8e1175bSopenharmony_ciexit:
134a8e1175bSopenharmony_ci    mbedtls_free(output_tag);
135a8e1175bSopenharmony_ci}
136a8e1175bSopenharmony_ci
137a8e1175bSopenharmony_cistatic void check_no_cipher_no_ad(mbedtls_gcm_context *ctx,
138a8e1175bSopenharmony_ci                                  int mode,
139a8e1175bSopenharmony_ci                                  const data_t *iv,
140a8e1175bSopenharmony_ci                                  const data_t *tag)
141a8e1175bSopenharmony_ci{
142a8e1175bSopenharmony_ci    uint8_t *output = NULL;
143a8e1175bSopenharmony_ci    size_t olen = 0;
144a8e1175bSopenharmony_ci
145a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
146a8e1175bSopenharmony_ci                                     iv->x, iv->len));
147a8e1175bSopenharmony_ci    TEST_CALLOC(output, tag->len);
148a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
149a8e1175bSopenharmony_ci    TEST_EQUAL(0, olen);
150a8e1175bSopenharmony_ci    TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len);
151a8e1175bSopenharmony_ci
152a8e1175bSopenharmony_ciexit:
153a8e1175bSopenharmony_ci    mbedtls_free(output);
154a8e1175bSopenharmony_ci}
155a8e1175bSopenharmony_ci
156a8e1175bSopenharmony_cistatic void gcm_reset_ctx(mbedtls_gcm_context *ctx, const uint8_t *key,
157a8e1175bSopenharmony_ci                          size_t key_bits, const uint8_t *iv, size_t iv_len,
158a8e1175bSopenharmony_ci                          int starts_ret)
159a8e1175bSopenharmony_ci{
160a8e1175bSopenharmony_ci    int mode = MBEDTLS_GCM_ENCRYPT;
161a8e1175bSopenharmony_ci    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
162a8e1175bSopenharmony_ci
163a8e1175bSopenharmony_ci    mbedtls_gcm_init(ctx);
164a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_setkey(ctx, valid_cipher, key, key_bits), 0);
165a8e1175bSopenharmony_ci    TEST_EQUAL(starts_ret, mbedtls_gcm_starts(ctx, mode, iv, iv_len));
166a8e1175bSopenharmony_ciexit:
167a8e1175bSopenharmony_ci    /* empty */
168a8e1175bSopenharmony_ci    return;
169a8e1175bSopenharmony_ci}
170a8e1175bSopenharmony_ci
171a8e1175bSopenharmony_ci/* END_HEADER */
172a8e1175bSopenharmony_ci
173a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES
174a8e1175bSopenharmony_ci * depends_on:MBEDTLS_GCM_C
175a8e1175bSopenharmony_ci * END_DEPENDENCIES
176a8e1175bSopenharmony_ci */
177a8e1175bSopenharmony_ci
178a8e1175bSopenharmony_ci/* BEGIN_CASE */
179a8e1175bSopenharmony_civoid gcm_bad_parameters(int cipher_id, int direction,
180a8e1175bSopenharmony_ci                        data_t *key_str, data_t *src_str,
181a8e1175bSopenharmony_ci                        data_t *iv_str, data_t *add_str,
182a8e1175bSopenharmony_ci                        int tag_len_bits, int gcm_result)
183a8e1175bSopenharmony_ci{
184a8e1175bSopenharmony_ci    unsigned char output[128];
185a8e1175bSopenharmony_ci    unsigned char tag_output[16];
186a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
187a8e1175bSopenharmony_ci    size_t tag_len = tag_len_bits / 8;
188a8e1175bSopenharmony_ci
189a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
190a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
191a8e1175bSopenharmony_ci
192a8e1175bSopenharmony_ci    memset(output, 0x00, sizeof(output));
193a8e1175bSopenharmony_ci    memset(tag_output, 0x00, sizeof(tag_output));
194a8e1175bSopenharmony_ci
195a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
196a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, direction, src_str->len, iv_str->x, iv_str->len,
197a8e1175bSopenharmony_ci                                          add_str->x, add_str->len, src_str->x, output, tag_len,
198a8e1175bSopenharmony_ci                                          tag_output) == gcm_result);
199a8e1175bSopenharmony_ci
200a8e1175bSopenharmony_ciexit:
201a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
202a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
203a8e1175bSopenharmony_ci}
204a8e1175bSopenharmony_ci/* END_CASE */
205a8e1175bSopenharmony_ci
206a8e1175bSopenharmony_ci/* BEGIN_CASE */
207a8e1175bSopenharmony_civoid gcm_encrypt_and_tag(int cipher_id, data_t *key_str,
208a8e1175bSopenharmony_ci                         data_t *src_str, data_t *iv_str,
209a8e1175bSopenharmony_ci                         data_t *add_str, data_t *dst,
210a8e1175bSopenharmony_ci                         int tag_len_bits, data_t *tag,
211a8e1175bSopenharmony_ci                         int init_result)
212a8e1175bSopenharmony_ci{
213a8e1175bSopenharmony_ci    unsigned char output[128];
214a8e1175bSopenharmony_ci    unsigned char tag_output[16];
215a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
216a8e1175bSopenharmony_ci    size_t tag_len = tag_len_bits / 8;
217a8e1175bSopenharmony_ci    size_t n1;
218a8e1175bSopenharmony_ci    size_t n1_add;
219a8e1175bSopenharmony_ci
220a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
221a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
222a8e1175bSopenharmony_ci
223a8e1175bSopenharmony_ci    memset(output, 0x00, 128);
224a8e1175bSopenharmony_ci    memset(tag_output, 0x00, 16);
225a8e1175bSopenharmony_ci
226a8e1175bSopenharmony_ci
227a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
228a8e1175bSopenharmony_ci    if (init_result == 0) {
229a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x,
230a8e1175bSopenharmony_ci                                              iv_str->len, add_str->x, add_str->len, src_str->x,
231a8e1175bSopenharmony_ci                                              output, tag_len, tag_output) == 0);
232a8e1175bSopenharmony_ci
233a8e1175bSopenharmony_ci        TEST_MEMORY_COMPARE(output, src_str->len, dst->x, dst->len);
234a8e1175bSopenharmony_ci        TEST_MEMORY_COMPARE(tag_output, tag_len, tag->x, tag->len);
235a8e1175bSopenharmony_ci
236a8e1175bSopenharmony_ci        for (n1 = 0; n1 <= src_str->len; n1 += 1) {
237a8e1175bSopenharmony_ci            for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) {
238a8e1175bSopenharmony_ci                mbedtls_test_set_step(n1 * 10000 + n1_add);
239a8e1175bSopenharmony_ci                if (!check_multipart(&ctx, MBEDTLS_GCM_ENCRYPT,
240a8e1175bSopenharmony_ci                                     iv_str, add_str, src_str,
241a8e1175bSopenharmony_ci                                     dst, tag,
242a8e1175bSopenharmony_ci                                     n1, n1_add)) {
243a8e1175bSopenharmony_ci                    goto exit;
244a8e1175bSopenharmony_ci                }
245a8e1175bSopenharmony_ci            }
246a8e1175bSopenharmony_ci        }
247a8e1175bSopenharmony_ci    }
248a8e1175bSopenharmony_ci
249a8e1175bSopenharmony_ciexit:
250a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
251a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
252a8e1175bSopenharmony_ci}
253a8e1175bSopenharmony_ci/* END_CASE */
254a8e1175bSopenharmony_ci
255a8e1175bSopenharmony_ci/* BEGIN_CASE */
256a8e1175bSopenharmony_civoid gcm_decrypt_and_verify(int cipher_id, data_t *key_str,
257a8e1175bSopenharmony_ci                            data_t *src_str, data_t *iv_str,
258a8e1175bSopenharmony_ci                            data_t *add_str, int tag_len_bits,
259a8e1175bSopenharmony_ci                            data_t *tag_str, char *result,
260a8e1175bSopenharmony_ci                            data_t *pt_result, int init_result)
261a8e1175bSopenharmony_ci{
262a8e1175bSopenharmony_ci    unsigned char output[128];
263a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
264a8e1175bSopenharmony_ci    int ret;
265a8e1175bSopenharmony_ci    size_t tag_len = tag_len_bits / 8;
266a8e1175bSopenharmony_ci    size_t n1;
267a8e1175bSopenharmony_ci    size_t n1_add;
268a8e1175bSopenharmony_ci
269a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
270a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
271a8e1175bSopenharmony_ci
272a8e1175bSopenharmony_ci    memset(output, 0x00, 128);
273a8e1175bSopenharmony_ci
274a8e1175bSopenharmony_ci
275a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
276a8e1175bSopenharmony_ci    if (init_result == 0) {
277a8e1175bSopenharmony_ci        ret = mbedtls_gcm_auth_decrypt(&ctx,
278a8e1175bSopenharmony_ci                                       src_str->len,
279a8e1175bSopenharmony_ci                                       iv_str->x,
280a8e1175bSopenharmony_ci                                       iv_str->len,
281a8e1175bSopenharmony_ci                                       add_str->x,
282a8e1175bSopenharmony_ci                                       add_str->len,
283a8e1175bSopenharmony_ci                                       tag_str->x,
284a8e1175bSopenharmony_ci                                       tag_len,
285a8e1175bSopenharmony_ci                                       src_str->x,
286a8e1175bSopenharmony_ci                                       output);
287a8e1175bSopenharmony_ci
288a8e1175bSopenharmony_ci        if (strcmp("FAIL", result) == 0) {
289a8e1175bSopenharmony_ci            TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED);
290a8e1175bSopenharmony_ci        } else {
291a8e1175bSopenharmony_ci            TEST_ASSERT(ret == 0);
292a8e1175bSopenharmony_ci            TEST_MEMORY_COMPARE(output, src_str->len, pt_result->x, pt_result->len);
293a8e1175bSopenharmony_ci
294a8e1175bSopenharmony_ci            for (n1 = 0; n1 <= src_str->len; n1 += 1) {
295a8e1175bSopenharmony_ci                for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) {
296a8e1175bSopenharmony_ci                    mbedtls_test_set_step(n1 * 10000 + n1_add);
297a8e1175bSopenharmony_ci                    if (!check_multipart(&ctx, MBEDTLS_GCM_DECRYPT,
298a8e1175bSopenharmony_ci                                         iv_str, add_str, src_str,
299a8e1175bSopenharmony_ci                                         pt_result, tag_str,
300a8e1175bSopenharmony_ci                                         n1, n1_add)) {
301a8e1175bSopenharmony_ci                        goto exit;
302a8e1175bSopenharmony_ci                    }
303a8e1175bSopenharmony_ci                }
304a8e1175bSopenharmony_ci            }
305a8e1175bSopenharmony_ci        }
306a8e1175bSopenharmony_ci    }
307a8e1175bSopenharmony_ci
308a8e1175bSopenharmony_ciexit:
309a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
310a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
311a8e1175bSopenharmony_ci}
312a8e1175bSopenharmony_ci/* END_CASE */
313a8e1175bSopenharmony_ci
314a8e1175bSopenharmony_ci/* BEGIN_CASE */
315a8e1175bSopenharmony_civoid gcm_decrypt_and_verify_empty_cipher(int cipher_id,
316a8e1175bSopenharmony_ci                                         data_t *key_str,
317a8e1175bSopenharmony_ci                                         data_t *iv_str,
318a8e1175bSopenharmony_ci                                         data_t *add_str,
319a8e1175bSopenharmony_ci                                         data_t *tag_str,
320a8e1175bSopenharmony_ci                                         int cipher_update_calls)
321a8e1175bSopenharmony_ci{
322a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
323a8e1175bSopenharmony_ci
324a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
325a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
326a8e1175bSopenharmony_ci
327a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
328a8e1175bSopenharmony_ci    check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_DECRYPT,
329a8e1175bSopenharmony_ci                               iv_str, add_str, tag_str,
330a8e1175bSopenharmony_ci                               cipher_update_calls);
331a8e1175bSopenharmony_ci
332a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
333a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
334a8e1175bSopenharmony_ci}
335a8e1175bSopenharmony_ci/* END_CASE */
336a8e1175bSopenharmony_ci
337a8e1175bSopenharmony_ci/* BEGIN_CASE */
338a8e1175bSopenharmony_civoid gcm_decrypt_and_verify_empty_ad(int cipher_id,
339a8e1175bSopenharmony_ci                                     data_t *key_str,
340a8e1175bSopenharmony_ci                                     data_t *iv_str,
341a8e1175bSopenharmony_ci                                     data_t *src_str,
342a8e1175bSopenharmony_ci                                     data_t *tag_str,
343a8e1175bSopenharmony_ci                                     data_t *pt_result,
344a8e1175bSopenharmony_ci                                     int ad_update_calls)
345a8e1175bSopenharmony_ci{
346a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
347a8e1175bSopenharmony_ci
348a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
349a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
350a8e1175bSopenharmony_ci
351a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
352a8e1175bSopenharmony_ci    check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_DECRYPT,
353a8e1175bSopenharmony_ci                               iv_str, src_str, pt_result, tag_str,
354a8e1175bSopenharmony_ci                               ad_update_calls);
355a8e1175bSopenharmony_ci
356a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
357a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
358a8e1175bSopenharmony_ci}
359a8e1175bSopenharmony_ci/* END_CASE */
360a8e1175bSopenharmony_ci
361a8e1175bSopenharmony_ci/* BEGIN_CASE */
362a8e1175bSopenharmony_civoid gcm_decrypt_and_verify_no_ad_no_cipher(int cipher_id,
363a8e1175bSopenharmony_ci                                            data_t *key_str,
364a8e1175bSopenharmony_ci                                            data_t *iv_str,
365a8e1175bSopenharmony_ci                                            data_t *tag_str)
366a8e1175bSopenharmony_ci{
367a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
368a8e1175bSopenharmony_ci
369a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
370a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
371a8e1175bSopenharmony_ci
372a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
373a8e1175bSopenharmony_ci    check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_DECRYPT,
374a8e1175bSopenharmony_ci                          iv_str, tag_str);
375a8e1175bSopenharmony_ci
376a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
377a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
378a8e1175bSopenharmony_ci}
379a8e1175bSopenharmony_ci/* END_CASE */
380a8e1175bSopenharmony_ci
381a8e1175bSopenharmony_ci/* BEGIN_CASE */
382a8e1175bSopenharmony_civoid gcm_encrypt_and_tag_empty_cipher(int cipher_id,
383a8e1175bSopenharmony_ci                                      data_t *key_str,
384a8e1175bSopenharmony_ci                                      data_t *iv_str,
385a8e1175bSopenharmony_ci                                      data_t *add_str,
386a8e1175bSopenharmony_ci                                      data_t *tag_str,
387a8e1175bSopenharmony_ci                                      int cipher_update_calls)
388a8e1175bSopenharmony_ci{
389a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
390a8e1175bSopenharmony_ci
391a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
392a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
393a8e1175bSopenharmony_ci
394a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
395a8e1175bSopenharmony_ci    check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
396a8e1175bSopenharmony_ci                               iv_str, add_str, tag_str,
397a8e1175bSopenharmony_ci                               cipher_update_calls);
398a8e1175bSopenharmony_ci
399a8e1175bSopenharmony_ciexit:
400a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
401a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
402a8e1175bSopenharmony_ci}
403a8e1175bSopenharmony_ci/* END_CASE */
404a8e1175bSopenharmony_ci
405a8e1175bSopenharmony_ci/* BEGIN_CASE */
406a8e1175bSopenharmony_civoid gcm_encrypt_and_tag_empty_ad(int cipher_id,
407a8e1175bSopenharmony_ci                                  data_t *key_str,
408a8e1175bSopenharmony_ci                                  data_t *iv_str,
409a8e1175bSopenharmony_ci                                  data_t *src_str,
410a8e1175bSopenharmony_ci                                  data_t *dst,
411a8e1175bSopenharmony_ci                                  data_t *tag_str,
412a8e1175bSopenharmony_ci                                  int ad_update_calls)
413a8e1175bSopenharmony_ci{
414a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
415a8e1175bSopenharmony_ci
416a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
417a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
418a8e1175bSopenharmony_ci
419a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
420a8e1175bSopenharmony_ci    check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
421a8e1175bSopenharmony_ci                               iv_str, src_str, dst, tag_str,
422a8e1175bSopenharmony_ci                               ad_update_calls);
423a8e1175bSopenharmony_ci
424a8e1175bSopenharmony_ciexit:
425a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
426a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
427a8e1175bSopenharmony_ci}
428a8e1175bSopenharmony_ci/* END_CASE */
429a8e1175bSopenharmony_ci
430a8e1175bSopenharmony_ci/* BEGIN_CASE */
431a8e1175bSopenharmony_civoid gcm_encrypt_and_verify_no_ad_no_cipher(int cipher_id,
432a8e1175bSopenharmony_ci                                            data_t *key_str,
433a8e1175bSopenharmony_ci                                            data_t *iv_str,
434a8e1175bSopenharmony_ci                                            data_t *tag_str)
435a8e1175bSopenharmony_ci{
436a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
437a8e1175bSopenharmony_ci
438a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
439a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
440a8e1175bSopenharmony_ci
441a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
442a8e1175bSopenharmony_ci    check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
443a8e1175bSopenharmony_ci                          iv_str, tag_str);
444a8e1175bSopenharmony_ci
445a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
446a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
447a8e1175bSopenharmony_ci}
448a8e1175bSopenharmony_ci/* END_CASE */
449a8e1175bSopenharmony_ci
450a8e1175bSopenharmony_ci/* BEGIN_CASE */
451a8e1175bSopenharmony_civoid gcm_invalid_param()
452a8e1175bSopenharmony_ci{
453a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
454a8e1175bSopenharmony_ci    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
455a8e1175bSopenharmony_ci    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
456a8e1175bSopenharmony_ci    int invalid_bitlen = 1;
457a8e1175bSopenharmony_ci
458a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
459a8e1175bSopenharmony_ci
460a8e1175bSopenharmony_ci    /* mbedtls_gcm_setkey */
461a8e1175bSopenharmony_ci    TEST_EQUAL(
462a8e1175bSopenharmony_ci        MBEDTLS_ERR_GCM_BAD_INPUT,
463a8e1175bSopenharmony_ci        mbedtls_gcm_setkey(&ctx, valid_cipher, valid_buffer, invalid_bitlen));
464a8e1175bSopenharmony_ci
465a8e1175bSopenharmony_ciexit:
466a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
467a8e1175bSopenharmony_ci}
468a8e1175bSopenharmony_ci/* END_CASE */
469a8e1175bSopenharmony_ci
470a8e1175bSopenharmony_ci/* BEGIN_CASE */
471a8e1175bSopenharmony_civoid gcm_update_output_buffer_too_small(int cipher_id, int mode,
472a8e1175bSopenharmony_ci                                        data_t *key_str, const data_t *input,
473a8e1175bSopenharmony_ci                                        const data_t *iv)
474a8e1175bSopenharmony_ci{
475a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
476a8e1175bSopenharmony_ci    uint8_t *output = NULL;
477a8e1175bSopenharmony_ci    size_t olen = 0;
478a8e1175bSopenharmony_ci    size_t output_len = input->len - 1;
479a8e1175bSopenharmony_ci
480a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
481a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
482a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8), 0);
483a8e1175bSopenharmony_ci    TEST_EQUAL(0, mbedtls_gcm_starts(&ctx, mode, iv->x, iv->len));
484a8e1175bSopenharmony_ci
485a8e1175bSopenharmony_ci    TEST_CALLOC(output, output_len);
486a8e1175bSopenharmony_ci    TEST_EQUAL(MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL,
487a8e1175bSopenharmony_ci               mbedtls_gcm_update(&ctx, input->x, input->len, output, output_len, &olen));
488a8e1175bSopenharmony_ci
489a8e1175bSopenharmony_ciexit:
490a8e1175bSopenharmony_ci    mbedtls_free(output);
491a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
492a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
493a8e1175bSopenharmony_ci}
494a8e1175bSopenharmony_ci/* END_CASE */
495a8e1175bSopenharmony_ci
496a8e1175bSopenharmony_ci/* BEGIN_CASE */
497a8e1175bSopenharmony_ci/* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of IV should
498a8e1175bSopenharmony_ci * satisfy 1 <= bit_len(IV) <= 2^64 - 1. */
499a8e1175bSopenharmony_civoid gcm_invalid_iv_len(void)
500a8e1175bSopenharmony_ci{
501a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
502a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
503a8e1175bSopenharmony_ci    uint8_t b16[16] = { 0 };
504a8e1175bSopenharmony_ci
505a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
506a8e1175bSopenharmony_ci
507a8e1175bSopenharmony_ci    // Invalid IV length 0
508a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 0, MBEDTLS_ERR_GCM_BAD_INPUT);
509a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
510a8e1175bSopenharmony_ci
511a8e1175bSopenharmony_ci    // Only testable on platforms where sizeof(size_t) >= 8.
512a8e1175bSopenharmony_ci#if SIZE_MAX >= UINT64_MAX
513a8e1175bSopenharmony_ci    // Invalid IV length 2^61
514a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 1ULL << 61, MBEDTLS_ERR_GCM_BAD_INPUT);
515a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
516a8e1175bSopenharmony_ci#endif
517a8e1175bSopenharmony_ci
518a8e1175bSopenharmony_ci    goto exit; /* To suppress error that exit is defined but not used */
519a8e1175bSopenharmony_ciexit:
520a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
521a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
522a8e1175bSopenharmony_ci}
523a8e1175bSopenharmony_ci/* END_CASE */
524a8e1175bSopenharmony_ci
525a8e1175bSopenharmony_ci/* BEGIN_CASE */
526a8e1175bSopenharmony_civoid gcm_add_len_too_long(void)
527a8e1175bSopenharmony_ci{
528a8e1175bSopenharmony_ci    // Only testable on platforms where sizeof(size_t) >= 8.
529a8e1175bSopenharmony_ci#if SIZE_MAX >= UINT64_MAX
530a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
531a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
532a8e1175bSopenharmony_ci    uint8_t b16[16] = { 0 };
533a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
534a8e1175bSopenharmony_ci
535a8e1175bSopenharmony_ci    /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of AD should
536a8e1175bSopenharmony_ci     * be <= 2^64 - 1, ie < 2^64. This is the minimum invalid length in bytes. */
537a8e1175bSopenharmony_ci    uint64_t len_max = 1ULL << 61;
538a8e1175bSopenharmony_ci
539a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
540a8e1175bSopenharmony_ci    // Feed AD that just exceeds the length limit
541a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max),
542a8e1175bSopenharmony_ci               MBEDTLS_ERR_GCM_BAD_INPUT);
543a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
544a8e1175bSopenharmony_ci
545a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
546a8e1175bSopenharmony_ci    // Feed AD that just exceeds the length limit in two calls
547a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0);
548a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max - 1),
549a8e1175bSopenharmony_ci               MBEDTLS_ERR_GCM_BAD_INPUT);
550a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
551a8e1175bSopenharmony_ci
552a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
553a8e1175bSopenharmony_ci    // Test if potential total AD length overflow is handled properly
554a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0);
555a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, UINT64_MAX), MBEDTLS_ERR_GCM_BAD_INPUT);
556a8e1175bSopenharmony_ci
557a8e1175bSopenharmony_ciexit:
558a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
559a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
560a8e1175bSopenharmony_ci#endif
561a8e1175bSopenharmony_ci}
562a8e1175bSopenharmony_ci/* END_CASE */
563a8e1175bSopenharmony_ci
564a8e1175bSopenharmony_ci/* BEGIN_CASE */
565a8e1175bSopenharmony_civoid gcm_input_len_too_long(void)
566a8e1175bSopenharmony_ci{
567a8e1175bSopenharmony_ci    // Only testable on platforms where sizeof(size_t) >= 8
568a8e1175bSopenharmony_ci#if SIZE_MAX >= UINT64_MAX
569a8e1175bSopenharmony_ci    mbedtls_gcm_context ctx;
570a8e1175bSopenharmony_ci    uint8_t b16[16] = { 0 };
571a8e1175bSopenharmony_ci    uint8_t out[1];
572a8e1175bSopenharmony_ci    size_t out_len;
573a8e1175bSopenharmony_ci    mbedtls_gcm_init(&ctx);
574a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
575a8e1175bSopenharmony_ci
576a8e1175bSopenharmony_ci    /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of input should
577a8e1175bSopenharmony_ci     * be <= 2^39 - 256. This is the maximum valid length in bytes. */
578a8e1175bSopenharmony_ci    uint64_t len_max = (1ULL << 36) - 32;
579a8e1175bSopenharmony_ci
580a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
581a8e1175bSopenharmony_ci    // Feed input that just exceeds the length limit
582a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max + 1, out, len_max + 1,
583a8e1175bSopenharmony_ci                                  &out_len),
584a8e1175bSopenharmony_ci               MBEDTLS_ERR_GCM_BAD_INPUT);
585a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
586a8e1175bSopenharmony_ci
587a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
588a8e1175bSopenharmony_ci    // Feed input that just exceeds the length limit in two calls
589a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0);
590a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, out, len_max, &out_len),
591a8e1175bSopenharmony_ci               MBEDTLS_ERR_GCM_BAD_INPUT);
592a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
593a8e1175bSopenharmony_ci
594a8e1175bSopenharmony_ci    gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
595a8e1175bSopenharmony_ci    // Test if potential total input length overflow is handled properly
596a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0);
597a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, UINT64_MAX, out, UINT64_MAX,
598a8e1175bSopenharmony_ci                                  &out_len),
599a8e1175bSopenharmony_ci               MBEDTLS_ERR_GCM_BAD_INPUT);
600a8e1175bSopenharmony_ci
601a8e1175bSopenharmony_ciexit:
602a8e1175bSopenharmony_ci    mbedtls_gcm_free(&ctx);
603a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
604a8e1175bSopenharmony_ci#endif
605a8e1175bSopenharmony_ci}
606a8e1175bSopenharmony_ci/* END_CASE */
607a8e1175bSopenharmony_ci
608a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_CCM_GCM_CAN_AES */
609a8e1175bSopenharmony_civoid gcm_selftest()
610a8e1175bSopenharmony_ci{
611a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_INIT();
612a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_gcm_self_test(1) == 0);
613a8e1175bSopenharmony_ci    BLOCK_CIPHER_PSA_DONE();
614a8e1175bSopenharmony_ci}
615a8e1175bSopenharmony_ci/* END_CASE */
616