10#include <botan/block_cipher.h>
11#include <botan/cmac.h>
12#include <botan/internal/poly_dbl.h>
18 m_name(cipher->
name() +
"/SIV"),
19 m_ctr(new
CTR_BE(cipher->clone(), 8)),
20 m_mac(new
CMAC(cipher)),
21 m_bs(cipher->block_size())
70 return m_mac->key_spec().multiple(2);
73void SIV_Mode::key_schedule(
const uint8_t key[],
size_t length)
75 const size_t keylen = length / 2;
76 m_mac->set_key(key, keylen);
77 m_ctr->set_key(key + keylen, keylen);
92 if(n >= m_ad_macs.size())
93 m_ad_macs.resize(n+1);
95 m_ad_macs[n] = m_mac->process(ad, length);
98void SIV_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
104 m_nonce = m_mac->process(nonce, nonce_len);
114 m_msg_buf.insert(m_msg_buf.end(), buf, buf + sz);
120 const std::vector<uint8_t> zeros(
block_size());
124 for(
size_t i = 0; i != m_ad_macs.size(); ++i)
139 xor_buf(V.data(), text, text_len);
141 return m_mac->process(V);
148 return m_mac->final();
161 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
163 buffer.insert(buffer.begin() + offset,
msg_buf().begin(),
msg_buf().end());
168 buffer.insert(buffer.begin() + offset, V.begin(), V.end());
170 if(buffer.size() != offset + V.size())
173 ctr().
cipher1(&buffer[offset + V.size()], buffer.size() - offset - V.size());
179 BOTAN_ASSERT(buffer.size() >= offset,
"Offset is sane");
183 buffer.insert(buffer.begin() + offset,
msg_buf().begin(),
msg_buf().end());
187 const size_t sz = buffer.size() - offset;
194 if(buffer.size() != offset + V.size())
198 ctr().
cipher(buffer.data() + offset + V.size(),
199 buffer.data() + offset,
200 buffer.size() - offset - V.size());
208 buffer.resize(buffer.size() -
tag_size());
#define BOTAN_ASSERT(expr, assertion_made)
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
void set_associated_data_n(size_t n, const uint8_t ad[], size_t ad_len) override
SIV_Mode(BlockCipher *cipher)
size_t block_size() const
std::string name() const override
void set_ctr_iv(secure_vector< uint8_t > V)
Key_Length_Specification key_spec() const override
secure_vector< uint8_t > S2V(const uint8_t text[], size_t text_len)
size_t update_granularity() const override
size_t tag_size() const override
size_t process(uint8_t buf[], size_t size) override
size_t maximum_associated_data_inputs() const override
secure_vector< uint8_t > & msg_buf()
bool valid_nonce_length(size_t) const override
void cipher1(uint8_t buf[], size_t len)
virtual void cipher(const uint8_t in[], uint8_t out[], size_t len)=0
virtual void set_iv(const uint8_t iv[], size_t iv_len)=0
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
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