/** * aes_gcm_ad - GCM-AD_K(IV, C, A, T) */ int aes_gcm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len, const aes_uchar *crypt, size_t crypt_len, const aes_uchar *aad, size_t aad_len, const aes_uchar *tag, aes_uchar *plain) { aes_uchar H[AES_BLOCK_SIZE]; aes_uchar J0[AES_BLOCK_SIZE]; aes_uchar S[16], T[16]; void *aes; aes = aes_gcm_init_hash_subkey(key, key_len, H); if (aes == NULL) return -1; aes_gcm_prepare_j0(iv, iv_len, H, J0); /* P = GCTR_K(inc_32(J_0), C) */ aes_gcm_gctr(aes, J0, crypt, crypt_len, plain); aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S); /* T' = MSB_t(GCTR_K(J_0, S)) */ aes_gctr(aes, J0, S, sizeof(S), T); aes_encrypt_deinit(aes); if (memcmp(tag, T, 16) != 0) { aes_printf(MSG_EXCESSIVE, "GCM: Tag mismatch"); return -1; } return 0; }
/** * aes_gcm_ae - GCM-AE_K(IV, P, A) */ int aes_gcm_ae( void *aes, // DHD20150614 const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, const u8 *plain, size_t plain_len, const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag) { u8 H[AES_BLOCK_SIZE]; u8 J0[AES_BLOCK_SIZE]; u8 S[16]; // void *aes; // aes = aes_gcm_init_hash_subkey( aes, // DHD20150614 key, key_len, H); // if (aes == NULL) // return -1; aes_gcm_prepare_j0(iv, iv_len, H, J0); /* C = GCTR_K(inc_32(J_0), P) */ aes_gcm_gctr(aes, J0, plain, plain_len, crypt); aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S); /* T = MSB_t(GCTR_K(J_0, S)) */ aes_gctr(aes, J0, S, sizeof(S), tag); /* Return (C, T) */ aes_encrypt_deinit(aes); return 0; }
/** * aes_gcm_ae - GCM-AE_K(IV, P, A) */ int aes_gcm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len, const aes_uchar *plain, size_t plain_len, const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *tag) { aes_uchar H[AES_BLOCK_SIZE]; aes_uchar J0[AES_BLOCK_SIZE]; aes_uchar S[16]; void *aes; aes = aes_gcm_init_hash_subkey(key, key_len, H); if (aes == NULL) return -1; aes_gcm_prepare_j0(iv, iv_len, H, J0); /* C = GCTR_K(inc_32(J_0), P) */ aes_gcm_gctr(aes, J0, plain, plain_len, crypt); aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S); /* T = MSB_t(GCTR_K(J_0, S)) */ aes_gctr(aes, J0, S, sizeof(S), tag); /* Return (C, T) */ aes_encrypt_deinit(aes); return 0; }
/** * aes_gcm_ad - GCM-AD_K(IV, C, A, T) */ int aes_gcm_ad( void *aes, // DHD20150614 const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, const u8 *crypt, size_t crypt_len, const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain) { u8 H[AES_BLOCK_SIZE]; u8 J0[AES_BLOCK_SIZE]; u8 S[16], T[16]; // void *aes; // aes = aes_gcm_init_hash_subkey( aes, // DHD20150614 key, key_len, H); // if (aes == NULL) // return -1; aes_gcm_prepare_j0(iv, iv_len, H, J0); /* P = GCTR_K(inc_32(J_0), C) */ aes_gcm_gctr(aes, J0, crypt, crypt_len, plain); aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S); /* T' = MSB_t(GCTR_K(J_0, S)) */ aes_gctr(aes, J0, S, sizeof(S), T); aes_encrypt_deinit(aes); if (os_memcmp_const(tag, T, 16) != 0) { /* printf("GCM: Tag mismatch\n"); */ return -1; } return 0; }