00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "pch.h"
00018 #include "misc.h"
00019 #include "des.h"
00020
00021 NAMESPACE_BEGIN(CryptoPP)
00022
00023 typedef BlockGetAndPut<word32, BigEndian> Block;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static inline void IPERM(word32 &left, word32 &right)
00077 {
00078 word32 work;
00079
00080 right = rotlFixed(right, 4U);
00081 work = (left ^ right) & 0xf0f0f0f0;
00082 left ^= work;
00083 right = rotrFixed(right^work, 20U);
00084 work = (left ^ right) & 0xffff0000;
00085 left ^= work;
00086 right = rotrFixed(right^work, 18U);
00087 work = (left ^ right) & 0x33333333;
00088 left ^= work;
00089 right = rotrFixed(right^work, 6U);
00090 work = (left ^ right) & 0x00ff00ff;
00091 left ^= work;
00092 right = rotlFixed(right^work, 9U);
00093 work = (left ^ right) & 0xaaaaaaaa;
00094 left = rotlFixed(left^work, 1U);
00095 right ^= work;
00096 }
00097
00098 static inline void FPERM(word32 &left, word32 &right)
00099 {
00100 word32 work;
00101
00102 right = rotrFixed(right, 1U);
00103 work = (left ^ right) & 0xaaaaaaaa;
00104 right ^= work;
00105 left = rotrFixed(left^work, 9U);
00106 work = (left ^ right) & 0x00ff00ff;
00107 right ^= work;
00108 left = rotlFixed(left^work, 6U);
00109 work = (left ^ right) & 0x33333333;
00110 right ^= work;
00111 left = rotlFixed(left^work, 18U);
00112 work = (left ^ right) & 0xffff0000;
00113 right ^= work;
00114 left = rotlFixed(left^work, 20U);
00115 work = (left ^ right) & 0xf0f0f0f0;
00116 right ^= work;
00117 left = rotrFixed(left^work, 4U);
00118 }
00119
00120 void DES::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
00121 {
00122 AssertValidKeyLength(length);
00123
00124 RawSetKey(GetCipherDirection(), userKey);
00125 }
00126
00127 #ifndef CRYPTOPP_IMPORTS
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 #ifdef notdef
00138
00139 static byte ip[] = {
00140 58, 50, 42, 34, 26, 18, 10, 2,
00141 60, 52, 44, 36, 28, 20, 12, 4,
00142 62, 54, 46, 38, 30, 22, 14, 6,
00143 64, 56, 48, 40, 32, 24, 16, 8,
00144 57, 49, 41, 33, 25, 17, 9, 1,
00145 59, 51, 43, 35, 27, 19, 11, 3,
00146 61, 53, 45, 37, 29, 21, 13, 5,
00147 63, 55, 47, 39, 31, 23, 15, 7
00148 };
00149
00150
00151 static byte fp[] = {
00152 40, 8, 48, 16, 56, 24, 64, 32,
00153 39, 7, 47, 15, 55, 23, 63, 31,
00154 38, 6, 46, 14, 54, 22, 62, 30,
00155 37, 5, 45, 13, 53, 21, 61, 29,
00156 36, 4, 44, 12, 52, 20, 60, 28,
00157 35, 3, 43, 11, 51, 19, 59, 27,
00158 34, 2, 42, 10, 50, 18, 58, 26,
00159 33, 1, 41, 9, 49, 17, 57, 25
00160 };
00161
00162 static byte ei[] = {
00163 32, 1, 2, 3, 4, 5,
00164 4, 5, 6, 7, 8, 9,
00165 8, 9, 10, 11, 12, 13,
00166 12, 13, 14, 15, 16, 17,
00167 16, 17, 18, 19, 20, 21,
00168 20, 21, 22, 23, 24, 25,
00169 24, 25, 26, 27, 28, 29,
00170 28, 29, 30, 31, 32, 1
00171 };
00172
00173 static byte sbox[8][64] = {
00174
00175 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
00176 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
00177 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
00178 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
00179
00180
00181 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
00182 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
00183 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
00184 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
00185
00186
00187 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
00188 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
00189 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
00190 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
00191
00192
00193 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
00194 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
00195 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
00196 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
00197
00198
00199 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
00200 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
00201 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
00202 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
00203
00204
00205 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
00206 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
00207 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
00208 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
00209
00210
00211 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
00212 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
00213 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
00214 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
00215
00216
00217 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
00218 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
00219 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
00220 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
00221 };
00222
00223
00224 static byte p32i[] = {
00225 16, 7, 20, 21,
00226 29, 12, 28, 17,
00227 1, 15, 23, 26,
00228 5, 18, 31, 10,
00229 2, 8, 24, 14,
00230 32, 27, 3, 9,
00231 19, 13, 30, 6,
00232 22, 11, 4, 25
00233 };
00234 #endif
00235
00236
00237 static const byte pc1[] = {
00238 57, 49, 41, 33, 25, 17, 9,
00239 1, 58, 50, 42, 34, 26, 18,
00240 10, 2, 59, 51, 43, 35, 27,
00241 19, 11, 3, 60, 52, 44, 36,
00242
00243 63, 55, 47, 39, 31, 23, 15,
00244 7, 62, 54, 46, 38, 30, 22,
00245 14, 6, 61, 53, 45, 37, 29,
00246 21, 13, 5, 28, 20, 12, 4
00247 };
00248
00249
00250 static const byte totrot[] = {
00251 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
00252 };
00253
00254
00255 static const byte pc2[] = {
00256 14, 17, 11, 24, 1, 5,
00257 3, 28, 15, 6, 21, 10,
00258 23, 19, 12, 4, 26, 8,
00259 16, 7, 27, 20, 13, 2,
00260 41, 52, 31, 37, 47, 55,
00261 30, 40, 51, 45, 33, 48,
00262 44, 49, 39, 56, 34, 53,
00263 46, 42, 50, 36, 29, 32
00264 };
00265
00266
00267
00268
00269 static const int bytebit[] = {
00270 0200,0100,040,020,010,04,02,01
00271 };
00272
00273
00274 void RawDES::RawSetKey(CipherDir dir, const byte *key)
00275 {
00276 SecByteBlock buffer(56+56+8);
00277 byte *const pc1m=buffer;
00278 byte *const pcr=pc1m+56;
00279 byte *const ks=pcr+56;
00280 register int i,j,l;
00281 int m;
00282
00283 for (j=0; j<56; j++) {
00284 l=pc1[j]-1;
00285 m = l & 07;
00286 pc1m[j]=(key[l>>3] &
00287 bytebit[m])
00288 ? 1 : 0;
00289 }
00290 for (i=0; i<16; i++) {
00291 memset(ks,0,8);
00292 for (j=0; j<56; j++)
00293 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
00294
00295 for (j=0; j<48; j++){
00296
00297 if (pcr[pc2[j]-1]){
00298
00299 l= j % 6;
00300 ks[j/6] |= bytebit[l] >> 2;
00301 }
00302 }
00303
00304 k[2*i] = ((word32)ks[0] << 24)
00305 | ((word32)ks[2] << 16)
00306 | ((word32)ks[4] << 8)
00307 | ((word32)ks[6]);
00308 k[2*i+1] = ((word32)ks[1] << 24)
00309 | ((word32)ks[3] << 16)
00310 | ((word32)ks[5] << 8)
00311 | ((word32)ks[7]);
00312 }
00313
00314 if (dir==DECRYPTION)
00315 for (i=0; i<16; i+=2)
00316 {
00317 std::swap(k[i], k[32-2-i]);
00318 std::swap(k[i+1], k[32-1-i]);
00319 }
00320 }
00321
00322 void RawDES::RawProcessBlock(word32 &l_, word32 &r_) const
00323 {
00324 word32 l = l_, r = r_;
00325 const word32 *kptr=k;
00326
00327 for (unsigned i=0; i<8; i++)
00328 {
00329 word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
00330 l ^= Spbox[6][(work) & 0x3f]
00331 ^ Spbox[4][(work >> 8) & 0x3f]
00332 ^ Spbox[2][(work >> 16) & 0x3f]
00333 ^ Spbox[0][(work >> 24) & 0x3f];
00334 work = r ^ kptr[4*i+1];
00335 l ^= Spbox[7][(work) & 0x3f]
00336 ^ Spbox[5][(work >> 8) & 0x3f]
00337 ^ Spbox[3][(work >> 16) & 0x3f]
00338 ^ Spbox[1][(work >> 24) & 0x3f];
00339
00340 work = rotrFixed(l, 4U) ^ kptr[4*i+2];
00341 r ^= Spbox[6][(work) & 0x3f]
00342 ^ Spbox[4][(work >> 8) & 0x3f]
00343 ^ Spbox[2][(work >> 16) & 0x3f]
00344 ^ Spbox[0][(work >> 24) & 0x3f];
00345 work = l ^ kptr[4*i+3];
00346 r ^= Spbox[7][(work) & 0x3f]
00347 ^ Spbox[5][(work >> 8) & 0x3f]
00348 ^ Spbox[3][(work >> 16) & 0x3f]
00349 ^ Spbox[1][(work >> 24) & 0x3f];
00350 }
00351
00352 l_ = l; r_ = r;
00353 }
00354
00355 void DES_EDE2::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
00356 {
00357 AssertValidKeyLength(length);
00358
00359 m_des1.RawSetKey(GetCipherDirection(), userKey);
00360 m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey+8);
00361 }
00362
00363 void DES_EDE2::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00364 {
00365 word32 l,r;
00366 Block::Get(inBlock)(l)(r);
00367 IPERM(l,r);
00368 m_des1.RawProcessBlock(l, r);
00369 m_des2.RawProcessBlock(r, l);
00370 m_des1.RawProcessBlock(l, r);
00371 FPERM(l,r);
00372 Block::Put(xorBlock, outBlock)(r)(l);
00373 }
00374
00375 void DES_EDE3::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
00376 {
00377 AssertValidKeyLength(length);
00378
00379 m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16));
00380 m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey + 8);
00381 m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0));
00382 }
00383
00384 void DES_EDE3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00385 {
00386 word32 l,r;
00387 Block::Get(inBlock)(l)(r);
00388 IPERM(l,r);
00389 m_des1.RawProcessBlock(l, r);
00390 m_des2.RawProcessBlock(r, l);
00391 m_des3.RawProcessBlock(l, r);
00392 FPERM(l,r);
00393 Block::Put(xorBlock, outBlock)(r)(l);
00394 }
00395
00396 #endif // #ifndef CRYPTOPP_IMPORTS
00397
00398 static inline bool CheckParity(byte b)
00399 {
00400 unsigned int a = b ^ (b >> 4);
00401 return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1;
00402 }
00403
00404 bool DES::CheckKeyParityBits(const byte *key)
00405 {
00406 for (unsigned int i=0; i<8; i++)
00407 if (!CheckParity(key[i]))
00408 return false;
00409 return true;
00410 }
00411
00412 void DES::CorrectKeyParityBits(byte *key)
00413 {
00414 for (unsigned int i=0; i<8; i++)
00415 if (!CheckParity(key[i]))
00416 key[i] ^= 1;
00417 }
00418
00419
00420 void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00421 {
00422 word32 l,r;
00423 Block::Get(inBlock)(l)(r);
00424 IPERM(l,r);
00425 RawProcessBlock(l, r);
00426 FPERM(l,r);
00427 Block::Put(xorBlock, outBlock)(r)(l);
00428 }
00429
00430 void DES_XEX3::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &)
00431 {
00432 AssertValidKeyLength(length);
00433
00434 if (!m_des.get())
00435 m_des.reset(new DES::Encryption);
00436
00437 memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE);
00438 m_des->RawSetKey(GetCipherDirection(), key + 8);
00439 memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE);
00440 }
00441
00442 void DES_XEX3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00443 {
00444 xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE);
00445 m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock);
00446 xorbuf(outBlock, m_x3, BLOCKSIZE);
00447 }
00448
00449 NAMESPACE_END