00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
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 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 #include <spl/types.h>             
00116 
00117 #ifdef _WINDOWS
00118 #include <spl/configwin32.h>
00119 #else
00120 #include <spl/autoconf/config.h>
00121 #endif
00122 
00123 #include <stdio.h>
00124 #ifdef HAVE_STRING_H
00125 #include <string.h>            
00126 #endif
00127 #include <spl/Debug.h>
00128 
00129 #include <spl/Des.h>
00130 #include <spl/text/StringBuffer.h>
00131 
00132 #define G10ERR_SELFTEST_FAILED -1
00133 #define G10ERR_WRONG_KEYLEN -2
00134 #define G10ERR_WEAK_KEY -3
00135 
00136 static void desSetPassword(des_ctx context, const String& password);
00137 
00138 #if defined(__GNUC__) && defined(__GNU_LIBRARY__)
00139 #define working_memcmp memcmp
00140 #else
00141 
00142 
00143 
00144 
00145 int
00146 working_memcmp( const char *a, const char *b, size_t n )
00147 {
00148     for( ; n; n--, a++, b++ )
00149         if( *a != *b )
00150             return (int)(*(byte*)a) - (int)(*(byte*)b);
00151     return 0;
00152 }
00153 #endif
00154 
00155 
00156 
00157 #ifndef CIPHER_ALGO_3DES
00158   #define CIPHER_ALGO_3DES 2
00159 #elif CIPHER_ALGO_3DES != 2
00160   #error CIPHER_ALGO_3DES is defined to a wrong value.
00161 #endif
00162 
00163 
00164 
00165 
00166 typedef struct _tripledes_ctx
00167   {
00168     uint32 encrypt_subkeys[96];
00169     uint32 decrypt_subkeys[96];
00170   }
00171 tripledes_ctx[1];
00172 
00173 static const char *selftest_failed;
00174 
00175 static void des_key_schedule (const byte *, uint32 *);
00176 static int des_setkey (struct _des_ctx *, const byte *);
00177 static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
00178 static int tripledes_set2keys (struct _tripledes_ctx *, const byte *, const byte *);
00179 static int tripledes_set3keys (struct _tripledes_ctx *, const byte *, const byte *, const byte *);
00180 static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, int);
00181 static int is_weak_key ( const byte *key );
00182 static const char *selftest (void);
00183 
00184 
00185 
00186 
00187 
00188 static uint32 sbox1[64] =
00189 {
00190   0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
00191   0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
00192   0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
00193   0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
00194   0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
00195   0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
00196   0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
00197   0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004
00198 };
00199 
00200 static uint32 sbox2[64] =
00201 {
00202   0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
00203   0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
00204   0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
00205   0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
00206   0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
00207   0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
00208   0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
00209   0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000
00210 };
00211 
00212 static uint32 sbox3[64] =
00213 {
00214   0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
00215   0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
00216   0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
00217   0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
00218   0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
00219   0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
00220   0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
00221   0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200
00222 };
00223 
00224 static uint32 sbox4[64] =
00225 {
00226   0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
00227   0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
00228   0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
00229   0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
00230   0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
00231   0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
00232   0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
00233   0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080
00234 };
00235 
00236 static uint32 sbox5[64] =
00237 {
00238   0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
00239   0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
00240   0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
00241   0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
00242   0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
00243   0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
00244   0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
00245   0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100
00246 };
00247 
00248 static uint32 sbox6[64] =
00249 {
00250   0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
00251   0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
00252   0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
00253   0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
00254   0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
00255   0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
00256   0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
00257   0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010
00258 };
00259 
00260 static uint32 sbox7[64] =
00261 {
00262   0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
00263   0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
00264   0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
00265   0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
00266   0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
00267   0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
00268   0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
00269   0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002
00270 };
00271 
00272 static uint32 sbox8[64] =
00273 {
00274   0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
00275   0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
00276   0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
00277   0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
00278   0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
00279   0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
00280   0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
00281   0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000
00282 };
00283 
00284 
00285 
00286 
00287 
00288 
00289 uint32 leftkey_swap[16] =
00290 {
00291   0x00000000, 0x00000001, 0x00000100, 0x00000101,
00292   0x00010000, 0x00010001, 0x00010100, 0x00010101,
00293   0x01000000, 0x01000001, 0x01000100, 0x01000101,
00294   0x01010000, 0x01010001, 0x01010100, 0x01010101
00295 };
00296 
00297 uint32 rightkey_swap[16] =
00298 {
00299   0x00000000, 0x01000000, 0x00010000, 0x01010000,
00300   0x00000100, 0x01000100, 0x00010100, 0x01010100,
00301   0x00000001, 0x01000001, 0x00010001, 0x01010001,
00302   0x00000101, 0x01000101, 0x00010101, 0x01010101,
00303 };
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 static byte encrypt_rotate_tab[16] =
00314 {
00315   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
00316 };
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 static byte weak_keys[64][8] =
00328 {
00329   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
00330   { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },  { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
00331   { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },  { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
00332   { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },  { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
00333   { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 },  { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
00334   { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },  { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
00335   { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },  { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
00336   { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },  { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
00337   { 0x0e, 0x0e, 0x0e, 0x0e, 0xf0, 0xf0, 0xf0, 0xf0 },  { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
00338   { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },  { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
00339   { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },  { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
00340   { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },  { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
00341   { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },  { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
00342   { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },  { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
00343   { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },  { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
00344   { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },  { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
00345   { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },  { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
00346   { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },  { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
00347   { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },  { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
00348   { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },  { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
00349   { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },  { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
00350   { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },  { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
00351   { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },  { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
00352   { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },  { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
00353   { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },  { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
00354   { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },  { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 },
00355   { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },  { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
00356   { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },  { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
00357   { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },  { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
00358   { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },  { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
00359   { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },  { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
00360   { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },  { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }
00361 };
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 #define DO_PERMUTATION(a, temp, b, offset, mask)        \
00372     temp = ((a>>offset) ^ b) & mask;                    \
00373     b ^= temp;                                          \
00374     a ^= temp<<offset;
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 #define INITIAL_PERMUTATION(left, temp, right)          \
00383     DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)    \
00384     DO_PERMUTATION(left, temp, right, 16, 0x0000ffff)   \
00385     DO_PERMUTATION(right, temp, left, 2, 0x33333333)    \
00386     DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff)    \
00387     right =  (right << 1) | (right >> 31);              \
00388     temp  =  (left ^ right) & 0xaaaaaaaa;               \
00389     right ^= temp;                                      \
00390     left  ^= temp;                                      \
00391     left  =  (left << 1) | (left >> 31);
00392 
00393 
00394 
00395 
00396 #define FINAL_PERMUTATION(left, temp, right)            \
00397     left  =  (left << 31) | (left >> 1);                \
00398     temp  =  (left ^ right) & 0xaaaaaaaa;               \
00399     left  ^= temp;                                      \
00400     right ^= temp;                                      \
00401     right  =  (right << 31) | (right >> 1);             \
00402     DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff)    \
00403     DO_PERMUTATION(right, temp, left, 2, 0x33333333)    \
00404     DO_PERMUTATION(left, temp, right, 16, 0x0000ffff)   \
00405     DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 #define DES_ROUND(from, to, work, subkey)               \
00415     work = from ^ *subkey++;                            \
00416     to ^= sbox8[  work      & 0x3f ];                   \
00417     to ^= sbox6[ (work>>8)  & 0x3f ];                   \
00418     to ^= sbox4[ (work>>16) & 0x3f ];                   \
00419     to ^= sbox2[ (work>>24) & 0x3f ];                   \
00420     work = ((from << 28) | (from >> 4)) ^ *subkey++;    \
00421     to ^= sbox7[  work      & 0x3f ];                   \
00422     to ^= sbox5[ (work>>8)  & 0x3f ];                   \
00423     to ^= sbox3[ (work>>16) & 0x3f ];                   \
00424     to ^= sbox1[ (work>>24) & 0x3f ];
00425 
00426 
00427 
00428 
00429 #define READ_64BIT_DATA(data, left, right)                                      \
00430     left  = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];       \
00431     right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
00432 
00433 #define WRITE_64BIT_DATA(data, left, right)                                     \
00434     data[0] = (byte)((left >> 24) &0xff); data[1] = (byte)((left >> 16) &0xff);                 \
00435     data[2] = (byte)((left >> 8) &0xff); data[3] = (byte)(left &0xff);                          \
00436     data[4] = (byte)((right >> 24) &0xff); data[5] = (byte)((right >> 16) &0xff);               \
00437     data[6] = (byte)((right >> 8) &0xff); data[7] = (byte)(right &0xff);
00438 
00439 
00440 
00441 
00442 #define des_ecb_encrypt(ctx, from, to)          des_ecb_crypt(ctx, from, to, 0)
00443 #define des_ecb_decrypt(ctx, from, to)          des_ecb_crypt(ctx, from, to, 1)
00444 #define tripledes_ecb_encrypt(ctx, from, to)    tripledes_ecb_crypt(ctx, from, to, 0)
00445 #define tripledes_ecb_decrypt(ctx, from, to)    tripledes_ecb_crypt(ctx, from, to, 1)
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 static void
00464 des_key_schedule (const byte * rawkey, uint32 * subkey)
00465 {
00466   uint32 left, right, work;
00467   int round;
00468 
00469   READ_64BIT_DATA (rawkey, left, right)
00470 
00471   DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
00472   DO_PERMUTATION (right, work, left, 0, 0x10101010)
00473 
00474   left = (leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2)
00475     | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf])
00476     | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6)
00477     | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4);
00478 
00479   left &= 0x0fffffff;
00480 
00481   right = (rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2)
00482     | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf])
00483     | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6)
00484     | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4);
00485 
00486   right &= 0x0fffffff;
00487 
00488   for (round = 0; round < 16; ++round)
00489     {
00490       left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
00491       right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
00492 
00493       *subkey++ = ((left << 4) & 0x24000000)
00494         | ((left << 28) & 0x10000000)
00495         | ((left << 14) & 0x08000000)
00496         | ((left << 18) & 0x02080000)
00497         | ((left << 6) & 0x01000000)
00498         | ((left << 9) & 0x00200000)
00499         | ((left >> 1) & 0x00100000)
00500         | ((left << 10) & 0x00040000)
00501         | ((left << 2) & 0x00020000)
00502         | ((left >> 10) & 0x00010000)
00503         | ((right >> 13) & 0x00002000)
00504         | ((right >> 4) & 0x00001000)
00505         | ((right << 6) & 0x00000800)
00506         | ((right >> 1) & 0x00000400)
00507         | ((right >> 14) & 0x00000200)
00508         | (right & 0x00000100)
00509         | ((right >> 5) & 0x00000020)
00510         | ((right >> 10) & 0x00000010)
00511         | ((right >> 3) & 0x00000008)
00512         | ((right >> 18) & 0x00000004)
00513         | ((right >> 26) & 0x00000002)
00514         | ((right >> 24) & 0x00000001);
00515 
00516       *subkey++ = ((left << 15) & 0x20000000)
00517         | ((left << 17) & 0x10000000)
00518         | ((left << 10) & 0x08000000)
00519         | ((left << 22) & 0x04000000)
00520         | ((left >> 2) & 0x02000000)
00521         | ((left << 1) & 0x01000000)
00522         | ((left << 16) & 0x00200000)
00523         | ((left << 11) & 0x00100000)
00524         | ((left << 3) & 0x00080000)
00525         | ((left >> 6) & 0x00040000)
00526         | ((left << 15) & 0x00020000)
00527         | ((left >> 4) & 0x00010000)
00528         | ((right >> 2) & 0x00002000)
00529         | ((right << 8) & 0x00001000)
00530         | ((right >> 14) & 0x00000808)
00531         | ((right >> 9) & 0x00000400)
00532         | ((right) & 0x00000200)
00533         | ((right << 7) & 0x00000100)
00534         | ((right >> 7) & 0x00000020)
00535         | ((right >> 3) & 0x00000011)
00536         | ((right << 2) & 0x00000004)
00537         | ((right >> 21) & 0x00000002);
00538     }
00539 }
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 static int
00549 des_setkey (struct _des_ctx *ctx, const byte * key)
00550 {
00551   int i;
00552 
00553   if( selftest_failed )
00554     return G10ERR_SELFTEST_FAILED;
00555 
00556   des_key_schedule (key, ctx->encrypt_subkeys);
00557 
00558   for(i=0; i<32; i+=2)
00559     {
00560       ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[30-i];
00561       ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
00562     }
00563 
00564   return 0;
00565 }
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 static int des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
00574 {
00575   uint32 left, right, work;
00576   uint32 *keys;
00577 
00578   keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
00579 
00580   READ_64BIT_DATA (from, left, right)
00581   INITIAL_PERMUTATION (left, work, right)
00582 
00583   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00584   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00585   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00586   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00587   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00588   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00589   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00590   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00591 
00592   FINAL_PERMUTATION (right, work, left)
00593   WRITE_64BIT_DATA (to, right, left)
00594 
00595   return 0;
00596 }
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 static int
00606 tripledes_set2keys (struct _tripledes_ctx *ctx,
00607                     const byte * key1,
00608                     const byte * key2)
00609 {
00610   int i;
00611 
00612   des_key_schedule (key1, ctx->encrypt_subkeys);
00613   des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
00614 
00615   for(i=0; i<32; i+=2)
00616     {
00617       ctx->decrypt_subkeys[i]    = ctx->encrypt_subkeys[30-i];
00618       ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[31-i];
00619 
00620       ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
00621       ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
00622 
00623       ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
00624       ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
00625 
00626       ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
00627       ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
00628     }
00629 
00630   return 0;
00631 }
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 static int
00641 tripledes_set3keys (struct _tripledes_ctx *ctx,
00642                     const byte * key1,
00643                     const byte * key2,
00644                     const byte * key3)
00645 {
00646   int i;
00647 
00648   des_key_schedule (key1, ctx->encrypt_subkeys);
00649   des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
00650   des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
00651 
00652   for(i=0; i<32; i+=2)
00653     {
00654       ctx->decrypt_subkeys[i]    = ctx->encrypt_subkeys[94-i];
00655       ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[95-i];
00656 
00657       ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
00658       ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
00659 
00660       ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
00661       ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
00662     }
00663 
00664   return 0;
00665 }
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 static int
00674 tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, int mode)
00675 {
00676   uint32 left, right, work;
00677   uint32 *keys;
00678 
00679   keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
00680 
00681   READ_64BIT_DATA (from, left, right)
00682   INITIAL_PERMUTATION (left, work, right)
00683 
00684   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00685   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00686   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00687   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00688   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00689   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00690   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00691   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00692 
00693   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00694   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00695   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00696   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00697   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00698   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00699   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00700   DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
00701 
00702   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00703   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00704   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00705   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00706   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00707   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00708   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00709   DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
00710 
00711   FINAL_PERMUTATION (right, work, left)
00712   WRITE_64BIT_DATA (to, right, left)
00713 
00714   return 0;
00715 }
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 static int
00726 is_weak_key ( const byte *key )
00727 {
00728   byte work[8];
00729   int i, left, right, middle, cmp_result;
00730 
00731   
00732   for(i=0; i<8; ++i)
00733      work[i] = (byte)(key[i] & 0xfe);
00734 
00735   
00736   left = 0;
00737   right = 63;
00738   while(left <= right)
00739     {
00740       middle = (left + right) / 2;
00741 
00742       if ( !(cmp_result=working_memcmp((char *)work, (char *)weak_keys[middle], 8)) )
00743           return -1;
00744 
00745       if ( cmp_result > 0 )
00746           left = middle + 1;
00747       else
00748           right = middle - 1;
00749     }
00750 
00751   return 0;
00752 }
00753 
00754 
00755 
00756 
00757 
00758 
00759 
00760 
00761 static const char *
00762 selftest (void)
00763 {
00764   
00765 
00766 
00767 
00768   if (sizeof (uint32) != 4)
00769        return "Wrong word size for DES configured.";
00770 
00771   
00772 
00773 
00774   {
00775     int i;
00776     byte key[8] =
00777     {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
00778     byte input[8] =
00779     {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
00780     byte result[8] =
00781     {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a};
00782     byte temp1[8], temp2[8], temp3[8];
00783     des_ctx des;
00784 
00785     for (i = 0; i < 64; ++i)
00786       {
00787         des_setkey (des, key);
00788         des_ecb_encrypt (des, input, temp1);
00789         des_ecb_encrypt (des, temp1, temp2);
00790         des_setkey (des, temp2);
00791         des_ecb_decrypt (des, temp1, temp3);
00792         memcpy (key, temp3, 8);
00793         memcpy (input, temp1, 8);
00794       }
00795     if (memcmp (temp3, result, 8))
00796       return "DES maintenance test failed.";
00797   }
00798 
00799 
00800   
00801 
00802 
00803   {
00804     int i;
00805     byte input[8] =
00806     {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
00807     byte key1[8] =
00808     {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
00809     byte key2[8] =
00810     {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd};
00811     byte result[8] =
00812     {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3};
00813 
00814     tripledes_ctx des3;
00815 
00816     for (i = 0; i < 16; ++i)
00817       {
00818         tripledes_set2keys (des3, key1, key2);
00819         tripledes_ecb_encrypt (des3, input, key1);
00820         tripledes_ecb_decrypt (des3, input, key2);
00821         tripledes_set3keys (des3, key1, input, key2);
00822         tripledes_ecb_encrypt (des3, input, input);
00823       }
00824     if (memcmp (input, result, 8))
00825       return "Triple-DES test failed.";
00826   }
00827 
00828     
00829 
00830 
00831 
00832     {   struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = {
00833         { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00834             0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00835             0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
00836           { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00  },
00837           { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00  }
00838         },
00839 
00840         { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00841             0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00842             0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
00843           { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, },
00844           { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00  }
00845         },
00846         { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
00847             0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
00848             0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E  },
00849           { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A  },
00850           { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A  }
00851         },
00852         { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
00853             0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
00854             0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6  },
00855           { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2  },
00856           { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95  }
00857         },
00858         { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
00859             0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
00860             0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF  },
00861           { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
00862           { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18  }
00863         },
00864         { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
00865             0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00866             0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF  },
00867           { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
00868           { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1  }
00869         },
00870         { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
00871             0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00872             0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10  },
00873           { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
00874           { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72  }
00875         },
00876         { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
00877             0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
00878             0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
00879           { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
00880           { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  }
00881         },
00882         { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00883             0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00884             0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02  },
00885           { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
00886           { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74  }
00887         },
00888         { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
00889             0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
00890             0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
00891           { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
00892           { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  }
00893         }
00894         };
00895 
00896         byte            result[8];
00897         int             i;
00898         static char     error[80];
00899         tripledes_ctx   des3;
00900 
00901         for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i) {
00902             tripledes_set3keys (des3, testdata[i].key, testdata[i].key + 8, testdata[i].key + 16);
00903 
00904             tripledes_ecb_encrypt (des3, testdata[i].plain, result);
00905             if (memcmp (testdata[i].cipher, result, 8)) {
00906                 sprintf (error, "Triple-DES SSLeay test pattern no. %d failend on encryption.", i+1);
00907                 return error;
00908             }
00909 
00910             tripledes_ecb_decrypt (des3, testdata[i].cipher, result);
00911             if (memcmp (testdata[i].plain, result, 8)) {
00912                 sprintf (error, "Triple-DES SSLeay test pattern no. %d failend on decryption.", i+1);
00913                 return error;
00914             }
00915         }
00916     }
00917 
00918   
00919 
00920 
00921 
00922 
00923   {
00924     int i;
00925 
00926     for (i = 0; i < 64; ++i)
00927         if (!is_weak_key(weak_keys[i]))
00928             return "DES weak key detection failed";
00929   }
00930 
00931   return 0;
00932 }
00933 
00934 
00935 static int
00936 do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
00937 {
00938     if( selftest_failed )
00939         return G10ERR_SELFTEST_FAILED;
00940     if( keylen != 24 )
00941         return G10ERR_WRONG_KEYLEN;
00942 
00943     tripledes_set3keys ( ctx, key, key+8, key+16);
00944 
00945     if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) )
00946         return G10ERR_WEAK_KEY;
00947 
00948     return 0;
00949 }
00950 
00951 
00952 static void
00953 do_tripledes_encrypt( struct _tripledes_ctx *ctx, byte *outbuf, byte *inbuf )
00954 {
00955     tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
00956 }
00957 
00958 static void
00959 do_tripledes_decrypt( struct _tripledes_ctx *ctx, byte *outbuf, byte *inbuf )
00960 {
00961     tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
00962 }
00963 
00964 
00965 
00966 
00967 
00968 
00969 
00970 
00971 static const char *
00972 des_get_info( int algo, size_t *keylen,
00973                    size_t *blocksize, size_t *contextsize,
00974                    int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
00975                    void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
00976                    void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
00977                  )
00978 {
00979     static int did_selftest = 0;
00980 
00981     if( !did_selftest ) {
00982         const char *s = selftest();
00983         did_selftest = 1;
00984         if( s ) {
00985             fprintf(stderr,"%s\n", s );
00986             selftest_failed = s;
00987             return NULL;
00988         }
00989     }
00990 
00991     if( algo == CIPHER_ALGO_3DES ) {
00992         *keylen = 192;
00993         *blocksize = 8;
00994         *contextsize = sizeof(struct _tripledes_ctx);
00995         *(int  (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey
00996                                                         = do_tripledes_setkey;
00997         *(void (**)(struct _tripledes_ctx*, byte*, byte*))r_encrypt
00998                                                         = do_tripledes_encrypt;
00999         *(void (**)(struct _tripledes_ctx*, byte*, byte*))r_decrypt
01000                                                         = do_tripledes_decrypt;
01001         return "3DES";
01002     }
01003     return NULL;
01004 }
01005 
01006 static void _encryptBuffer(des_ctx context, Array<byte>& data, const bool encrypt)
01007 {
01008         byte chunk[8];
01009         Array<byte> to(8);
01010         int x;
01011         int y;
01012 
01013         int len = data.Length();
01014 
01015         for ( x = 0; x < len; x+=8) 
01016         {
01017                 for (y = 0; y < 8; y++) 
01018                 {
01019                         if (x+y >= len) 
01020                         {
01021                                 chunk[y] = 0;
01022                         }
01023                         else
01024                         {
01025                                 chunk[y] = data[x+y];
01026                         }
01027                 }
01028 
01029                 data.CopyTo(to, x);
01030 
01031                 if (encrypt) 
01032                 {
01033                         des_ecb_encrypt(context, chunk, to.Data());
01034                 }
01035                 else 
01036                 {
01037                         des_ecb_decrypt(context, chunk, to.Data());
01038                 }
01039                 Array<byte>::CopyBinary(to, 0, data, x, 8);
01040         }
01041         if ( (len % 8) != 0 ) 
01042         {
01043                 byte out[8];
01044                 memset( out, 0, 8 );
01045                 for (x = 0; x < 8; x++) 
01046                 {
01047                         chunk[x] = 0;
01048                 }
01049                 
01050                 
01051                 for (x = 7; x > 0; x--) 
01052                 {
01053                         chunk[x-1] = data[len-x];
01054                 }
01055                 if (encrypt) 
01056                 {
01057                         des_ecb_encrypt(context, chunk, out);
01058                 }
01059                 else 
01060                 {
01061                         des_ecb_decrypt(context, chunk, out);
01062                 }
01063                 for (x = 7; x > 0; x--) 
01064                 {
01065                         data[len-x] = out[x-1];
01066                 }
01067         }
01068 }
01069 
01070 static void desSetPassword(des_ctx context, const String& password)
01071 {
01072         byte pass[8];
01073         int x;
01074 
01075         memset( pass, 0, 8 );
01076 
01077         for (x = 0; x < password.Length(); x++) 
01078         {
01079                 if ( x >= 8 )
01080                 {
01081                         pass[x % 8] ^= password[x];
01082                 }
01083                 else
01084                 {
01085                         pass[x] = password[x];                  
01086                 }
01087         }
01088         des_setkey(context, pass);      
01089 }
01090 
01091 static bool desEncryptBinaryCtx( des_ctx context, const Array<byte>& data, Array<byte>& output)
01092 {
01093         int outlen;
01094 
01095         if ( (data.Length() % 8) == 0 )
01096         {
01097                 outlen = data.Length();
01098         }
01099         else
01100         {
01101                 outlen = data.Length() + 8 - data.Length() % 8;
01102         }
01103         
01104         if (output.Length() != outlen)
01105         {
01106                 output = Array<byte>(outlen);
01107         }
01108         else
01109         {
01110                 output.Clear();
01111         }
01112 
01113         data.CopyTo(output, 0);
01114         
01115         _encryptBuffer(context, output, true);
01116         return true;
01117 }
01118 
01119 bool desDecryptBinaryCtx( des_ctx context, Array<byte>& data )
01120 {
01121         
01122         _encryptBuffer(context, data, false);
01123         ASSERT( sizeof(byte) == sizeof(char) );
01124         return true;
01125 }
01126 
01127 bool desEncryptBinary(const String& password, const Array<byte>& data, Array<byte>& output)
01128 {
01129         des_ctx context;
01130         desSetPassword( context, password );
01131         return desEncryptBinaryCtx(context, data, output);
01132 }
01133 
01134 bool desDecryptBinary( const String& password, Array<byte>& data )
01135 {
01136         des_ctx context;
01137         desSetPassword( context, password );
01138         return desDecryptBinaryCtx(context, data);
01139 }
01140 
01141 static RefCountPtr<String> desEncryptStringCtx(des_ctx ctx, const Array<byte>& data)
01142 {
01143         int datalen8 = data.Length() + 8 - data.Length() % 8;
01144         Array<byte> data8(datalen8);
01145 
01146         Array<byte>::CopyBinary(data, 0, data8, 0, data.Length());
01147 
01148         _encryptBuffer(ctx, data8, true);
01149         return String::Base64Encode((const char *)data8.Data(), datalen8);
01150 }
01151 
01152 static RefCountPtr<Array<byte> > desDecryptStringCtx(des_ctx context, const String& data)
01153 {
01154         RefCountPtr<Array<byte> > bins = String::Base64Decode(data);
01155 
01156         
01157         _encryptBuffer(context, bins, false);
01158         
01159         return bins;
01160 }
01161 
01162 DES::DES(const String& password)
01163 {
01164         desSetPassword( m_ctx, password );
01165 }
01166 
01167 void DES::EncryptBinary(const Array<byte>& data, Array<byte>& output)
01168 {
01169         if ( ! desEncryptBinaryCtx(m_ctx, data, output) )
01170         {
01171                 throw OutOfMemoryException();
01172         }
01173 }
01174 
01175 void DES::DecryptBinary(Array<byte>& data )
01176 {
01177         if ( ! desDecryptBinaryCtx(m_ctx, data) )
01178         {
01179                 throw OutOfMemoryException();
01180         }
01181 }
01182 
01183 RefCountPtr<Array<byte> > DES::DecryptString(const String& data)
01184 {
01185         RefCountPtr<Array<byte> > output = desDecryptStringCtx(m_ctx, data);
01186         return output;
01187 }
01188 
01189 RefCountPtr<String> DES::EncryptString(const Array<byte>& data)
01190 {
01191         return desEncryptStringCtx(m_ctx, data);
01192 }
01193 
01194 RefCountPtr<Array<byte> > DES::DecryptString(const String& password, const String& data)
01195 {
01196         des_ctx context;
01197         desSetPassword( context, password );
01198 
01199         return desDecryptStringCtx(context, data);
01200 }
01201 
01202 RefCountPtr<String> DES::EncryptString(const String& password, const Array<byte>& data)
01203 {
01204         des_ctx context;
01205 
01206         desSetPassword( context, password );
01207         
01208         return desEncryptStringCtx( context, data );
01209 }
01210 
01211 void DES::EncryptBinary(const String& password, const Array<byte>& data, Array<byte>& output)
01212 {
01213         if ( !desEncryptBinary(password, data, output) )
01214         {
01215                 throw OutOfMemoryException();
01216         }
01217 }
01218 
01219 void DES::DecryptBinary(const String& password, Array<byte>& data)
01220 {
01221         if ( !desDecryptBinary(password, data) )
01222         {
01223                 throw OutOfMemoryException();
01224         }
01225 }
01226