aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stream/rc4
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-01-01 21:20:55 +0000
committerlloyd <[email protected]>2014-01-01 21:20:55 +0000
commit197dc467dec28a04c3b2f30da7cef122dfbb13e9 (patch)
treecdbd3ddaec051c72f0a757db461973d90c37b97a /lib/stream/rc4
parent62faac373c07cfe10bc8c309e89ebdd30d8e5eaa (diff)
Shuffle things around. Add NIST X.509 test to build.
Diffstat (limited to 'lib/stream/rc4')
-rw-r--r--lib/stream/rc4/info.txt1
-rw-r--r--lib/stream/rc4/rc4.cpp109
-rw-r--r--lib/stream/rc4/rc4.h55
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