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