diff options
author | lloyd <[email protected]> | 2014-01-10 03:41:59 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-01-10 03:41:59 +0000 |
commit | 6894dca64c04936d07048c0e8cbf7e25858548c3 (patch) | |
tree | 5d572bfde9fe667dab14e3f04b5285a85d8acd95 /src/lib/stream/ctr/ctr.cpp | |
parent | 9efa3be92442afb3d0b69890a36c7f122df18eda (diff) |
Move lib into src
Diffstat (limited to 'src/lib/stream/ctr/ctr.cpp')
-rw-r--r-- | src/lib/stream/ctr/ctr.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp new file mode 100644 index 000000000..87ec86c65 --- /dev/null +++ b/src/lib/stream/ctr/ctr.cpp @@ -0,0 +1,134 @@ +/* +* Counter mode +* (C) 1999-2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/ctr.h> +#include <botan/internal/xor_buf.h> + +namespace Botan { + +/* +* CTR-BE Constructor +*/ + +CTR_BE::CTR_BE(BlockCipher* ciph) : + permutation(ciph), + counter(256 * permutation->block_size()), + buffer(counter.size()), + position(0) + { + } + +/* +* CTR_BE Destructor +*/ +CTR_BE::~CTR_BE() + { + delete permutation; + } + +/* +* Zeroize +*/ +void CTR_BE::clear() + { + permutation->clear(); + zeroise(buffer); + zeroise(counter); + position = 0; + } + +/* +* Set the key +*/ +void CTR_BE::key_schedule(const byte key[], size_t key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(nullptr, 0); + } + +/* +* Return the name of this type +*/ +std::string CTR_BE::name() const + { + return ("CTR-BE(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void CTR_BE::cipher(const byte in[], byte out[], size_t length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, &buffer[position], buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + increment_counter(); + } + xor_buf(out, in, &buffer[position], length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void CTR_BE::set_iv(const byte iv[], size_t iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + const size_t bs = permutation->block_size(); + + zeroise(counter); + + buffer_insert(counter, 0, iv, iv_len); + + /* + * Set counter blocks to IV, IV + 1, ... IV + 255 + */ + for(size_t i = 1; i != 256; ++i) + { + buffer_insert(counter, i*bs, &counter[(i-1)*bs], bs); + + for(size_t j = 0; j != bs; ++j) + if(++counter[i*bs + (bs - 1 - j)]) + break; + } + + permutation->encrypt_n(&counter[0], &buffer[0], 256); + position = 0; + } + +/* +* Increment the counter and update the buffer +*/ +void CTR_BE::increment_counter() + { + const size_t bs = permutation->block_size(); + + /* + * Each counter value always needs to be incremented by 256, + * so we don't touch the lowest byte and instead treat it as + * an increment of one starting with the next byte. + */ + for(size_t i = 0; i != 256; ++i) + { + for(size_t j = 1; j != bs; ++j) + if(++counter[i*bs + (bs - 1 - j)]) + break; + } + + permutation->encrypt_n(&counter[0], &buffer[0], 256); + + position = 0; + } + +} |