Commit 3857074503 for openssl.org

commit 385707450376d8611905cf48a03be62ef98b1f6a
Author: Daniel Kubec <kubec@openssl.foundation>
Date:   Sat Oct 31 19:16:17 2026 +0100

    test/evp_extra_test.c: add tests for CVE-2026-88823

    Assisted-by: Claude:claude-fable-5-1
    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Reviewed-by: Norbert Pocs <norbertp@openssl.org>
    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Merge-date: Wed Nov  4 12:15:49 2026
    Merged-from: https://github.com/openssl/openssl/pull/33456

diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 70c23536d6..7182b1cb28 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -7905,7 +7905,7 @@ static int test_aes_gcm_siv_empty_data(void)
     unsigned char out[16];
     int outl, ret = 0;
     EVP_CIPHER_CTX *ctx = NULL;
-    EVP_CIPHER *c = EVP_CIPHER_fetch(NULL, "AES-128-GCM-SIV", NULL);
+    EVP_CIPHER *c = EVP_CIPHER_fetch(testctx, "AES-128-GCM-SIV", testpropq);

     if (c == NULL) {
         return TEST_skip("AES-128-GCM-SIV cipher is not available");
@@ -7971,6 +7971,406 @@ err:
     return ret;
 }

+/* A zero-length AAD update must be a no-op for AES-GCM-SIV. */
+static int gcm_siv_encrypt_aad_seq(const EVP_CIPHER *c,
+    const unsigned char *key, const unsigned char *nonce,
+    int aad_before, int empty_aad, int aad_after,
+    const unsigned char *aad, size_t aad_len,
+    const unsigned char *pt, size_t pt_len,
+    unsigned char *ct, unsigned char *tag)
+{
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+    unsigned char dummy = 0;
+    int outl, ret = 0;
+
+    if (!TEST_ptr(ctx) || !TEST_true(EVP_EncryptInit_ex2(ctx, c, key, nonce, NULL)))
+        goto err;
+    if (aad_before != 0
+        && !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, aad, (int)aad_len)))
+        goto err;
+    if (empty_aad != 0 && !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, &dummy, 0)))
+        goto err;
+    if (aad_after != 0
+        && !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, aad, (int)aad_len)))
+        goto err;
+    if (!TEST_true(EVP_EncryptUpdate(ctx, ct, &outl, pt, (int)pt_len))
+        || !TEST_int_eq(outl, (int)pt_len)
+        || !TEST_true(EVP_EncryptFinal_ex(ctx, ct + outl, &outl))
+        || !TEST_int_eq(outl, 0)
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tag)))
+        goto err;
+    ret = 1;
+err:
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
+static int gcm_siv_decrypt_aad_seq(const EVP_CIPHER *c,
+    const unsigned char *key, const unsigned char *nonce,
+    const unsigned char *aad, size_t aad_len,
+    const unsigned char *ct, size_t ct_len,
+    unsigned char *tag, unsigned char *out)
+{
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+    unsigned char dummy = 0;
+    int outl, ret = 0;
+
+    /* AAD followed by an empty fragment, then the ciphertext */
+    if (!TEST_ptr(ctx)
+        || !TEST_true(EVP_DecryptInit_ex2(ctx, c, key, nonce, NULL))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, tag))
+        || !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, aad, (int)aad_len))
+        || !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, &dummy, 0))
+        || !TEST_true(EVP_DecryptUpdate(ctx, out, &outl, ct, (int)ct_len))
+        || !TEST_int_eq(outl, (int)ct_len))
+        goto err;
+    /* Tag verification result is the return value, not a test assertion */
+    ret = EVP_DecryptFinal_ex(ctx, out + outl, &outl);
+err:
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
+static int test_aes_gcm_siv_zero_length_aad(void)
+{
+    EVP_CIPHER *c = EVP_CIPHER_fetch(testctx, "AES-128-GCM-SIV", testpropq);
+    const unsigned char key[16] = { 0x01 }, nonce[12] = { 0x01 };
+    const unsigned char aad[] = "role=user", pt[] = "transfer 100 to bob";
+    const size_t aad_len = sizeof(aad) - 1, pt_len = sizeof(pt) - 1;
+    unsigned char ct_ref[sizeof(pt) - 1], ct_none[sizeof(pt) - 1];
+    unsigned char ct[sizeof(pt) - 1], out[sizeof(pt) - 1];
+    unsigned char tag_ref[16], tag_none[16], tag[16];
+    int ret = 0;
+
+    if (c == NULL)
+        return TEST_skip("AES-128-GCM-SIV cipher is not available");
+
+    /* Reference: AAD supplied in a single fragment */
+    if (!TEST_true(gcm_siv_encrypt_aad_seq(c, key, nonce, 1, 0, 0,
+            aad, aad_len, pt, pt_len, ct_ref, tag_ref)))
+        goto err;
+
+    /* Sanity: no AAD at all must authenticate differently */
+    if (!TEST_true(gcm_siv_encrypt_aad_seq(c, key, nonce, 0, 0, 0,
+            aad, aad_len, pt, pt_len, ct_none, tag_none))
+        || !TEST_mem_ne(tag_none, sizeof(tag_none), tag_ref, sizeof(tag_ref)))
+        goto err;
+
+    /* AAD followed by an empty fragment must equal AAD alone, not no AAD */
+    if (!TEST_true(gcm_siv_encrypt_aad_seq(c, key, nonce, 1, 1, 0,
+            aad, aad_len, pt, pt_len, ct, tag))
+        || !TEST_mem_eq(tag, sizeof(tag), tag_ref, sizeof(tag_ref))
+        || !TEST_mem_eq(ct, sizeof(ct), ct_ref, sizeof(ct_ref)))
+        goto err;
+
+    /* An empty fragment followed by AAD must also equal AAD alone */
+    if (!TEST_true(gcm_siv_encrypt_aad_seq(c, key, nonce, 0, 1, 1,
+            aad, aad_len, pt, pt_len, ct, tag))
+        || !TEST_mem_eq(tag, sizeof(tag), tag_ref, sizeof(tag_ref))
+        || !TEST_mem_eq(ct, sizeof(ct), ct_ref, sizeof(ct_ref)))
+        goto err;
+
+    /* A lone empty fragment must equal no AAD */
+    if (!TEST_true(gcm_siv_encrypt_aad_seq(c, key, nonce, 0, 1, 0,
+            aad, aad_len, pt, pt_len, ct, tag))
+        || !TEST_mem_eq(tag, sizeof(tag), tag_none, sizeof(tag_none))
+        || !TEST_mem_eq(ct, sizeof(ct), ct_none, sizeof(ct_none)))
+        goto err;
+
+    /* Decrypt the reference with AAD + empty fragment: must verify */
+    if (!TEST_true(gcm_siv_decrypt_aad_seq(c, key, nonce, aad, aad_len,
+            ct_ref, sizeof(ct_ref), tag_ref, out))
+        || !TEST_mem_eq(out, sizeof(out), pt, pt_len))
+        goto err;
+
+    /* Decrypt the no-AAD message with AAD + empty fragment: must fail. */
+    if (!TEST_false(gcm_siv_decrypt_aad_seq(c, key, nonce, aad, aad_len,
+            ct_none, sizeof(ct_none), tag_none, out)))
+        goto err;
+
+    ret = 1;
+err:
+    EVP_CIPHER_free(c);
+    return ret;
+}
+
+/*
+ * Seal pt under key, nonce and aad with a fresh context, producing ct and
+ * tag.  A zero aad_len means no AAD update at all.
+ */
+static int gcm_siv_seal(const EVP_CIPHER *c, const unsigned char *key,
+    const unsigned char *nonce, const unsigned char *aad, size_t aad_len,
+    const unsigned char *pt, size_t pt_len, unsigned char *ct,
+    unsigned char *tag)
+{
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+    int outl, ret = 0;
+
+    if (!TEST_ptr(ctx)
+        || !TEST_true(EVP_EncryptInit_ex2(ctx, c, key, nonce, NULL)))
+        goto err;
+    if (aad_len > 0
+        && !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, aad, (int)aad_len)))
+        goto err;
+    if (!TEST_true(EVP_EncryptUpdate(ctx, ct, &outl, pt, (int)pt_len))
+        || !TEST_int_eq(outl, (int)pt_len)
+        || !TEST_true(EVP_EncryptFinal_ex(ctx, ct + outl, &outl))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tag)))
+        goto err;
+    ret = 1;
+err:
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
+/*
+ * A long-lived receiver context: keyed once, then re-initialised with the
+ * nonce only for every message it receives.
+ */
+static EVP_CIPHER_CTX *gcm_siv_receiver_new(const EVP_CIPHER *c,
+    const unsigned char *key)
+{
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+
+    if (ctx != NULL && !EVP_DecryptInit_ex2(ctx, c, key, NULL, NULL)) {
+        EVP_CIPHER_CTX_free(ctx);
+        ctx = NULL;
+    }
+    return ctx;
+}
+
+/*
+ * Present nonce, ct and tag to the receiver, which supplies aad as the AAD
+ * it believes the message is bound to (none if aad_len is zero). Returns 1 if
+ * the outcome of EVP_DecryptFinal_ex() matches expect_ok and, when the tag was
+ * expected to verify, the recovered plaintext equals pt.
+ */
+static int gcm_siv_receive(EVP_CIPHER_CTX *ctx, const unsigned char *nonce,
+    const unsigned char *aad, size_t aad_len,
+    const unsigned char *ct, size_t ct_len, const unsigned char *tag,
+    const unsigned char *pt, int expect_ok)
+{
+    unsigned char out[64];
+    int outl, ok;
+
+    if (!TEST_size_t_le(ct_len, sizeof(out))
+        || !TEST_true(EVP_DecryptInit_ex2(ctx, NULL, NULL, nonce, NULL))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16,
+            (void *)tag)))
+        return 0;
+    if (aad_len > 0
+        && !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, aad, (int)aad_len)))
+        return 0;
+    if (!TEST_true(EVP_DecryptUpdate(ctx, out, &outl, ct, (int)ct_len))
+        || !TEST_int_eq(outl, (int)ct_len))
+        return 0;
+    ok = EVP_DecryptFinal_ex(ctx, out + outl, &outl) == 1;
+    if (!ok)
+        ERR_clear_error();
+    if (!TEST_int_eq(ok, expect_ok))
+        return 0;
+    if (expect_ok && !TEST_mem_eq(out, ct_len, pt, ct_len))
+        return 0;
+    return 1;
+}
+
+/*
+ * Seal a message bound to an AAD and hand it to a long-lived receiver
+ * context. The receiver first verifies it honestly with the correct AAD,
+ * then is re-initialised with the nonce only and given the same ciphertext
+ * and tag again with no AAD at all. The AAD supplied for the first message
+ * must not carry over into the second, so the second presentation must be
+ * rejected. Neither ciphertext nor tag is modified.
+ */
+static int test_aes_gcm_siv_reinit_aad_replay(void)
+{
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *c = EVP_CIPHER_fetch(testctx, "AES-128-GCM-SIV", testpropq);
+    unsigned char key[16] = { 0x01 }, n[12] = { 0x01 };
+    unsigned char aad[] = "tenant=A;role=admin";
+    unsigned char pt[] = "transfer 100 to bob";
+    size_t aad_len = sizeof(aad) - 1, pt_len = sizeof(pt) - 1;
+    unsigned char ct[sizeof(pt)], tag[16];
+    int test = 0;
+
+    if (c == NULL)
+        return TEST_skip("AES-128-GCM-SIV cipher is not available");
+
+    /* Honest verification, then the same message replayed unbound */
+    test = TEST_true(gcm_siv_seal(c, key, n, aad, aad_len, pt, pt_len, ct, tag))
+        && TEST_ptr(ctx = gcm_siv_receiver_new(c, key))
+        && TEST_true(gcm_siv_receive(ctx, n, aad, aad_len, ct, pt_len, tag, pt, 1))
+        && TEST_true(gcm_siv_receive(ctx, n, NULL, 0, ct, pt_len, tag, pt, 0));
+
+    EVP_CIPHER_CTX_free(ctx);
+    EVP_CIPHER_free(c);
+    return test;
+}
+
+/*
+ * Seal a message bound to the AAD "tenant=A;role=admin" and hand it to a
+ * long-lived receiver context. The receiver is first given a garbage tag
+ * together with the AAD prefix "tenant=A;", which it rejects. It is then
+ * re-initialised with the nonce only and given the genuine ciphertext and
+ * tag under the AAD suffix "role=admin" alone. The prefix from the rejected
+ * attempt must not be concatenated with the suffix, so the second
+ * presentation must be rejected. Neither ciphertext nor tag is modified.
+ */
+static int test_aes_gcm_siv_reinit_aad_prefix(void)
+{
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *c = EVP_CIPHER_fetch(testctx, "AES-128-GCM-SIV", testpropq);
+    unsigned char key[16] = { 0x01 }, n[12] = { 0x01 };
+    unsigned char aad[] = "tenant=A;role=admin";
+    unsigned char pt[] = "transfer 100 to bob";
+    size_t aad_len = sizeof(aad) - 1, pt_len = sizeof(pt) - 1;
+    size_t prefix_len = sizeof("tenant=A;") - 1;
+    unsigned char ct[sizeof(pt)], tag[16], bad_tag[16] = { 0 };
+    int test = 0;
+
+    if (c == NULL)
+        return TEST_skip("AES-128-GCM-SIV cipher is not available");
+
+    /* Rejected probe plants the prefix, replay claims the rest */
+    test = TEST_true(gcm_siv_seal(c, key, n, aad, aad_len, pt, pt_len, ct, tag))
+        && TEST_ptr(ctx = gcm_siv_receiver_new(c, key))
+        && TEST_true(gcm_siv_receive(ctx, n, aad, prefix_len, ct, pt_len,
+            bad_tag, pt, 0))
+        && TEST_true(gcm_siv_receive(ctx, n, aad + prefix_len,
+            aad_len - prefix_len, ct, pt_len, tag, pt, 0));
+
+    EVP_CIPHER_CTX_free(ctx);
+    EVP_CIPHER_free(c);
+    return test;
+}
+
+/*
+ * Re-initialising a long-lived receiver with neither key nor nonce after a
+ * completed decryption restarts the operation under the same key and nonce.
+ * The AAD of the completed message must not survive that restart: the
+ * genuine ciphertext and tag presented again with no AAD, or after an empty
+ * AAD fragment, must be rejected, and presented again with the correct AAD
+ * must still verify. Neither ciphertext nor tag is modified.
+ */
+static int test_aes_gcm_siv_reinit_aad_replay_no_nonce(void)
+{
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *c = EVP_CIPHER_fetch(testctx, "AES-128-GCM-SIV", testpropq);
+    unsigned char key[16] = { 0x01 }, n[12] = { 0x01 }, dummy = 0;
+    unsigned char aad[] = "tenant=A;role=admin";
+    unsigned char pt[] = "transfer 100 to bob";
+    size_t aad_len = sizeof(aad) - 1, pt_len = sizeof(pt) - 1;
+    unsigned char ct[sizeof(pt)], tag[16], out[sizeof(pt)];
+    int outl, test = 0;
+
+    if (c == NULL)
+        return TEST_skip("AES-128-GCM-SIV cipher is not available");
+
+    if (!TEST_true(gcm_siv_seal(c, key, n, aad, aad_len, pt, pt_len, ct, tag))
+        || !TEST_ptr(ctx = gcm_siv_receiver_new(c, key))
+        || !TEST_true(gcm_siv_receive(ctx, n, aad, aad_len, ct, pt_len, tag, pt, 1)))
+        goto err;
+
+    /* Restart without key or nonce: the previous AAD must be gone */
+    if (!TEST_true(EVP_DecryptInit_ex2(ctx, NULL, NULL, NULL, NULL))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, tag))
+        || !TEST_true(EVP_DecryptUpdate(ctx, out, &outl, ct, (int)pt_len))
+        || !TEST_false(EVP_DecryptFinal_ex(ctx, out + outl, &outl)))
+        goto err;
+    ERR_clear_error();
+
+    /* Same restart, with an empty AAD fragment that must not act as a reset */
+    if (!TEST_true(EVP_DecryptInit_ex2(ctx, NULL, NULL, NULL, NULL))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, tag))
+        || !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, &dummy, 0))
+        || !TEST_true(EVP_DecryptUpdate(ctx, out, &outl, ct, (int)pt_len))
+        || !TEST_false(EVP_DecryptFinal_ex(ctx, out + outl, &outl)))
+        goto err;
+    ERR_clear_error();
+
+    /* The restarted context must still accept the message with its AAD */
+    if (!TEST_true(EVP_DecryptInit_ex2(ctx, NULL, NULL, NULL, NULL))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, tag))
+        || !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, aad, (int)aad_len))
+        || !TEST_true(EVP_DecryptUpdate(ctx, out, &outl, ct, (int)pt_len))
+        || !TEST_int_eq(outl, (int)pt_len)
+        || !TEST_true(EVP_DecryptFinal_ex(ctx, out + outl, &outl))
+        || !TEST_mem_eq(out, pt_len, pt, pt_len))
+        goto err;
+
+    test = 1;
+err:
+    EVP_CIPHER_CTX_free(ctx);
+    EVP_CIPHER_free(c);
+    return test;
+}
+
+/*
+ * A re-initialisation with neither key nor nonce before the payload is a
+ * parameter adjustment, not a new message, so the AAD supplied before it
+ * must survive. The sender supplies the AAD prefix, re-initialises with no
+ * arguments, then supplies the suffix and the payload, and must produce the
+ * same ciphertext and tag as a single-fragment seal. The receiver supplies
+ * the prefix, re-initialises with the tag as its only parameter, then
+ * supplies the suffix and the payload, and the message must verify.
+ */
+static int test_aes_gcm_siv_reinit_aad_params_only_keeps(void)
+{
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *c = EVP_CIPHER_fetch(testctx, "AES-128-GCM-SIV", testpropq);
+    unsigned char key[16] = { 0x01 }, n[12] = { 0x01 };
+    unsigned char aad[] = "tenant=A;role=admin";
+    unsigned char pt[] = "transfer 100 to bob";
+    size_t aad_len = sizeof(aad) - 1, pt_len = sizeof(pt) - 1;
+    size_t prefix_len = sizeof("tenant=A;") - 1;
+    unsigned char ct[sizeof(pt)], tag[16], ct2[sizeof(pt)], tag2[16];
+    unsigned char out[sizeof(pt)];
+    OSSL_PARAM params[2];
+    int outl, test = 0;
+
+    if (c == NULL)
+        return TEST_skip("AES-128-GCM-SIV cipher is not available");
+
+    if (!TEST_true(gcm_siv_seal(c, key, n, aad, aad_len, pt, pt_len, ct, tag))
+        || !TEST_ptr(ctx = EVP_CIPHER_CTX_new()))
+        goto err;
+
+    /* Sender: AAD prefix, parameters-only re-init, AAD suffix, payload */
+    if (!TEST_true(EVP_EncryptInit_ex2(ctx, c, key, n, NULL))
+        || !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, aad, (int)prefix_len))
+        || !TEST_true(EVP_EncryptInit_ex2(ctx, NULL, NULL, NULL, NULL))
+        || !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, aad + prefix_len,
+            (int)(aad_len - prefix_len)))
+        || !TEST_true(EVP_EncryptUpdate(ctx, ct2, &outl, pt, (int)pt_len))
+        || !TEST_int_eq(outl, (int)pt_len)
+        || !TEST_true(EVP_EncryptFinal_ex(ctx, ct2 + outl, &outl))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tag2))
+        || !TEST_mem_eq(ct2, pt_len, ct, pt_len)
+        || !TEST_mem_eq(tag2, sizeof(tag2), tag, sizeof(tag)))
+        goto err;
+
+    /* Receiver: AAD prefix, tag via parameters-only re-init, AAD suffix, payload */
+    params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
+        tag, sizeof(tag));
+    params[1] = OSSL_PARAM_construct_end();
+    if (!TEST_true(EVP_DecryptInit_ex2(ctx, c, key, n, NULL))
+        || !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, aad, (int)prefix_len))
+        || !TEST_true(EVP_DecryptInit_ex2(ctx, NULL, NULL, NULL, params))
+        || !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, aad + prefix_len,
+            (int)(aad_len - prefix_len)))
+        || !TEST_true(EVP_DecryptUpdate(ctx, out, &outl, ct, (int)pt_len))
+        || !TEST_int_eq(outl, (int)pt_len)
+        || !TEST_true(EVP_DecryptFinal_ex(ctx, out + outl, &outl))
+        || !TEST_mem_eq(out, pt_len, pt, pt_len))
+        goto err;
+
+    test = 1;
+err:
+    EVP_CIPHER_CTX_free(ctx);
+    EVP_CIPHER_free(c);
+    return test;
+}
+
 /*
  * AES-SIV reuse-without-rekey:
  *   msg1: legit non-empty CT, tag verifies, final_ret=0
@@ -9691,6 +10091,11 @@ int setup_tests(void)
     ADD_TEST(test_aes_gcm_siv_empty_data);
     ADD_TEST(test_aes_siv_ctx_reuse);
     ADD_TEST(test_aes_siv_ctx_dec_retval);
+    ADD_TEST(test_aes_gcm_siv_reinit_aad_replay);
+    ADD_TEST(test_aes_gcm_siv_reinit_aad_prefix);
+    ADD_TEST(test_aes_gcm_siv_reinit_aad_replay_no_nonce);
+    ADD_TEST(test_aes_gcm_siv_reinit_aad_params_only_keeps);
+    ADD_TEST(test_aes_gcm_siv_zero_length_aad);

     ADD_TEST(test_invalid_ctx_for_digest);