static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len, const u8 *crypt, size_t crypt_len, u8 *S) { u8 len_buf[16]; /* * u = 128 * ceil[len(C)/128] - len(C) * v = 128 * ceil[len(A)/128] - len(A) * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) * (i.e., zero padded to block size A || C and lengths of each in bits) */ ghash_start(S); ghash(H, aad, aad_len, S); ghash(H, crypt, crypt_len, S); // AIDEN - Used to be: WPA_PUT_BE64(len_buf, aad_len * 8); WPA_PUT_BE32(len_buf, 0); WPA_PUT_BE32(len_buf + 4, aad_len * 8); // AIDEN - Used to be: WPA_PUT_BE64(len_buf + 8, crypt_len * 8); WPA_PUT_BE32(len_buf + 8, 0); WPA_PUT_BE32(len_buf + 12, crypt_len * 8); ghash(H, len_buf, sizeof(len_buf), S); /* wpa_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16); */ }
static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0) { u8 len_buf[16]; #ifndef OT_AESGCM_AES128_IV12_ONLY // DHD20150614 if (iv_len == 12) { #endif // DHD20150614 /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ os_memcpy(J0, iv, iv_len); os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); J0[AES_BLOCK_SIZE - 1] = 0x01; #ifndef OT_AESGCM_AES128_IV12_ONLY // DHD20150614 } else { /* * s = 128 * ceil(len(IV)/128) - len(IV) * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) */ ghash_start(J0); ghash(H, iv, iv_len, J0); // AIDEN - Used to be: WPA_PUT_BE64(len_buf, 0); WPA_PUT_BE32(len_buf, 0); WPA_PUT_BE32(len_buf + 4, 0); // AIDEN - Used to be: WPA_PUT_BE64(len_buf + 8, iv_len * 8); WPA_PUT_BE32(len_buf + 8, 0); WPA_PUT_BE32(len_buf + 12, iv_len * 8); ghash(H, len_buf, sizeof(len_buf), J0); } #endif // DHD20150614 }
static void aes_gcm_ghash(const aes_uchar *H, const aes_uchar *aad, size_t aad_len, const aes_uchar *crypt, size_t crypt_len, aes_uchar *S) { aes_uchar len_buf[16]; /* * u = 128 * ceil[len(C)/128] - len(C) * v = 128 * ceil[len(A)/128] - len(A) * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) * (i.e., zero padded to block size A || C and lengths of each in bits) */ ghash_start(S); ghash(H, aad, aad_len, S); ghash(H, crypt, crypt_len, S); AES_PUT_BE64(len_buf, aad_len * 8); AES_PUT_BE64(len_buf + 8, crypt_len * 8); ghash(H, len_buf, sizeof(len_buf), S); aes_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16); }
static void aes_gcm_prepare_j0(const aes_uchar *iv, size_t iv_len, const aes_uchar *H, aes_uchar *J0) { aes_uchar len_buf[16]; if (iv_len == 12) { /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ memcpy(J0, iv, iv_len); memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); J0[AES_BLOCK_SIZE - 1] = 0x01; } else { /* * s = 128 * ceil(len(IV)/128) - len(IV) * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) */ ghash_start(J0); ghash(H, iv, iv_len, J0); AES_PUT_BE64(len_buf, 0); AES_PUT_BE64(len_buf + 8, iv_len * 8); ghash(H, len_buf, sizeof(len_buf), J0); } }