static int myaes_gcm_decrypt(void *_ctx, const void *nonce, size_t nonce_size, const void *auth, size_t auth_size, size_t tag_size, const void *encr, size_t encr_size, void *plain, size_t plain_size) { uint8_t tag[16]; struct myaes_gcm_ctx *ctx = _ctx; if (encr_size < tag_size) return GNUTLS_E_DECRYPTION_FAILED; aead_used++; gcm_aes128_set_iv(&ctx->aes, nonce_size, nonce); gcm_aes128_update(&ctx->aes, auth_size, auth); encr_size -= tag_size; gcm_aes128_decrypt(&ctx->aes, encr_size, plain, encr); gcm_aes128_digest(&ctx->aes, tag_size, tag); if (gnutls_memcmp(((uint8_t*)encr)+encr_size, tag, tag_size) != 0) return GNUTLS_E_DECRYPTION_FAILED; return 0; }
static int myaes_gcm_encrypt(void *_ctx, const void *nonce, size_t nonce_size, const void *auth, size_t auth_size, size_t tag_size, const void *plain, size_t plain_size, void *encr, size_t encr_size) { /* proper AEAD cipher */ struct myaes_gcm_ctx *ctx = _ctx; if (encr_size < plain_size + tag_size) return GNUTLS_E_SHORT_MEMORY_BUFFER; aead_used++; gcm_aes128_set_iv(&ctx->aes, nonce_size, nonce); gcm_aes128_update(&ctx->aes, auth_size, auth); gcm_aes128_encrypt(&ctx->aes, plain_size, encr, plain); gcm_aes128_digest(&ctx->aes, tag_size, ((uint8_t*)encr) + plain_size); return 0; }
static void test_gcm_hash (const struct tstring *msg, const struct tstring *ref) { struct gcm_aes128_ctx ctx; const uint8_t z16[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; uint8_t digest[16]; ASSERT (ref->length == sizeof(digest)); gcm_aes128_set_key (&ctx, z16); gcm_aes128_set_iv (&ctx, 16, z16); gcm_aes128_update (&ctx, msg->length, msg->data); gcm_aes128_digest (&ctx, sizeof(digest), digest); if (!MEMEQ (ref->length, ref->data, digest)) { fprintf (stderr, "gcm_hash failed, msg: %s\nOutput: ", msg->data); print_hex (16, digest); fprintf(stderr, "Expected:"); tstring_print_hex(ref); fprintf(stderr, "\n"); FAIL(); } }