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 #include "xyssl/config.h"
00028
00029 #if defined(XYSSL_DES_C)
00030
00031 #include "xyssl/des.h"
00032
00033 #include <string.h>
00034
00035
00036
00037
00038 #ifndef GET_ULONG_BE
00039 #define GET_ULONG_BE(n,b,i) \
00040 { \
00041 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
00042 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
00043 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
00044 | ( (unsigned long) (b)[(i) + 3] ); \
00045 }
00046 #endif
00047
00048 #ifndef PUT_ULONG_BE
00049 #define PUT_ULONG_BE(n,b,i) \
00050 { \
00051 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
00052 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
00053 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
00054 (b)[(i) + 3] = (unsigned char) ( (n) ); \
00055 }
00056 #endif
00057
00058
00059
00060
00061 static const unsigned long SB1[64] =
00062 {
00063 0x01010400, 0x00000000, 0x00010000, 0x01010404,
00064 0x01010004, 0x00010404, 0x00000004, 0x00010000,
00065 0x00000400, 0x01010400, 0x01010404, 0x00000400,
00066 0x01000404, 0x01010004, 0x01000000, 0x00000004,
00067 0x00000404, 0x01000400, 0x01000400, 0x00010400,
00068 0x00010400, 0x01010000, 0x01010000, 0x01000404,
00069 0x00010004, 0x01000004, 0x01000004, 0x00010004,
00070 0x00000000, 0x00000404, 0x00010404, 0x01000000,
00071 0x00010000, 0x01010404, 0x00000004, 0x01010000,
00072 0x01010400, 0x01000000, 0x01000000, 0x00000400,
00073 0x01010004, 0x00010000, 0x00010400, 0x01000004,
00074 0x00000400, 0x00000004, 0x01000404, 0x00010404,
00075 0x01010404, 0x00010004, 0x01010000, 0x01000404,
00076 0x01000004, 0x00000404, 0x00010404, 0x01010400,
00077 0x00000404, 0x01000400, 0x01000400, 0x00000000,
00078 0x00010004, 0x00010400, 0x00000000, 0x01010004
00079 };
00080
00081 static const unsigned long SB2[64] =
00082 {
00083 0x80108020, 0x80008000, 0x00008000, 0x00108020,
00084 0x00100000, 0x00000020, 0x80100020, 0x80008020,
00085 0x80000020, 0x80108020, 0x80108000, 0x80000000,
00086 0x80008000, 0x00100000, 0x00000020, 0x80100020,
00087 0x00108000, 0x00100020, 0x80008020, 0x00000000,
00088 0x80000000, 0x00008000, 0x00108020, 0x80100000,
00089 0x00100020, 0x80000020, 0x00000000, 0x00108000,
00090 0x00008020, 0x80108000, 0x80100000, 0x00008020,
00091 0x00000000, 0x00108020, 0x80100020, 0x00100000,
00092 0x80008020, 0x80100000, 0x80108000, 0x00008000,
00093 0x80100000, 0x80008000, 0x00000020, 0x80108020,
00094 0x00108020, 0x00000020, 0x00008000, 0x80000000,
00095 0x00008020, 0x80108000, 0x00100000, 0x80000020,
00096 0x00100020, 0x80008020, 0x80000020, 0x00100020,
00097 0x00108000, 0x00000000, 0x80008000, 0x00008020,
00098 0x80000000, 0x80100020, 0x80108020, 0x00108000
00099 };
00100
00101 static const unsigned long SB3[64] =
00102 {
00103 0x00000208, 0x08020200, 0x00000000, 0x08020008,
00104 0x08000200, 0x00000000, 0x00020208, 0x08000200,
00105 0x00020008, 0x08000008, 0x08000008, 0x00020000,
00106 0x08020208, 0x00020008, 0x08020000, 0x00000208,
00107 0x08000000, 0x00000008, 0x08020200, 0x00000200,
00108 0x00020200, 0x08020000, 0x08020008, 0x00020208,
00109 0x08000208, 0x00020200, 0x00020000, 0x08000208,
00110 0x00000008, 0x08020208, 0x00000200, 0x08000000,
00111 0x08020200, 0x08000000, 0x00020008, 0x00000208,
00112 0x00020000, 0x08020200, 0x08000200, 0x00000000,
00113 0x00000200, 0x00020008, 0x08020208, 0x08000200,
00114 0x08000008, 0x00000200, 0x00000000, 0x08020008,
00115 0x08000208, 0x00020000, 0x08000000, 0x08020208,
00116 0x00000008, 0x00020208, 0x00020200, 0x08000008,
00117 0x08020000, 0x08000208, 0x00000208, 0x08020000,
00118 0x00020208, 0x00000008, 0x08020008, 0x00020200
00119 };
00120
00121 static const unsigned long SB4[64] =
00122 {
00123 0x00802001, 0x00002081, 0x00002081, 0x00000080,
00124 0x00802080, 0x00800081, 0x00800001, 0x00002001,
00125 0x00000000, 0x00802000, 0x00802000, 0x00802081,
00126 0x00000081, 0x00000000, 0x00800080, 0x00800001,
00127 0x00000001, 0x00002000, 0x00800000, 0x00802001,
00128 0x00000080, 0x00800000, 0x00002001, 0x00002080,
00129 0x00800081, 0x00000001, 0x00002080, 0x00800080,
00130 0x00002000, 0x00802080, 0x00802081, 0x00000081,
00131 0x00800080, 0x00800001, 0x00802000, 0x00802081,
00132 0x00000081, 0x00000000, 0x00000000, 0x00802000,
00133 0x00002080, 0x00800080, 0x00800081, 0x00000001,
00134 0x00802001, 0x00002081, 0x00002081, 0x00000080,
00135 0x00802081, 0x00000081, 0x00000001, 0x00002000,
00136 0x00800001, 0x00002001, 0x00802080, 0x00800081,
00137 0x00002001, 0x00002080, 0x00800000, 0x00802001,
00138 0x00000080, 0x00800000, 0x00002000, 0x00802080
00139 };
00140
00141 static const unsigned long SB5[64] =
00142 {
00143 0x00000100, 0x02080100, 0x02080000, 0x42000100,
00144 0x00080000, 0x00000100, 0x40000000, 0x02080000,
00145 0x40080100, 0x00080000, 0x02000100, 0x40080100,
00146 0x42000100, 0x42080000, 0x00080100, 0x40000000,
00147 0x02000000, 0x40080000, 0x40080000, 0x00000000,
00148 0x40000100, 0x42080100, 0x42080100, 0x02000100,
00149 0x42080000, 0x40000100, 0x00000000, 0x42000000,
00150 0x02080100, 0x02000000, 0x42000000, 0x00080100,
00151 0x00080000, 0x42000100, 0x00000100, 0x02000000,
00152 0x40000000, 0x02080000, 0x42000100, 0x40080100,
00153 0x02000100, 0x40000000, 0x42080000, 0x02080100,
00154 0x40080100, 0x00000100, 0x02000000, 0x42080000,
00155 0x42080100, 0x00080100, 0x42000000, 0x42080100,
00156 0x02080000, 0x00000000, 0x40080000, 0x42000000,
00157 0x00080100, 0x02000100, 0x40000100, 0x00080000,
00158 0x00000000, 0x40080000, 0x02080100, 0x40000100
00159 };
00160
00161 static const unsigned long SB6[64] =
00162 {
00163 0x20000010, 0x20400000, 0x00004000, 0x20404010,
00164 0x20400000, 0x00000010, 0x20404010, 0x00400000,
00165 0x20004000, 0x00404010, 0x00400000, 0x20000010,
00166 0x00400010, 0x20004000, 0x20000000, 0x00004010,
00167 0x00000000, 0x00400010, 0x20004010, 0x00004000,
00168 0x00404000, 0x20004010, 0x00000010, 0x20400010,
00169 0x20400010, 0x00000000, 0x00404010, 0x20404000,
00170 0x00004010, 0x00404000, 0x20404000, 0x20000000,
00171 0x20004000, 0x00000010, 0x20400010, 0x00404000,
00172 0x20404010, 0x00400000, 0x00004010, 0x20000010,
00173 0x00400000, 0x20004000, 0x20000000, 0x00004010,
00174 0x20000010, 0x20404010, 0x00404000, 0x20400000,
00175 0x00404010, 0x20404000, 0x00000000, 0x20400010,
00176 0x00000010, 0x00004000, 0x20400000, 0x00404010,
00177 0x00004000, 0x00400010, 0x20004010, 0x00000000,
00178 0x20404000, 0x20000000, 0x00400010, 0x20004010
00179 };
00180
00181 static const unsigned long SB7[64] =
00182 {
00183 0x00200000, 0x04200002, 0x04000802, 0x00000000,
00184 0x00000800, 0x04000802, 0x00200802, 0x04200800,
00185 0x04200802, 0x00200000, 0x00000000, 0x04000002,
00186 0x00000002, 0x04000000, 0x04200002, 0x00000802,
00187 0x04000800, 0x00200802, 0x00200002, 0x04000800,
00188 0x04000002, 0x04200000, 0x04200800, 0x00200002,
00189 0x04200000, 0x00000800, 0x00000802, 0x04200802,
00190 0x00200800, 0x00000002, 0x04000000, 0x00200800,
00191 0x04000000, 0x00200800, 0x00200000, 0x04000802,
00192 0x04000802, 0x04200002, 0x04200002, 0x00000002,
00193 0x00200002, 0x04000000, 0x04000800, 0x00200000,
00194 0x04200800, 0x00000802, 0x00200802, 0x04200800,
00195 0x00000802, 0x04000002, 0x04200802, 0x04200000,
00196 0x00200800, 0x00000000, 0x00000002, 0x04200802,
00197 0x00000000, 0x00200802, 0x04200000, 0x00000800,
00198 0x04000002, 0x04000800, 0x00000800, 0x00200002
00199 };
00200
00201 static const unsigned long SB8[64] =
00202 {
00203 0x10001040, 0x00001000, 0x00040000, 0x10041040,
00204 0x10000000, 0x10001040, 0x00000040, 0x10000000,
00205 0x00040040, 0x10040000, 0x10041040, 0x00041000,
00206 0x10041000, 0x00041040, 0x00001000, 0x00000040,
00207 0x10040000, 0x10000040, 0x10001000, 0x00001040,
00208 0x00041000, 0x00040040, 0x10040040, 0x10041000,
00209 0x00001040, 0x00000000, 0x00000000, 0x10040040,
00210 0x10000040, 0x10001000, 0x00041040, 0x00040000,
00211 0x00041040, 0x00040000, 0x10041000, 0x00001000,
00212 0x00000040, 0x10040040, 0x00001000, 0x00041040,
00213 0x10001000, 0x00000040, 0x10000040, 0x10040000,
00214 0x10040040, 0x10000000, 0x00040000, 0x10001040,
00215 0x00000000, 0x10041040, 0x00040040, 0x10000040,
00216 0x10040000, 0x10001000, 0x10001040, 0x00000000,
00217 0x10041040, 0x00041000, 0x00041000, 0x00001040,
00218 0x00001040, 0x00040040, 0x10000000, 0x10041000
00219 };
00220
00221
00222
00223
00224 static const unsigned long LHs[16] =
00225 {
00226 0x00000000, 0x00000001, 0x00000100, 0x00000101,
00227 0x00010000, 0x00010001, 0x00010100, 0x00010101,
00228 0x01000000, 0x01000001, 0x01000100, 0x01000101,
00229 0x01010000, 0x01010001, 0x01010100, 0x01010101
00230 };
00231
00232 static const unsigned long RHs[16] =
00233 {
00234 0x00000000, 0x01000000, 0x00010000, 0x01010000,
00235 0x00000100, 0x01000100, 0x00010100, 0x01010100,
00236 0x00000001, 0x01000001, 0x00010001, 0x01010001,
00237 0x00000101, 0x01000101, 0x00010101, 0x01010101,
00238 };
00239
00240
00241
00242
00243 #define DES_IP(X,Y) \
00244 { \
00245 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
00246 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
00247 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
00248 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
00249 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
00250 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
00251 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
00252 }
00253
00254
00255
00256
00257 #define DES_FP(X,Y) \
00258 { \
00259 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
00260 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
00261 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
00262 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
00263 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
00264 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
00265 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
00266 }
00267
00268
00269
00270
00271 #define DES_ROUND(X,Y) \
00272 { \
00273 T = *SK++ ^ X; \
00274 Y ^= SB8[ (T ) & 0x3F ] ^ \
00275 SB6[ (T >> 8) & 0x3F ] ^ \
00276 SB4[ (T >> 16) & 0x3F ] ^ \
00277 SB2[ (T >> 24) & 0x3F ]; \
00278 \
00279 T = *SK++ ^ ((X << 28) | (X >> 4)); \
00280 Y ^= SB7[ (T ) & 0x3F ] ^ \
00281 SB5[ (T >> 8) & 0x3F ] ^ \
00282 SB3[ (T >> 16) & 0x3F ] ^ \
00283 SB1[ (T >> 24) & 0x3F ]; \
00284 }
00285
00286 #define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
00287
00288 static void des_setkey( unsigned long SK[32], unsigned char key[8] )
00289 {
00290 int i;
00291 unsigned long X, Y, T;
00292
00293 GET_ULONG_BE( X, key, 0 );
00294 GET_ULONG_BE( Y, key, 4 );
00295
00296
00297
00298
00299 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
00300 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
00301
00302 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
00303 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
00304 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
00305 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
00306
00307 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
00308 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
00309 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
00310 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
00311
00312 X &= 0x0FFFFFFF;
00313 Y &= 0x0FFFFFFF;
00314
00315
00316
00317
00318 for( i = 0; i < 16; i++ )
00319 {
00320 if( i < 2 || i == 8 || i == 15 )
00321 {
00322 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
00323 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
00324 }
00325 else
00326 {
00327 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
00328 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
00329 }
00330
00331 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
00332 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
00333 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
00334 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
00335 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
00336 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
00337 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
00338 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
00339 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
00340 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
00341 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
00342
00343 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
00344 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
00345 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
00346 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
00347 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
00348 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
00349 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
00350 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
00351 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
00352 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
00353 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
00354 }
00355 }
00356
00357
00358
00359
00360 void des_setkey_enc( des_context *ctx, unsigned char key[8] )
00361 {
00362 des_setkey( ctx->sk, key );
00363 }
00364
00365
00366
00367
00368 void des_setkey_dec( des_context *ctx, unsigned char key[8] )
00369 {
00370 int i;
00371
00372 des_setkey( ctx->sk, key );
00373
00374 for( i = 0; i < 16; i += 2 )
00375 {
00376 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
00377 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
00378 }
00379 }
00380
00381 static void des3_set2key( unsigned long esk[96],
00382 unsigned long dsk[96],
00383 unsigned char key[16] )
00384 {
00385 int i;
00386
00387 des_setkey( esk, key );
00388 des_setkey( dsk + 32, key + 8 );
00389
00390 for( i = 0; i < 32; i += 2 )
00391 {
00392 dsk[i ] = esk[30 - i];
00393 dsk[i + 1] = esk[31 - i];
00394
00395 esk[i + 32] = dsk[62 - i];
00396 esk[i + 33] = dsk[63 - i];
00397
00398 esk[i + 64] = esk[i ];
00399 esk[i + 65] = esk[i + 1];
00400
00401 dsk[i + 64] = dsk[i ];
00402 dsk[i + 65] = dsk[i + 1];
00403 }
00404 }
00405
00406
00407
00408
00409 void des3_set2key_enc( des3_context *ctx, unsigned char key[16] )
00410 {
00411 unsigned long sk[96];
00412
00413 des3_set2key( ctx->sk, sk, key );
00414 memset( sk, 0, sizeof( sk ) );
00415 }
00416
00417
00418
00419
00420 void des3_set2key_dec( des3_context *ctx, unsigned char key[16] )
00421 {
00422 unsigned long sk[96];
00423
00424 des3_set2key( sk, ctx->sk, key );
00425 memset( sk, 0, sizeof( sk ) );
00426 }
00427
00428 static void des3_set3key( unsigned long esk[96],
00429 unsigned long dsk[96],
00430 unsigned char key[24] )
00431 {
00432 int i;
00433
00434 des_setkey( esk, key );
00435 des_setkey( dsk + 32, key + 8 );
00436 des_setkey( esk + 64, key + 16 );
00437
00438 for( i = 0; i < 32; i += 2 )
00439 {
00440 dsk[i ] = esk[94 - i];
00441 dsk[i + 1] = esk[95 - i];
00442
00443 esk[i + 32] = dsk[62 - i];
00444 esk[i + 33] = dsk[63 - i];
00445
00446 dsk[i + 64] = esk[30 - i];
00447 dsk[i + 65] = esk[31 - i];
00448 }
00449 }
00450
00451
00452
00453
00454 void des3_set3key_enc( des3_context *ctx, unsigned char key[24] )
00455 {
00456 unsigned long sk[96];
00457
00458 des3_set3key( ctx->sk, sk, key );
00459 memset( sk, 0, sizeof( sk ) );
00460 }
00461
00462
00463
00464
00465 void des3_set3key_dec( des3_context *ctx, unsigned char key[24] )
00466 {
00467 unsigned long sk[96];
00468
00469 des3_set3key( sk, ctx->sk, key );
00470 memset( sk, 0, sizeof( sk ) );
00471 }
00472
00473
00474
00475
00476 void des_crypt_ecb( des_context *ctx,
00477 unsigned char input[8],
00478 unsigned char output[8] )
00479 {
00480 int i;
00481 unsigned long X, Y, T, *SK;
00482
00483 SK = ctx->sk;
00484
00485 GET_ULONG_BE( X, input, 0 );
00486 GET_ULONG_BE( Y, input, 4 );
00487
00488 DES_IP( X, Y );
00489
00490 for( i = 0; i < 8; i++ )
00491 {
00492 DES_ROUND( Y, X );
00493 DES_ROUND( X, Y );
00494 }
00495
00496 DES_FP( Y, X );
00497
00498 PUT_ULONG_BE( Y, output, 0 );
00499 PUT_ULONG_BE( X, output, 4 );
00500 }
00501
00502
00503
00504
00505 void des_crypt_cbc( des_context *ctx,
00506 int mode,
00507 int length,
00508 unsigned char iv[8],
00509 unsigned char *input,
00510 unsigned char *output )
00511 {
00512 int i;
00513 unsigned char temp[8];
00514
00515 if( mode == DES_ENCRYPT )
00516 {
00517 while( length > 0 )
00518 {
00519 for( i = 0; i < 8; i++ )
00520 output[i] = (unsigned char)( input[i] ^ iv[i] );
00521
00522 des_crypt_ecb( ctx, output, output );
00523 memcpy( iv, output, 8 );
00524
00525 input += 8;
00526 output += 8;
00527 length -= 8;
00528 }
00529 }
00530 else
00531 {
00532 while( length > 0 )
00533 {
00534 memcpy( temp, input, 8 );
00535 des_crypt_ecb( ctx, input, output );
00536
00537 for( i = 0; i < 8; i++ )
00538 output[i] = (unsigned char)( output[i] ^ iv[i] );
00539
00540 memcpy( iv, temp, 8 );
00541
00542 input += 8;
00543 output += 8;
00544 length -= 8;
00545 }
00546 }
00547 }
00548
00549
00550
00551
00552 void des3_crypt_ecb( des3_context *ctx,
00553 unsigned char input[8],
00554 unsigned char output[8] )
00555 {
00556 int i;
00557 unsigned long X, Y, T, *SK;
00558
00559 SK = ctx->sk;
00560
00561 GET_ULONG_BE( X, input, 0 );
00562 GET_ULONG_BE( Y, input, 4 );
00563
00564 DES_IP( X, Y );
00565
00566 for( i = 0; i < 8; i++ )
00567 {
00568 DES_ROUND( Y, X );
00569 DES_ROUND( X, Y );
00570 }
00571
00572 for( i = 0; i < 8; i++ )
00573 {
00574 DES_ROUND( X, Y );
00575 DES_ROUND( Y, X );
00576 }
00577
00578 for( i = 0; i < 8; i++ )
00579 {
00580 DES_ROUND( Y, X );
00581 DES_ROUND( X, Y );
00582 }
00583
00584 DES_FP( Y, X );
00585
00586 PUT_ULONG_BE( Y, output, 0 );
00587 PUT_ULONG_BE( X, output, 4 );
00588 }
00589
00590
00591
00592
00593 void des3_crypt_cbc( des3_context *ctx,
00594 int mode,
00595 int length,
00596 unsigned char iv[8],
00597 unsigned char *input,
00598 unsigned char *output )
00599 {
00600 int i;
00601 unsigned char temp[8];
00602
00603 if( mode == DES_ENCRYPT )
00604 {
00605 while( length > 0 )
00606 {
00607 for( i = 0; i < 8; i++ )
00608 output[i] = (unsigned char)( input[i] ^ iv[i] );
00609
00610 des3_crypt_ecb( ctx, output, output );
00611 memcpy( iv, output, 8 );
00612
00613 input += 8;
00614 output += 8;
00615 length -= 8;
00616 }
00617 }
00618 else
00619 {
00620 while( length > 0 )
00621 {
00622 memcpy( temp, input, 8 );
00623 des3_crypt_ecb( ctx, input, output );
00624
00625 for( i = 0; i < 8; i++ )
00626 output[i] = (unsigned char)( output[i] ^ iv[i] );
00627
00628 memcpy( iv, temp, 8 );
00629
00630 input += 8;
00631 output += 8;
00632 length -= 8;
00633 }
00634 }
00635 }
00636
00637 #if defined(XYSSL_SELF_TEST)
00638
00639 #include <stdio.h>
00640
00641
00642
00643
00644
00645
00646 static const unsigned char des3_test_keys[24] =
00647 {
00648 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
00649 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
00650 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
00651 };
00652
00653 static const unsigned char des3_test_iv[8] =
00654 {
00655 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
00656 };
00657
00658 static const unsigned char des3_test_buf[8] =
00659 {
00660 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
00661 };
00662
00663 static const unsigned char des3_test_ecb_dec[3][8] =
00664 {
00665 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
00666 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
00667 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
00668 };
00669
00670 static const unsigned char des3_test_ecb_enc[3][8] =
00671 {
00672 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
00673 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
00674 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
00675 };
00676
00677 static const unsigned char des3_test_cbc_dec[3][8] =
00678 {
00679 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
00680 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
00681 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
00682 };
00683
00684 static const unsigned char des3_test_cbc_enc[3][8] =
00685 {
00686 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
00687 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
00688 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
00689 };
00690
00691
00692
00693
00694 int des_self_test( int verbose )
00695 {
00696 int i, j, u, v;
00697 des_context ctx;
00698 des3_context ctx3;
00699 unsigned char key[24];
00700 unsigned char buf[8];
00701 unsigned char prv[8];
00702 unsigned char iv[8];
00703
00704 memset( key, 0, 24 );
00705
00706
00707
00708
00709 for( i = 0; i < 6; i++ )
00710 {
00711 u = i >> 1;
00712 v = i & 1;
00713
00714 if( verbose != 0 )
00715 printf( " DES%c-ECB-%3d (%s): ",
00716 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
00717 ( v == DES_DECRYPT ) ? "dec" : "enc" );
00718
00719 memcpy( buf, des3_test_buf, 8 );
00720
00721 switch( i )
00722 {
00723 case 0:
00724 des_setkey_dec( &ctx, (unsigned char *) des3_test_keys );
00725 break;
00726
00727 case 1:
00728 des_setkey_enc( &ctx, (unsigned char *) des3_test_keys );
00729 break;
00730
00731 case 2:
00732 des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys );
00733 break;
00734
00735 case 3:
00736 des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys );
00737 break;
00738
00739 case 4:
00740 des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys );
00741 break;
00742
00743 case 5:
00744 des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys );
00745 break;
00746
00747 default:
00748 return( 1 );
00749 }
00750
00751 for( j = 0; j < 10000; j++ )
00752 {
00753 if( u == 0 )
00754 des_crypt_ecb( &ctx, buf, buf );
00755 else
00756 des3_crypt_ecb( &ctx3, buf, buf );
00757 }
00758
00759 if( ( v == DES_DECRYPT &&
00760 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
00761 ( v != DES_DECRYPT &&
00762 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
00763 {
00764 if( verbose != 0 )
00765 printf( "failed\n" );
00766
00767 return( 1 );
00768 }
00769
00770 if( verbose != 0 )
00771 printf( "passed\n" );
00772 }
00773
00774 if( verbose != 0 )
00775 printf( "\n" );
00776
00777
00778
00779
00780 for( i = 0; i < 6; i++ )
00781 {
00782 u = i >> 1;
00783 v = i & 1;
00784
00785 if( verbose != 0 )
00786 printf( " DES%c-CBC-%3d (%s): ",
00787 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
00788 ( v == DES_DECRYPT ) ? "dec" : "enc" );
00789
00790 memcpy( iv, des3_test_iv, 8 );
00791 memcpy( prv, des3_test_iv, 8 );
00792 memcpy( buf, des3_test_buf, 8 );
00793
00794 switch( i )
00795 {
00796 case 0:
00797 des_setkey_dec( &ctx, (unsigned char *) des3_test_keys );
00798 break;
00799
00800 case 1:
00801 des_setkey_enc( &ctx, (unsigned char *) des3_test_keys );
00802 break;
00803
00804 case 2:
00805 des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys );
00806 break;
00807
00808 case 3:
00809 des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys );
00810 break;
00811
00812 case 4:
00813 des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys );
00814 break;
00815
00816 case 5:
00817 des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys );
00818 break;
00819
00820 default:
00821 return( 1 );
00822 }
00823
00824 if( v == DES_DECRYPT )
00825 {
00826 for( j = 0; j < 10000; j++ )
00827 {
00828 if( u == 0 )
00829 des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
00830 else
00831 des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
00832 }
00833 }
00834 else
00835 {
00836 for( j = 0; j < 10000; j++ )
00837 {
00838 unsigned char tmp[8];
00839
00840 if( u == 0 )
00841 des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
00842 else
00843 des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
00844
00845 memcpy( tmp, prv, 8 );
00846 memcpy( prv, buf, 8 );
00847 memcpy( buf, tmp, 8 );
00848 }
00849
00850 memcpy( buf, prv, 8 );
00851 }
00852
00853 if( ( v == DES_DECRYPT &&
00854 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
00855 ( v != DES_DECRYPT &&
00856 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
00857 {
00858 if( verbose != 0 )
00859 printf( "failed\n" );
00860
00861 return( 1 );
00862 }
00863
00864 if( verbose != 0 )
00865 printf( "passed\n" );
00866 }
00867
00868 if( verbose != 0 )
00869 printf( "\n" );
00870
00871 return( 0 );
00872 }
00873
00874 #endif
00875
00876 #endif