9 #include <botan/ghash.h>
10 #include <botan/internal/ct_utils.h>
11 #include <botan/loadstor.h>
12 #include <botan/cpuid.h>
13 #include <botan/exceptn.h>
15 #if defined(BOTAN_HAS_GCM_CLMUL_CPU)
16 #include <botan/internal/clmul_cpu.h>
19 #if defined(BOTAN_HAS_GCM_CLMUL_SSSE3)
20 #include <botan/internal/clmul_ssse3.h>
27 #if defined(BOTAN_HAS_GCM_CLMUL_CPU)
32 #if defined(BOTAN_HAS_GCM_CLMUL_SSSE3)
33 if(CPUID::has_ssse3())
41 const uint8_t input[],
44 #if defined(BOTAN_HAS_GCM_CLMUL_CPU)
51 #if defined(BOTAN_HAS_GCM_CLMUL_SSSE3)
52 if(CPUID::has_ssse3())
60 const uint64_t ALL_BITS = 0xFFFFFFFFFFFFFFFF;
67 for(
size_t b = 0; b != blocks; ++b)
72 uint64_t
Z[2] = { 0, 0 };
74 for(
size_t i = 0; i != 64; ++i)
76 const uint64_t X0MASK = (ALL_BITS + (X[0] >> 63)) ^ ALL_BITS;
77 const uint64_t X1MASK = (ALL_BITS + (X[1] >> 63)) ^ ALL_BITS;
82 Z[0] ^= m_HM[4*i ] & X0MASK;
83 Z[1] ^= m_HM[4*i+1] & X0MASK;
84 Z[0] ^= m_HM[4*i+2] & X1MASK;
85 Z[1] ^= m_HM[4*i+3] & X1MASK;
92 store_be<uint64_t>(x.data(), X[0], X[1]);
97 const uint8_t input[],
size_t length)
106 const size_t full_blocks = length / GCM_BS;
107 const size_t final_bytes = length - (full_blocks * GCM_BS);
111 gcm_multiply(ghash, input, full_blocks);
116 uint8_t last_block[GCM_BS] = { 0 };
117 copy_mem(last_block, input + full_blocks * GCM_BS, final_bytes);
118 gcm_multiply(ghash, last_block, 1);
123 void GHASH::key_schedule(
const uint8_t key[],
size_t length)
125 m_H.assign(key, key+length);
126 m_H_ad.resize(GCM_BS);
133 const uint64_t R = 0xE100000000000000;
138 for(
size_t i = 0; i != 2; ++i)
140 for(
size_t j = 0; j != 64; ++j)
147 m_HM[4*j+2*i+1] = H1;
150 const uint64_t
carry = R * (H1 & 1);
151 H1 = (H1 >> 1) | (H0 << 63);
152 H0 = (H0 >> 1) ^ carry;
156 #if defined(BOTAN_HAS_GCM_CLMUL_CPU)
168 m_nonce.assign(nonce, nonce + len);
174 if(m_ghash.empty() ==
false)
193 m_text_len += length;
198 size_t ad_len,
size_t text_len)
204 uint8_t final_block[GCM_BS];
205 store_be<uint64_t>(final_block, 8*ad_len, 8*text_len);
214 for(
size_t i = 0; i != mac_len; ++i)
215 mac[i] = m_ghash[i] ^ m_nonce[i];
223 BOTAN_ASSERT(m_ghash.size() == 0,
"nonce_hash called during wrong time");
241 m_text_len = m_ad_len = 0;
void start(const uint8_t nonce[], size_t len)
void gcm_multiply_ssse3(uint8_t x[16], const uint64_t HM[256], const uint8_t input_bytes[], size_t blocks)
void add_final_block(secure_vector< uint8_t > &x, size_t ad_len, size_t pt_len)
void zap(std::vector< T, Alloc > &vec)
void carry(int64_t &h0, int64_t &h1)
void gcm_clmul_precompute(const uint8_t H_bytes[16], uint64_t H_pow[4 *2])
void update_associated_data(const uint8_t ad[], size_t len)
void poison(const T *p, size_t n)
void ghash_update(secure_vector< uint8_t > &x, const uint8_t input[], size_t input_len)
static bool has_carryless_multiply()
void update(const uint8_t in[], size_t len)
#define BOTAN_ASSERT(expr, assertion_made)
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
std::vector< T, secure_allocator< T >> secure_vector
secure_vector< uint8_t > nonce_hash(const uint8_t nonce[], size_t nonce_len)
void copy_mem(T *out, const T *in, size_t n)
#define BOTAN_ARG_CHECK(expr, msg)
secure_vector< uint8_t > final()
void gcm_multiply_clmul(uint8_t x[16], const uint64_t H_pow[8], const uint8_t input[], size_t blocks)
void verify_key_set(bool cond) const
void secure_scrub_memory(void *ptr, size_t n)
void unpoison(const T *p, size_t n)
void set_associated_data(const uint8_t ad[], size_t ad_len)
std::string provider() const
void zeroise(std::vector< T, Alloc > &vec)