10 #include <botan/cmac.h>
11 #include <botan/internal/bit_ops.h>
19 explicit L_computer(
const BlockCipher& cipher)
21 m_L_star.resize(cipher.block_size());
22 cipher.encrypt(m_L_star);
23 m_L_dollar = poly_double(star());
24 m_L.push_back(poly_double(dollar()));
27 const secure_vector<uint8_t>& star()
const {
return m_L_star; }
29 const secure_vector<uint8_t>& dollar()
const {
return m_L_dollar; }
31 const secure_vector<uint8_t>& operator()(
size_t i)
const {
return get(i); }
33 const secure_vector<uint8_t>& compute_offsets(secure_vector<uint8_t>& offset,
37 m_offset_buf.resize(blocks * 16);
39 for(
size_t i = 0; i != blocks; ++i)
41 offset ^=
get(
ctz(block_index + 1 + i));
42 copy_mem(&m_offset_buf[16*i], offset.data(), 16);
49 const secure_vector<uint8_t>&
get(
size_t i)
const
51 while(m_L.size() <= i)
52 m_L.push_back(poly_double(m_L.back()));
57 secure_vector<uint8_t> poly_double(
const secure_vector<uint8_t>& in)
const
62 secure_vector<uint8_t> m_L_dollar, m_L_star;
63 mutable std::vector<secure_vector<uint8_t>> m_L;
64 mutable secure_vector<uint8_t> m_offset_buf;
72 secure_vector<uint8_t> ocb_hash(
const L_computer& L,
73 const BlockCipher& cipher,
74 const uint8_t ad[],
size_t ad_len)
76 secure_vector<uint8_t> sum(16);
77 secure_vector<uint8_t> offset(16);
79 secure_vector<uint8_t> buf(16);
81 const size_t ad_blocks = (ad_len / 16);
82 const size_t ad_remainder = (ad_len % 16);
84 for(
size_t i = 0; i != ad_blocks; ++i)
87 offset ^= L(
ctz(i+1));
90 xor_buf(buf.data(), &ad[16*i], 16);
102 xor_buf(buf.data(), &ad[16*ad_blocks], ad_remainder);
103 buf[ad_len % 16] ^= 0x80;
117 m_checksum(m_cipher->parallel_bytes()),
125 if(m_tag_size % 4 != 0 || m_tag_size < 8 || m_tag_size > 16)
144 m_last_nonce.clear();
150 return (length > 0 && length < m_cipher->block_size());
168 void OCB_Mode::key_schedule(
const uint8_t key[],
size_t length)
181 OCB_Mode::update_nonce(
const uint8_t nonce[],
size_t nonce_len)
183 BOTAN_ASSERT(nonce_len < 16,
"OCB nonce is less than cipher block size");
187 copy_mem(&nonce_buf[16 - nonce_len], nonce, nonce_len);
188 nonce_buf[0] = ((
tag_size() * 8) % 128) << 1;
189 nonce_buf[16 - nonce_len - 1] = 1;
191 const uint8_t bottom = nonce_buf[16-1] & 0x3F;
192 nonce_buf[16-1] &= 0xC0;
194 const bool need_new_stretch = (m_last_nonce != nonce_buf);
198 m_last_nonce = nonce_buf;
202 for(
size_t i = 0; i != 16 / 2; ++i)
203 nonce_buf.push_back(nonce_buf[i] ^ nonce_buf[i+1]);
205 m_stretch = nonce_buf;
210 const size_t shift_bytes = bottom / 8;
211 const size_t shift_bits = bottom % 8;
213 secure_vector<uint8_t> offset(16);
214 for(
size_t i = 0; i != 16; ++i)
216 offset[i] = (m_stretch[i+shift_bytes] << shift_bits);
217 offset[i] |= (m_stretch[i+shift_bytes+1] >> (8-shift_bits));
223 void OCB_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
226 throw Invalid_IV_Length(
name(), nonce_len);
230 m_offset = update_nonce(nonce, nonce_len);
235 void OCB_Encryption::encrypt(uint8_t buffer[],
size_t blocks)
237 const size_t par_blocks =
m_checksum.size() / 16;
241 const size_t proc_blocks =
std::min(blocks, par_blocks);
242 const size_t proc_bytes = proc_blocks * 16;
248 xor_buf(buffer, offsets.data(), proc_bytes);
249 m_cipher->encrypt_n(buffer, buffer, proc_blocks);
250 xor_buf(buffer, offsets.data(), proc_bytes);
252 buffer += proc_bytes;
253 blocks -= proc_blocks;
261 encrypt(buf, sz / 16);
267 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
268 const size_t sz = buffer.size() - offset;
269 uint8_t* buf = buffer.data() + offset;
273 const size_t final_full_blocks = sz / 16;
274 const size_t remainder_bytes = sz - (final_full_blocks * 16);
276 encrypt(buf, final_full_blocks);
280 BOTAN_ASSERT(remainder_bytes < 16,
"Only a partial block left");
281 uint8_t* remainder = &buf[sz - remainder_bytes];
290 xor_buf(remainder, zeros.data(), remainder_bytes);
297 for(
size_t i = 0; i !=
m_checksum.size(); ++i)
298 checksum[i % checksum.size()] ^=
m_checksum[i];
303 mac ^=
m_L->dollar();
309 buffer += std::make_pair(mac.data(),
tag_size());
316 void OCB_Decryption::decrypt(uint8_t buffer[],
size_t blocks)
318 const size_t par_bytes =
m_cipher->parallel_bytes();
320 BOTAN_ASSERT(par_bytes % 16 == 0,
"Cipher is parallel in full blocks");
322 const size_t par_blocks = par_bytes / 16;
326 const size_t proc_blocks =
std::min(blocks, par_blocks);
327 const size_t proc_bytes = proc_blocks * 16;
331 xor_buf(buffer, offsets.data(), proc_bytes);
332 m_cipher->decrypt_n(buffer, buffer, proc_blocks);
333 xor_buf(buffer, offsets.data(), proc_bytes);
337 buffer += proc_bytes;
338 blocks -= proc_blocks;
346 decrypt(buf, sz / 16);
352 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
353 const size_t sz = buffer.size() - offset;
354 uint8_t* buf = buffer.data() + offset;
358 const size_t remaining = sz -
tag_size();
362 const size_t final_full_blocks = remaining / 16;
363 const size_t final_bytes = remaining - (final_full_blocks * 16);
365 decrypt(buf, final_full_blocks);
369 BOTAN_ASSERT(final_bytes < 16,
"Only a partial block left");
371 uint8_t* remainder = &buf[remaining - final_bytes];
378 xor_buf(remainder, pad.data(), final_bytes);
388 for(
size_t i = 0; i !=
m_checksum.size(); ++i)
389 checksum[i % checksum.size()] ^=
m_checksum[i];
394 mac ^=
m_L->dollar();
406 const uint8_t* included_tag = &buf[remaining];
412 buffer.resize(remaining + offset);
void xor_buf(T out[], const T in[], size_t length)
std::unique_ptr< BlockCipher > m_cipher
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
bool same_mem(const T *p1, const T *p2, size_t n)
bool valid_nonce_length(size_t) const override
void set_associated_data(const uint8_t ad[], size_t ad_len) override
size_t tag_size() const override
#define BOTAN_ASSERT(expr, assertion_made)
std::vector< T, secure_allocator< T >> secure_vector
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
size_t update_granularity() const override
void copy_mem(T *out, const T *in, size_t n)
std::unique_ptr< L_computer > m_L
static secure_vector< uint8_t > poly_double(const secure_vector< uint8_t > &in)
secure_vector< uint8_t > m_ad_hash
OCB_Mode(BlockCipher *cipher, size_t tag_size)
secure_vector< uint8_t > m_checksum
size_t process(uint8_t buf[], size_t size) override
std::string name() const override
secure_vector< uint8_t > m_offset
size_t process(uint8_t buf[], size_t size) override
Key_Length_Specification key_spec() const override
void zeroise(std::vector< T, Alloc > &vec)