9 #include <botan/internal/xor_buf.h>    17 void poly_double(
byte tweak[], 
size_t size)
    19    const byte polynomial = (size == 16) ? 0x87 : 0x1B;
    22    for(
size_t i = 0; i != size; ++i)
    24       byte carry2 = (tweak[i] >> 7);
    25       tweak[i] = (tweak[i] << 1) | carry;
    30       tweak[0] ^= polynomial;
    36 size_t xts_parallelism(BlockCipher* cipher)
    38    return std::max<size_t>(cipher->parallel_bytes(),
    39                            2 * cipher->block_size());
    51    if(cipher->block_size() != 8 && cipher->block_size() != 16)
    52       throw std::invalid_argument(
"Bad cipher for XTS: " + cipher->name());
    54    cipher2 = cipher->
clone();
    67    if(cipher->block_size() != 8 && cipher->block_size() != 16)
    68        throw std::invalid_argument(
"Bad cipher for XTS: " + cipher->name());
    70    cipher2 = cipher->
clone();
    82    return (cipher->name() + 
"/XTS");
    93    const size_t blocks_in_tweak = tweak.size() / cipher->block_size();
    98    for(
size_t i = 1; i < blocks_in_tweak; ++i)
   100       tweak.copy(i*cipher->block_size(),
   101                  &tweak[(i-1)*cipher->block_size()],
   102                  cipher->block_size());
   104       poly_double(&tweak[i*cipher->block_size()], cipher->block_size());
   110    size_t key_half = key.
length() / 2;
   112    if(key.
length() % 2 == 1 || !cipher->valid_keylength(key_half))
   115    cipher->set_key(key.
begin(), key_half);
   122 void XTS_Encryption::write(
const byte input[], 
size_t length)
   129 void XTS_Encryption::end_msg()
   134 void XTS_Encryption::buffered_block(
const byte input[], 
size_t length)
   136    const size_t blocks_in_tweak = tweak.size() / cipher->block_size();
   137    size_t blocks = length / cipher->block_size();
   143       size_t to_proc = 
std::min(blocks, blocks_in_tweak);
   144       size_t to_proc_bytes = to_proc * cipher->block_size();
   146       xor_buf(temp, input, tweak, to_proc_bytes);
   148       cipher->encrypt_n(&temp[0], &temp[0], to_proc);
   150       xor_buf(temp, tweak, to_proc_bytes);
   152       send(temp, to_proc_bytes);
   154       tweak.copy(&tweak[(to_proc-1)*cipher->block_size()],
   155                  cipher->block_size());
   156       poly_double(&tweak[0], cipher->block_size());
   158       for(
size_t i = 1; i < blocks_in_tweak; ++i)
   160          tweak.copy(i*cipher->block_size(),
   161                     &tweak[(i-1)*cipher->block_size()],
   162                     cipher->block_size());
   164          poly_double(&tweak[i*cipher->block_size()], cipher->block_size());
   167       input += to_proc * cipher->block_size();
   175 void XTS_Encryption::buffered_final(
const byte input[], 
size_t length)
   177    if(length <= cipher->block_size())
   178       throw Encoding_Error(
"XTS_Encryption: insufficient data to encrypt");
   180    if(length % cipher->block_size() == 0)
   182       buffered_block(input, length);
   187       size_t leftover_blocks =
   188          ((length / cipher->block_size()) - 1) * cipher->block_size();
   190       buffered_block(input, leftover_blocks);
   192       input += leftover_blocks;
   193       length -= leftover_blocks;
   197       xor_buf(temp, tweak, cipher->block_size());
   198       cipher->encrypt(temp);
   199       xor_buf(temp, tweak, cipher->block_size());
   201       poly_double(&tweak[0], cipher->block_size());
   203       for(
size_t i = 0; i != length - cipher->block_size(); ++i)
   204          std::swap(temp[i], temp[i + cipher->block_size()]);
   206       xor_buf(temp, tweak, cipher->block_size());
   207       cipher->encrypt(temp);
   208       xor_buf(temp, tweak, cipher->block_size());
   223    if(cipher->block_size() != 8 && cipher->block_size() != 16)
   224        throw std::invalid_argument(
"Bad cipher for XTS: " + cipher->name());
   226    cipher2 = ciph->
