Botan
1.11.15
|
00001 /* 00002 * RC4 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/stream_utils.h> 00009 #include <botan/rc4.h> 00010 00011 namespace Botan { 00012 00013 BOTAN_REGISTER_NAMED_T(StreamCipher, "RC4", RC4, RC4::make); 00014 00015 RC4* RC4::make(const Spec& spec) 00016 { 00017 if(spec.algo_name() == "RC4") 00018 return new RC4(spec.arg_as_integer(0, 0)); 00019 if(spec.algo_name() == "RC4_drop") 00020 return new RC4(768); 00021 return nullptr; 00022 } 00023 00024 /* 00025 * Combine cipher stream with message 00026 */ 00027 void RC4::cipher(const byte in[], byte out[], size_t length) 00028 { 00029 while(length >= buffer.size() - position) 00030 { 00031 xor_buf(out, in, &buffer[position], buffer.size() - position); 00032 length -= (buffer.size() - position); 00033 in += (buffer.size() - position); 00034 out += (buffer.size() - position); 00035 generate(); 00036 } 00037 xor_buf(out, in, &buffer[position], length); 00038 position += length; 00039 } 00040 00041 /* 00042 * Generate cipher stream 00043 */ 00044 void RC4::generate() 00045 { 00046 byte SX, SY; 00047 for(size_t i = 0; i != buffer.size(); i += 4) 00048 { 00049 SX = state[X+1]; Y = (Y + SX) % 256; SY = state[Y]; 00050 state[X+1] = SY; state[Y] = SX; 00051 buffer[i] = state[(SX + SY) % 256]; 00052 00053 SX = state[X+2]; Y = (Y + SX) % 256; SY = state[Y]; 00054 state[X+2] = SY; state[Y] = SX; 00055 buffer[i+1] = state[(SX + SY) % 256]; 00056 00057 SX = state[X+3]; Y = (Y + SX) % 256; SY = state[Y]; 00058 state[X+3] = SY; state[Y] = SX; 00059 buffer[i+2] = state[(SX + SY) % 256]; 00060 00061 X = (X + 4) % 256; 00062 SX = state[X]; Y = (Y + SX) % 256; SY = state[Y]; 00063 state[X] = SY; state[Y] = SX; 00064 buffer[i+3] = state[(SX + SY) % 256]; 00065 } 00066 position = 0; 00067 } 00068 00069 /* 00070 * RC4 Key Schedule 00071 */ 00072 void RC4::key_schedule(const byte key[], size_t length) 00073 { 00074 state.resize(256); 00075 buffer.resize(256); 00076 00077 position = X = Y = 0; 00078 00079 for(size_t i = 0; i != 256; ++i) 00080 state[i] = static_cast<byte>(i); 00081 00082 for(size_t i = 0, state_index = 0; i != 256; ++i) 00083 { 00084 state_index = (state_index + key[i % length] + state[i]) % 256; 00085 std::swap(state[i], state[state_index]); 00086 } 00087 00088 for(size_t i = 0; i <= SKIP; i += buffer.size()) 00089 generate(); 00090 00091 position += (SKIP % buffer.size()); 00092 } 00093 00094 /* 00095 * Return the name of this type 00096 */ 00097 std::string RC4::name() const 00098 { 00099 if(SKIP == 0) return "RC4"; 00100 if(SKIP == 256) return "MARK-4"; 00101 else return "RC4_skip(" + std::to_string(SKIP) + ")"; 00102 } 00103 00104 /* 00105 * Clear memory of sensitive data 00106 */ 00107 void RC4::clear() 00108 { 00109 zap(state); 00110 zap(buffer); 00111 position = X = Y = 0; 00112 } 00113 00114 /* 00115 * RC4 Constructor 00116 */ 00117 RC4::RC4(size_t s) : SKIP(s) {} 00118 00119 }