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 #if (_MSC_VER >= 1600) || (__cplusplus >= 201103L)
00277 # define register
00278 #endif
00279
00280 SecByteBlock buffer(56+56+8);
00281 byte *const pc1m=buffer;
00282 byte *const pcr=pc1m+56;
00283 byte *const ks=pcr+56;
00284 register int i,j,l;
00285 int m;
00286
00287 for (j=0; j<56; j++) {
00288 l=pc1[j]-1;
00289 m = l & 07;
00290 pc1m[j]=(key[l>>3] &
00291 bytebit[m])
00292 ? 1 : 0;
00293 }
00294 for (i=0; i<16; i++) {
00295 memset(ks,0,8);
00296 for (j=0; j<56; j++)
00297 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
00298
00299 for (j=0; j<48; j++){
00300
00301 if (pcr[pc2[j]-1]){
00302
00303 l= j % 6;
00304 ks[j/6] |= bytebit[l] >> 2;
00305 }
00306 }
00307
00308 k[2*i] = ((word32)ks[0] << 24)
00309 | ((word32)ks[2] << 16)
00310 | ((word32)ks[4] << 8)
00311 | ((word32)ks[6]);
00312 k[2*i+1] = ((word32)ks[1] << 24)
00313 | ((word32)ks[3] << 16)
00314 | ((word32)ks[5] << 8)
00315 | ((word32)ks[7]);
00316 }
00317
00318 if (dir==DECRYPTION)
00319 for (i=0; i<16; i+=2)
00320 {
00321 std::swap(k[i], k[32-2-i]);
00322 std::swap(k[i+1], k[32-1-i]);
00323 }
00324 }
00325
00326 void RawDES::RawProcessBlock(word32 &l_, word32 &r_) const
00327 {
00328 word32 l = l_, r = r_;
00329 const word32 *kptr=k;
00330
00331 for (unsigned i=0; i<8; i++)
00332 {
00333 word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
00334 l ^= Spbox[6][(work) & 0x3f]
00335 ^ Spbox[4][(work >> 8) & 0x3f]
00336 ^ Spbox[2][(work >> 16) & 0x3f]
00337 ^ Spbox[0][(work >> 24) & 0x3f];
00338 work = r ^ kptr[4*i+1];
00339 l ^= Spbox[7][(work) & 0x3f]
00340 ^ Spbox[5][(work >> 8) & 0x3f]
00341 ^ Spbox[3][(work >> 16) & 0x3f]
00342 ^ Spbox[1][(work >> 24) & 0x3f];
00343
00344 work = rotrFixed(l, 4U) ^ kptr[4*i+2];
00345 r ^= Spbox[6][(work) & 0x3f]
00346 ^ Spbox[4][(work >> 8) & 0x3f]
00347 ^ Spbox[2][(work >> 16) & 0x3f]
00348 ^ Spbox[0][(work >> 24) & 0x3f];
00349 work = l ^ kptr[4*i+3];
00350 r ^= Spbox[7][(work) & 0x3f]
00351 ^ Spbox[5][(work >> 8) & 0x3f]
00352 ^ Spbox[3][(work >> 16) & 0x3f]
00353 ^ Spbox[1][(work >> 24) & 0x3f];
00354 }
00355
00356 l_ = l; r_ = r;
00357 }
00358
00359 void DES_EDE2::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
00360 {
00361 AssertValidKeyLength(length);
00362
00363 m_des1.RawSetKey(GetCipherDirection(), userKey);
00364 m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey+8);
00365 }
00366
00367 void DES_EDE2::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00368 {
00369 word32 l,r;
00370 Block::Get(inBlock)(l)(r);
00371 IPERM(l,r);
00372 m_des1.RawProcessBlock(l, r);
00373 m_des2.RawProcessBlock(r, l);
00374 m_des1.RawProcessBlock(l, r);
00375 FPERM(l,r);
00376 Block::Put(xorBlock, outBlock)(r)(l);
00377 }
00378
00379 void DES_EDE3::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
00380 {
00381 AssertValidKeyLength(length);
00382
00383 m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16));
00384 m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey + 8);
00385 m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0));
00386 }
00387
00388 void DES_EDE3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00389 {
00390 word32 l,r;
00391 Block::Get(inBlock)(l)(r);
00392 IPERM(l,r);
00393 m_des1.RawProcessBlock(l, r);
00394 m_des2.RawProcessBlock(r, l);
00395 m_des3.RawProcessBlock(l, r);
00396 FPERM(l,r);
00397 Block::Put(xorBlock, outBlock)(r)(l);
00398 }
00399
00400 #endif // #ifndef CRYPTOPP_IMPORTS
00401
00402 static inline bool CheckParity(byte b)
00403 {
00404 unsigned int a = b ^ (b >> 4);
00405 return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1;
00406 }
00407
00408 bool DES::CheckKeyParityBits(const byte *key)
00409 {
00410 for (unsigned int i=0; i<8; i++)
00411 if (!CheckParity(key[i]))
00412 return false;
00413 return true;
00414 }
00415
00416 void DES::CorrectKeyParityBits(byte *key)
00417 {
00418 for (unsigned int i=0; i<8; i++)
00419 if (!CheckParity(key[i]))
00420 key[i] ^= 1;
00421 }
00422
00423
00424 void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00425 {
00426 word32 l,r;
00427 Block::Get(inBlock)(l)(r);
00428 IPERM(l,r);
00429 RawProcessBlock(l, r);
00430 FPERM(l,r);
00431 Block::Put(xorBlock, outBlock)(r)(l);
00432 }
00433
00434 void DES_XEX3::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &)
00435 {
00436 AssertValidKeyLength(length);
00437
00438 if (!m_des.get())
00439 m_des.reset(new DES::Encryption);
00440
00441 memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE);
00442 m_des->RawSetKey(GetCipherDirection(), key + 8);
00443 memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE);
00444 }
00445
00446 void DES_XEX3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00447 {
00448 xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE);
00449 m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock);
00450 xorbuf(outBlock, m_x3, BLOCKSIZE);
00451 }
00452
00453 NAMESPACE_END