clone();
   239    if(cipher->block_size() != 8 && cipher->block_size() != 16)
   240        throw std::invalid_argument(
"Bad cipher for XTS: " + cipher->name());
   242    cipher2 = ciph->
clone();
   254    return (cipher->name() + 
"/XTS");
   265    const size_t blocks_in_tweak = tweak.size() / cipher->block_size();
   270    for(
size_t i = 1; i < blocks_in_tweak; ++i)
   272       tweak.copy(i*cipher->block_size(),
   273                  &tweak[(i-1)*cipher->block_size()],
   274                  cipher->block_size());
   276       poly_double(&tweak[i*cipher->block_size()], cipher->block_size());
   282    size_t key_half = key.
length() / 2;
   284    if(key.
length() % 2 == 1 || !cipher->valid_keylength(key_half))
   287    cipher->set_key(key.
begin(), key_half);
   294 void XTS_Decryption::write(
const byte input[], 
size_t length)
   302 void XTS_Decryption::end_msg()
   307 void XTS_Decryption::buffered_block(
const byte input[], 
size_t input_length)
   309    const size_t blocks_in_tweak = tweak.size() / cipher->block_size();
   310    size_t blocks = input_length / cipher->block_size();
   316       size_t to_proc = 
std::min(blocks, blocks_in_tweak);
   317       size_t to_proc_bytes = to_proc * cipher->block_size();
   319       xor_buf(temp, input, tweak, to_proc_bytes);
   321       cipher->decrypt_n(&temp[0], &temp[0], to_proc);
   323       xor_buf(temp, tweak, to_proc_bytes);
   325       send(temp, to_proc_bytes);
   327       tweak.copy(&tweak[(to_proc-1)*cipher->block_size()],
   328                  cipher->block_size());
   329       poly_double(&tweak[0], cipher->block_size());
   331       for(
size_t i = 1; i < blocks_in_tweak; ++i)
   333          tweak.copy(i*cipher->block_size(),
   334                     &tweak[(i-1)*cipher->block_size()],
   335                     cipher->block_size());
   337          poly_double(&tweak[i*cipher->block_size()], cipher->block_size());
   340       input += to_proc * cipher->block_size();
   345 void XTS_Decryption::buffered_final(
const byte input[], 
size_t length)
   347    if(length <= cipher->block_size())
   348       throw Decoding_Error(
"XTS_Decryption: insufficient data to decrypt");
   350    if(length % cipher->block_size() == 0)
   352       buffered_block(input, length);
   356       size_t leftover_blocks =
   357          ((length / cipher->block_size()) - 1) * cipher->block_size();
   359       buffered_block(input, leftover_blocks);
   361       input += leftover_blocks;
   362       length -= leftover_blocks;
   367       poly_double(&tweak_copy[0], cipher->block_size());
   369       xor_buf(temp, tweak_copy, cipher->block_size());
   370       cipher->decrypt(temp);
   371       xor_buf(temp, tweak_copy, cipher->block_size());
   373       for(
size_t i = 0; i != length - cipher->block_size(); ++i)
   374          std::swap(temp[i], temp[i + cipher->block_size()]);
   376       xor_buf(temp, tweak, cipher->block_size());
   377       cipher->decrypt(temp);
   378       xor_buf(temp, tweak, cipher->block_size());
 
virtual BlockCipher * clone() const =0
XTS_Encryption(BlockCipher *ciph)
void write(const byte in[], size_t length)
const byte * begin() const
void send(const byte in[], size_t length)
void encrypt(const byte in[], byte out[]) const
void set_key(const SymmetricKey &key)
void set_iv(const InitializationVector &iv)
bool valid_iv_length(size_t iv_len) const
void set_iv(const InitializationVector &iv)
XTS_Decryption(BlockCipher *ciph)
size_t buffered_block_size() const
bool valid_iv_length(size_t iv_len) const
void swap(Botan::MemoryRegion< T > &x, Botan::MemoryRegion< T > &y)
void xor_buf(byte out[], const byte in[], size_t length)
void set_key(const SymmetricKey &key)
void set_key(const SymmetricKey &key)