10#include <botan/block_cipher.h>
11#include <botan/internal/poly_dbl.h>
12#include <botan/internal/bit_ops.h>
20 explicit L_computer(
const BlockCipher& cipher) :
21 m_BS(cipher.block_size()),
22 m_max_blocks(cipher.parallel_bytes() / m_BS)
24 m_L_star.resize(m_BS);
25 cipher.encrypt(m_L_star);
26 m_L_dollar = poly_double(star());
38 m_L.push_back(poly_double(dollar()));
41 m_L.push_back(poly_double(m_L.back()));
43 m_offset_buf.resize(m_BS * m_max_blocks);
46 void init(
const secure_vector<uint8_t>& offset)
51 bool initialized()
const {
return m_offset.empty() ==
false; }
53 const secure_vector<uint8_t>& star()
const {
return m_L_star; }
54 const secure_vector<uint8_t>& dollar()
const {
return m_L_dollar; }
55 const secure_vector<uint8_t>& offset()
const {
return m_offset; }
57 const secure_vector<uint8_t>& get(
size_t i)
const
59 while(m_L.size() <= i)
60 m_L.push_back(poly_double(m_L.back()));
66 compute_offsets(
size_t block_index,
size_t blocks)
70 uint8_t* offsets = m_offset_buf.data();
72 if(block_index % 4 == 0)
74 const secure_vector<uint8_t>& L0 = get(0);
75 const secure_vector<uint8_t>& L1 = get(1);
83 const size_t ntz4 =
var_ctz32(
static_cast<uint32_t
>(block_index));
85 xor_buf(offsets, m_offset.data(), L0.data(), m_BS);
88 xor_buf(offsets, offsets - m_BS, L1.data(), m_BS);
91 xor_buf(m_offset.data(), L1.data(), m_BS);
92 copy_mem(offsets, m_offset.data(), m_BS);
95 xor_buf(m_offset.data(), get(ntz4).data(), m_BS);
96 copy_mem(offsets, m_offset.data(), m_BS);
103 for(
size_t i = 0; i != blocks; ++i)
105 const size_t ntz =
var_ctz32(
static_cast<uint32_t
>(block_index + i + 1));
106 xor_buf(m_offset.data(), get(ntz).data(), m_BS);
107 copy_mem(offsets, m_offset.data(), m_BS);
111 return m_offset_buf.data();
115 secure_vector<uint8_t> poly_double(
const secure_vector<uint8_t>& in)
const
117 secure_vector<uint8_t> out(in.size());
122 const size_t m_BS, m_max_blocks;
123 secure_vector<uint8_t> m_L_dollar, m_L_star;
124 secure_vector<uint8_t> m_offset;
125 mutable std::vector<secure_vector<uint8_t>> m_L;
126 secure_vector<uint8_t> m_offset_buf;
134secure_vector<uint8_t> ocb_hash(
const L_computer& L,
135 const BlockCipher& cipher,
136 const uint8_t ad[],
size_t ad_len)
138 const size_t BS = cipher.block_size();
139 secure_vector<uint8_t> sum(BS);
140 secure_vector<uint8_t> offset(BS);
142 secure_vector<uint8_t> buf(BS);
144 const size_t ad_blocks = (ad_len / BS);
145 const size_t ad_remainder = (ad_len % BS);
147 for(
size_t i = 0; i != ad_blocks; ++i)
150 offset ^= L.get(
var_ctz32(
static_cast<uint32_t
>(i+1)));
152 xor_buf(buf.data(), &ad[BS*i], BS);
161 xor_buf(buf.data(), &ad[BS*ad_blocks], ad_remainder);
162 buf[ad_remainder] ^= 0x80;
174 m_checksum(m_cipher->parallel_bytes()),
175 m_ad_hash(m_cipher->block_size()),
176 m_tag_size(tag_size),
177 m_block_size(m_cipher->block_size()),
178 m_par_blocks(m_cipher->parallel_bytes() / m_block_size)
188 "Invalid block size for OCB");
191 m_tag_size >= 8 && m_tag_size <= BS &&
193 "Invalid OCB tag length");
210 m_last_nonce.clear();
239void OCB_Mode::key_schedule(
const uint8_t key[],
size_t length)
252OCB_Mode::update_nonce(
const uint8_t nonce[],
size_t nonce_len)
256 BOTAN_ASSERT(BS == 16 || BS == 24 || BS == 32 || BS == 64,
257 "OCB block size is supported");
259 const size_t MASKLEN = (BS == 16 ? 6 : ((BS == 24) ? 7 : 8));
261 const uint8_t BOTTOM_MASK =
262 static_cast<uint8_t
>((
static_cast<uint16_t
>(1) << MASKLEN) - 1);
264 m_nonce_buf.resize(BS);
265 clear_mem(&m_nonce_buf[0], m_nonce_buf.size());
267 copy_mem(&m_nonce_buf[BS - nonce_len], nonce, nonce_len);
268 m_nonce_buf[0] =
static_cast<uint8_t
>(((
tag_size()*8) % (BS*8)) << (BS <= 16 ? 1 : 0));
270 m_nonce_buf[BS - nonce_len - 1] ^= 1;
272 const uint8_t bottom = m_nonce_buf[BS-1] & BOTTOM_MASK;
273 m_nonce_buf[BS-1] &= ~BOTTOM_MASK;
275 const bool need_new_stretch = (m_last_nonce != m_nonce_buf);
279 m_last_nonce = m_nonce_buf;
305 for(
size_t i = 0; i != BS / 2; ++i)
306 m_nonce_buf.push_back(m_nonce_buf[i] ^ m_nonce_buf[i+1]);
310 for(
size_t i = 0; i != 16; ++i)
311 m_nonce_buf.push_back(m_nonce_buf[i] ^ m_nonce_buf[i+5]);
315 for(
size_t i = 0; i != BS; ++i)
316 m_nonce_buf.push_back(m_nonce_buf[i] ^ (m_nonce_buf[i] << 1) ^ (m_nonce_buf[i+1] >> 7));
320 for(
size_t i = 0; i != BS / 2; ++i)
321 m_nonce_buf.push_back(m_nonce_buf[i] ^ m_nonce_buf[i+22]);
324 m_stretch = m_nonce_buf;
328 const size_t shift_bytes = bottom / 8;
329 const size_t shift_bits = bottom % 8;
331 BOTAN_ASSERT(m_stretch.size() >= BS + shift_bytes + 1,
"Size ok");
334 for(
size_t i = 0; i != BS; ++i)
336 m_offset[i] = (m_stretch[i+shift_bytes] << shift_bits);
337 m_offset[i] |= (m_stretch[i+shift_bytes+1] >> (8-shift_bits));
343void OCB_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
346 throw Invalid_IV_Length(
name(), nonce_len);
350 m_L->init(update_nonce(nonce, nonce_len));
355void OCB_Encryption::encrypt(uint8_t buffer[],
size_t blocks)
364 const size_t proc_blocks = std::min(blocks,
par_blocks());
365 const size_t proc_bytes = proc_blocks * BS;
371 m_cipher->encrypt_n_xex(buffer, offsets, proc_blocks);
373 buffer += proc_bytes;
374 blocks -= proc_blocks;
392 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
393 const size_t sz = buffer.size() - offset;
394 uint8_t* buf = buffer.data() + offset;
400 const size_t final_full_blocks = sz / BS;
401 const size_t remainder_bytes = sz - (final_full_blocks * BS);
403 encrypt(buf, final_full_blocks);
408 BOTAN_ASSERT(remainder_bytes < BS,
"Only a partial block left");
409 uint8_t* remainder = &buf[sz - remainder_bytes];
419 xor_buf(remainder, pad.data(), remainder_bytes);
430 for(
size_t i = 0; i !=
m_checksum.size(); i += BS)
435 xor_buf(mac.data(),
m_L->dollar().data(), BS);
439 buffer += std::make_pair(mac.data(),
tag_size());
445void OCB_Decryption::decrypt(uint8_t buffer[],
size_t blocks)
454 const size_t proc_blocks = std::min(blocks,
par_blocks());
455 const size_t proc_bytes = proc_blocks * BS;
459 m_cipher->decrypt_n_xex(buffer, offsets, proc_blocks);
463 buffer += proc_bytes;
464 blocks -= proc_blocks;
482 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
483 const size_t sz = buffer.size() - offset;
484 uint8_t* buf = buffer.data() + offset;
488 const size_t remaining = sz -
tag_size();
494 const size_t final_full_blocks = remaining / BS;
495 const size_t final_bytes = remaining - (final_full_blocks * BS);
497 decrypt(buf, final_full_blocks);
498 mac ^=
m_L->offset();
502 BOTAN_ASSERT(final_bytes < BS,
"Only a partial block left");
504 uint8_t* remainder = &buf[remaining - final_bytes];
509 xor_buf(remainder, pad.data(), final_bytes);
521 for(
size_t i = 0; i !=
m_checksum.size(); i += BS)
526 mac ^=
m_L->dollar();
535 const uint8_t* included_tag = &buf[remaining];
541 buffer.resize(remaining + offset);
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_ASSERT(expr, assertion_made)
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
size_t process(uint8_t buf[], size_t size) override
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
size_t process(uint8_t buf[], size_t size) override
size_t block_size() const
void set_associated_data(const uint8_t ad[], size_t ad_len) override
size_t par_blocks() const
secure_vector< uint8_t > m_checksum
size_t tag_size() const override
std::string name() const override
std::unique_ptr< BlockCipher > m_cipher
bool valid_nonce_length(size_t) const override
secure_vector< uint8_t > m_ad_hash
size_t update_granularity() const override
OCB_Mode(BlockCipher *cipher, size_t tag_size)
Key_Length_Specification key_spec() const override
std::unique_ptr< L_computer > m_L
void verify_key_set(bool cond) const
int(* final)(unsigned char *, CTX *)
void zeroise(std::vector< T, Alloc > &vec)
void copy_mem(T *out, const T *in, size_t n)
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
size_t var_ctz32(uint32_t n)
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
void poly_double_n(uint8_t out[], const uint8_t in[], size_t n)
std::vector< T, secure_allocator< T > > secure_vector
void clear_mem(T *ptr, size_t n)