diff options
author | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
commit | 197dc467dec28a04c3b2f30da7cef122dfbb13e9 (patch) | |
tree | cdbd3ddaec051c72f0a757db461973d90c37b97a /lib/stream/rc4 | |
parent | 62faac373c07cfe10bc8c309e89ebdd30d8e5eaa (diff) |
Shuffle things around. Add NIST X.509 test to build.
Diffstat (limited to 'lib/stream/rc4')
-rw-r--r-- | lib/stream/rc4/info.txt | 1 | ||||
-rw-r--r-- | lib/stream/rc4/rc4.cpp | 109 | ||||
-rw-r--r-- | lib/stream/rc4/rc4.h | 55 |
3 files changed, 165 insertions, 0 deletions
diff --git a/lib/stream/rc4/info.txt b/lib/stream/rc4/info.txt new file mode 100644 index 000000000..f61b8a4cc --- /dev/null +++ b/lib/stream/rc4/info.txt @@ -0,0 +1 @@ +define RC4 20131128 diff --git a/lib/stream/rc4/rc4.cpp b/lib/stream/rc4/rc4.cpp new file mode 100644 index 000000000..df6976235 --- /dev/null +++ b/lib/stream/rc4/rc4.cpp @@ -0,0 +1,109 @@ +/* +* RC4 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/rc4.h> +#include <botan/internal/xor_buf.h> +#include <botan/internal/rounding.h> + +namespace Botan { + +/* +* Combine cipher stream with message +*/ +void RC4::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); + generate(); + } + xor_buf(out, in, &buffer[position], length); + position += length; + } + +/* +* Generate cipher stream +*/ +void RC4::generate() + { + byte SX, SY; + for(size_t i = 0; i != buffer.size(); i += 4) + { + SX = state[X+1]; Y = (Y + SX) % 256; SY = state[Y]; + state[X+1] = SY; state[Y] = SX; + buffer[i] = state[(SX + SY) % 256]; + + SX = state[X+2]; Y = (Y + SX) % 256; SY = state[Y]; + state[X+2] = SY; state[Y] = SX; + buffer[i+1] = state[(SX + SY) % 256]; + + SX = state[X+3]; Y = (Y + SX) % 256; SY = state[Y]; + state[X+3] = SY; state[Y] = SX; + buffer[i+2] = state[(SX + SY) % 256]; + + X = (X + 4) % 256; + SX = state[X]; Y = (Y + SX) % 256; SY = state[Y]; + state[X] = SY; state[Y] = SX; + buffer[i+3] = state[(SX + SY) % 256]; + } + position = 0; + } + +/* +* RC4 Key Schedule +*/ +void RC4::key_schedule(const byte key[], size_t length) + { + state.resize(256); + buffer.resize(round_up<size_t>(DEFAULT_BUFFERSIZE, 4)); + + position = X = Y = 0; + + for(size_t i = 0; i != 256; ++i) + state[i] = static_cast<byte>(i); + + for(size_t i = 0, state_index = 0; i != 256; ++i) + { + state_index = (state_index + key[i % length] + state[i]) % 256; + std::swap(state[i], state[state_index]); + } + + for(size_t i = 0; i <= SKIP; i += buffer.size()) + generate(); + + position += (SKIP % buffer.size()); + } + +/* +* Return the name of this type +*/ +std::string RC4::name() const + { + if(SKIP == 0) return "RC4"; + if(SKIP == 256) return "MARK-4"; + else return "RC4_skip(" + std::to_string(SKIP) + ")"; + } + +/* +* Clear memory of sensitive data +*/ +void RC4::clear() + { + zap(state); + zap(buffer); + position = X = Y = 0; + } + +/* +* RC4 Constructor +*/ +RC4::RC4(size_t s) : SKIP(s) {} + +} diff --git a/lib/stream/rc4/rc4.h b/lib/stream/rc4/rc4.h new file mode 100644 index 000000000..c23f8c853 --- /dev/null +++ b/lib/stream/rc4/rc4.h @@ -0,0 +1,55 @@ +/* +* RC4 +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_RC4_H__ +#define BOTAN_RC4_H__ + +#include <botan/stream_cipher.h> +#include <botan/types.h> + +namespace Botan { + +/** +* RC4 stream cipher +*/ +class BOTAN_DLL RC4 : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], size_t length); + + void clear(); + std::string name() const; + + StreamCipher* clone() const { return new RC4(SKIP); } + + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(1, 256); + } + + /** + * @param skip skip this many initial bytes in the keystream + */ + RC4(size_t skip = 0); + + ~RC4() { clear(); } + private: + void key_schedule(const byte[], size_t); + void generate(); + + const size_t SKIP; + + byte X, Y; + secure_vector<byte> state; + + secure_vector<byte> buffer; + size_t position; + }; + +} + +#endif |