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