00001
00002
00003 #include "pch.h"
00004 #include "rc2.h"
00005 #include "misc.h"
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009 void RC2::Base::UncheckedSetKey(CipherDir direction, const byte *key, unsigned int keyLen, unsigned int effectiveLen)
00010 {
00011 AssertValidKeyLength(keyLen);
00012
00013 static const unsigned char PITABLE[256] = {
00014 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
00015 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
00016 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
00017 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
00018 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
00019 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
00020 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
00021 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
00022 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
00023 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
00024 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
00025 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
00026 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
00027 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
00028 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
00029 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173};
00030
00031 SecByteBlock L(128);
00032 memcpy(L, key, keyLen);
00033
00034 int i;
00035 for (i=keyLen; i<128; i++)
00036 L[i] = PITABLE[(L[i-1] + L[i-keyLen]) & 255];
00037
00038 unsigned int T8 = (effectiveLen+7) / 8;
00039 byte TM = 255 >> ((8-(effectiveLen%8))%8);
00040 L[128-T8] = PITABLE[L[128-T8] & TM];
00041
00042 for (i=127-T8; i>=0; i--)
00043 L[i] = PITABLE[L[i+1] ^ L[i+T8]];
00044
00045 for (i=0; i<64; i++)
00046 K[i] = L[2*i] + (L[2*i+1] << 8);
00047 }
00048
00049 void RC2::Base::SetKeyWithEffectiveKeyLength(const byte *key, unsigned int length, unsigned int effectiveKeyLength)
00050 {
00051 if (effectiveKeyLength > MAX_EFFECTIVE_KEYLENGTH)
00052 throw InvalidArgument("RC2: effective key length parameter exceeds maximum");
00053 UncheckedSetKey(ENCRYPTION, key, length, effectiveKeyLength);
00054 }
00055
00056 typedef BlockGetAndPut<word16, LittleEndian> Block;
00057
00058 void RC2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00059 {
00060 word16 R0, R1, R2, R3;
00061 Block::Get(inBlock)(R0)(R1)(R2)(R3);
00062
00063 for (int i = 0; i < 16; i++)
00064 {
00065 R0 += (R1 & ~R3) + (R2 & R3) + K[4*i+0];
00066 R0 = rotlFixed(R0, 1);
00067
00068 R1 += (R2 & ~R0) + (R3 & R0) + K[4*i+1];
00069 R1 = rotlFixed(R1, 2);
00070
00071 R2 += (R3 & ~R1) + (R0 & R1) + K[4*i+2];
00072 R2 = rotlFixed(R2, 3);
00073
00074 R3 += (R0 & ~R2) + (R1 & R2) + K[4*i+3];
00075 R3 = rotlFixed(R3, 5);
00076
00077 if (i == 4 || i == 10)
00078 {
00079 R0 += K[R3 & 63];
00080 R1 += K[R0 & 63];
00081 R2 += K[R1 & 63];
00082 R3 += K[R2 & 63];
00083 }
00084 }
00085
00086 Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3);
00087 }
00088
00089 void RC2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00090 {
00091 word16 R0, R1, R2, R3;
00092 Block::Get(inBlock)(R0)(R1)(R2)(R3);
00093
00094 for (int i = 15; i >= 0; i--)
00095 {
00096 if (i == 4 || i == 10)
00097 {
00098 R3 -= K[R2 & 63];
00099 R2 -= K[R1 & 63];
00100 R1 -= K[R0 & 63];
00101 R0 -= K[R3 & 63];
00102 }
00103
00104 R3 = rotrFixed(R3, 5);
00105 R3 -= (R0 & ~R2) + (R1 & R2) + K[4*i+3];
00106
00107 R2 = rotrFixed(R2, 3);
00108 R2 -= (R3 & ~R1) + (R0 & R1) + K[4*i+2];
00109
00110 R1 = rotrFixed(R1, 2);
00111 R1 -= (R2 & ~R0) + (R3 & R0) + K[4*i+1];
00112
00113 R0 = rotrFixed(R0, 1);
00114 R0 -= (R1 & ~R3) + (R2 & R3) + K[4*i+0];
00115 }
00116
00117 Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3);
00118 }
00119
00120 NAMESPACE_END