/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/security/xyssl-0.9/library/des.c

Go to the documentation of this file.
00001 /*
00002  *  FIPS-46-3 compliant Triple-DES implementation
00003  *
00004  *  Copyright (C) 2006-2007  Christophe Devine
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 /*
00021  *  DES, on which TDES is based, was originally designed by Hans Feistel
00022  *  at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
00023  *
00024  *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
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  * 32-bit integer manipulation macros (big endian)
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  * Expanded DES S-boxes
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  * PC1: left and right halves bit-swap
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  * Initial Permutation macro
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  * Final Permutation macro
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  * DES round macro
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      * Permuted Choice 1
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      * calculate subkeys
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  * DES key schedule (56-bit, encryption)
00359  */
00360 void des_setkey_enc( des_context *ctx, unsigned char key[8] )
00361 {
00362     des_setkey( ctx->sk, key );
00363 }
00364 
00365 /*
00366  * DES key schedule (56-bit, decryption)
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  * Triple-DES key schedule (112-bit, encryption)
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  * Triple-DES key schedule (112-bit, decryption)
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  * Triple-DES key schedule (168-bit, encryption)
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  * Triple-DES key schedule (168-bit, decryption)
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  * DES-ECB block encryption/decryption
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  * DES-CBC buffer encryption/decryption
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 /* DES_DECRYPT */
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  * 3DES-ECB block encryption/decryption
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  * 3DES-CBC buffer encryption/decryption
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 /* DES_DECRYPT */
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  * DES and 3DES test vectors from:
00643  *
00644  * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
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  * Checkup routine
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      * ECB mode
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      * CBC mode
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

Generated on Fri Jul 11 17:59:46 2008 for Mobile-C by  doxygen 1.5.4