static void check_gcm(const void *key, size_t nkey, const void *plain, size_t nplain, const void *aad, size_t naad, const void *iv, size_t niv, const void *cipher_expect, size_t ncipher, const void *tag_expect, size_t ntag) { uint8_t plain_decrypt[64], cipher[64], tag[16]; assert(ncipher == nplain); cf_aes_context ctx; cf_aes_init(&ctx, key, nkey); cf_gcm_encrypt(&cf_aes, &ctx, plain, nplain, aad, naad, iv, niv, cipher, tag, ntag); TEST_CHECK(memcmp(tag, tag_expect, ntag) == 0); TEST_CHECK(memcmp(cipher, cipher_expect, ncipher) == 0); int err = cf_gcm_decrypt(&cf_aes, &ctx, cipher, ncipher, aad, naad, iv, niv, tag, ntag, plain_decrypt); TEST_CHECK(err == 0); TEST_CHECK(memcmp(plain_decrypt, plain, ncipher) == 0); tag[0] ^= 0xff; err = cf_gcm_decrypt(&cf_aes, &ctx, cipher, ncipher, aad, naad, iv, niv, tag, ntag, plain_decrypt); TEST_CHECK(err == 1); }
static size_t aesgcm_decrypt(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, const void *iv, const void *aad, size_t aadlen) { struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; if (inlen < PTLS_AESGCM_TAG_SIZE) return SIZE_MAX; size_t tag_offset = inlen - PTLS_AESGCM_TAG_SIZE; if (cf_gcm_decrypt(&cf_aes, &ctx->aes, input, tag_offset, aad, aadlen, iv, PTLS_AESGCM_IV_SIZE, (uint8_t *)input + tag_offset, PTLS_AESGCM_TAG_SIZE, output) != 0) return SIZE_MAX; return tag_offset; }