/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/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 library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License, version 2.1 as published by the Free Software Foundation.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Lesser General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Lesser General Public
00016  *  License along with this library; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  *  MA  02110-1301  USA
00019  */
00020 /*
00021  *  DES, on which TDES is based, was originally designed by IBM in
00022  *  1974 and adopted as a standard by NIST (formerly NBS).
00023  *
00024  *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
00025  */
00026 
00027 #ifndef _CRT_SECURE_NO_DEPRECATE
00028 #define _CRT_SECURE_NO_DEPRECATE 1
00029 #endif
00030 
00031 #include <string.h>
00032 
00033 #include "xyssl/des.h"
00034 
00035 /*
00036  * 32-bit integer manipulation macros (big endian)
00037  */
00038 #ifndef GET_UINT32_BE
00039 #define GET_UINT32_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 #ifndef PUT_UINT32_BE
00048 #define PUT_UINT32_BE(n,b,i)                            \
00049 {                                                       \
00050     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
00051     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
00052     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
00053     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
00054 }
00055 #endif
00056 
00057 /*
00058  * Expanded DES S-boxes
00059  */
00060 static const unsigned long SB1[64] =
00061 {
00062     0x01010400, 0x00000000, 0x00010000, 0x01010404,
00063     0x01010004, 0x00010404, 0x00000004, 0x00010000,
00064     0x00000400, 0x01010400, 0x01010404, 0x00000400,
00065     0x01000404, 0x01010004, 0x01000000, 0x00000004,
00066     0x00000404, 0x01000400, 0x01000400, 0x00010400,
00067     0x00010400, 0x01010000, 0x01010000, 0x01000404,
00068     0x00010004, 0x01000004, 0x01000004, 0x00010004,
00069     0x00000000, 0x00000404, 0x00010404, 0x01000000,
00070     0x00010000, 0x01010404, 0x00000004, 0x01010000,
00071     0x01010400, 0x01000000, 0x01000000, 0x00000400,
00072     0x01010004, 0x00010000, 0x00010400, 0x01000004,
00073     0x00000400, 0x00000004, 0x01000404, 0x00010404,
00074     0x01010404, 0x00010004, 0x01010000, 0x01000404,
00075     0x01000004, 0x00000404, 0x00010404, 0x01010400,
00076     0x00000404, 0x01000400, 0x01000400, 0x00000000,
00077     0x00010004, 0x00010400, 0x00000000, 0x01010004
00078 };
00079 
00080 static const unsigned long SB2[64] =
00081 {
00082     0x80108020, 0x80008000, 0x00008000, 0x00108020,
00083     0x00100000, 0x00000020, 0x80100020, 0x80008020,
00084     0x80000020, 0x80108020, 0x80108000, 0x80000000,
00085     0x80008000, 0x00100000, 0x00000020, 0x80100020,
00086     0x00108000, 0x00100020, 0x80008020, 0x00000000,
00087     0x80000000, 0x00008000, 0x00108020, 0x80100000,
00088     0x00100020, 0x80000020, 0x00000000, 0x00108000,
00089     0x00008020, 0x80108000, 0x80100000, 0x00008020,
00090     0x00000000, 0x00108020, 0x80100020, 0x00100000,
00091     0x80008020, 0x80100000, 0x80108000, 0x00008000,
00092     0x80100000, 0x80008000, 0x00000020, 0x80108020,
00093     0x00108020, 0x00000020, 0x00008000, 0x80000000,
00094     0x00008020, 0x80108000, 0x00100000, 0x80000020,
00095     0x00100020, 0x80008020, 0x80000020, 0x00100020,
00096     0x00108000, 0x00000000, 0x80008000, 0x00008020,
00097     0x80000000, 0x80100020, 0x80108020, 0x00108000
00098 };
00099 
00100 static const unsigned long SB3[64] =
00101 {
00102     0x00000208, 0x08020200, 0x00000000, 0x08020008,
00103     0x08000200, 0x00000000, 0x00020208, 0x08000200,
00104     0x00020008, 0x08000008, 0x08000008, 0x00020000,
00105     0x08020208, 0x00020008, 0x08020000, 0x00000208,
00106     0x08000000, 0x00000008, 0x08020200, 0x00000200,
00107     0x00020200, 0x08020000, 0x08020008, 0x00020208,
00108     0x08000208, 0x00020200, 0x00020000, 0x08000208,
00109     0x00000008, 0x08020208, 0x00000200, 0x08000000,
00110     0x08020200, 0x08000000, 0x00020008, 0x00000208,
00111     0x00020000, 0x08020200, 0x08000200, 0x00000000,
00112     0x00000200, 0x00020008, 0x08020208, 0x08000200,
00113     0x08000008, 0x00000200, 0x00000000, 0x08020008,
00114     0x08000208, 0x00020000, 0x08000000, 0x08020208,
00115     0x00000008, 0x00020208, 0x00020200, 0x08000008,
00116     0x08020000, 0x08000208, 0x00000208, 0x08020000,
00117     0x00020208, 0x00000008, 0x08020008, 0x00020200
00118 };
00119 
00120 static const unsigned long SB4[64] =
00121 {
00122     0x00802001, 0x00002081, 0x00002081, 0x00000080,
00123     0x00802080, 0x00800081, 0x00800001, 0x00002001,
00124     0x00000000, 0x00802000, 0x00802000, 0x00802081,
00125     0x00000081, 0x00000000, 0x00800080, 0x00800001,
00126     0x00000001, 0x00002000, 0x00800000, 0x00802001,
00127     0x00000080, 0x00800000, 0x00002001, 0x00002080,
00128     0x00800081, 0x00000001, 0x00002080, 0x00800080,
00129     0x00002000, 0x00802080, 0x00802081, 0x00000081,
00130     0x00800080, 0x00800001, 0x00802000, 0x00802081,
00131     0x00000081, 0x00000000, 0x00000000, 0x00802000,
00132     0x00002080, 0x00800080, 0x00800081, 0x00000001,
00133     0x00802001, 0x00002081, 0x00002081, 0x00000080,
00134     0x00802081, 0x00000081, 0x00000001, 0x00002000,
00135     0x00800001, 0x00002001, 0x00802080, 0x00800081,
00136     0x00002001, 0x00002080, 0x00800000, 0x00802001,
00137     0x00000080, 0x00800000, 0x00002000, 0x00802080
00138 };
00139 
00140 static const unsigned long SB5[64] =
00141 {
00142     0x00000100, 0x02080100, 0x02080000, 0x42000100,
00143     0x00080000, 0x00000100, 0x40000000, 0x02080000,
00144     0x40080100, 0x00080000, 0x02000100, 0x40080100,
00145     0x42000100, 0x42080000, 0x00080100, 0x40000000,
00146     0x02000000, 0x40080000, 0x40080000, 0x00000000,
00147     0x40000100, 0x42080100, 0x42080100, 0x02000100,
00148     0x42080000, 0x40000100, 0x00000000, 0x42000000,
00149     0x02080100, 0x02000000, 0x42000000, 0x00080100,
00150     0x00080000, 0x42000100, 0x00000100, 0x02000000,
00151     0x40000000, 0x02080000, 0x42000100, 0x40080100,
00152     0x02000100, 0x40000000, 0x42080000, 0x02080100,
00153     0x40080100, 0x00000100, 0x02000000, 0x42080000,
00154     0x42080100, 0x00080100, 0x42000000, 0x42080100,
00155     0x02080000, 0x00000000, 0x40080000, 0x42000000,
00156     0x00080100, 0x02000100, 0x40000100, 0x00080000,
00157     0x00000000, 0x40080000, 0x02080100, 0x40000100
00158 };
00159 
00160 static const unsigned long SB6[64] =
00161 {
00162     0x20000010, 0x20400000, 0x00004000, 0x20404010,
00163     0x20400000, 0x00000010, 0x20404010, 0x00400000,
00164     0x20004000, 0x00404010, 0x00400000, 0x20000010,
00165     0x00400010, 0x20004000, 0x20000000, 0x00004010,
00166     0x00000000, 0x00400010, 0x20004010, 0x00004000,
00167     0x00404000, 0x20004010, 0x00000010, 0x20400010,
00168     0x20400010, 0x00000000, 0x00404010, 0x20404000,
00169     0x00004010, 0x00404000, 0x20404000, 0x20000000,
00170     0x20004000, 0x00000010, 0x20400010, 0x00404000,
00171     0x20404010, 0x00400000, 0x00004010, 0x20000010,
00172     0x00400000, 0x20004000, 0x20000000, 0x00004010,
00173     0x20000010, 0x20404010, 0x00404000, 0x20400000,
00174     0x00404010, 0x20404000, 0x00000000, 0x20400010,
00175     0x00000010, 0x00004000, 0x20400000, 0x00404010,
00176     0x00004000, 0x00400010, 0x20004010, 0x00000000,
00177     0x20404000, 0x20000000, 0x00400010, 0x20004010
00178 };
00179 
00180 static const unsigned long SB7[64] =
00181 {
00182     0x00200000, 0x04200002, 0x04000802, 0x00000000,
00183     0x00000800, 0x04000802, 0x00200802, 0x04200800,
00184     0x04200802, 0x00200000, 0x00000000, 0x04000002,
00185     0x00000002, 0x04000000, 0x04200002, 0x00000802,
00186     0x04000800, 0x00200802, 0x00200002, 0x04000800,
00187     0x04000002, 0x04200000, 0x04200800, 0x00200002,
00188     0x04200000, 0x00000800, 0x00000802, 0x04200802,
00189     0x00200800, 0x00000002, 0x04000000, 0x00200800,
00190     0x04000000, 0x00200800, 0x00200000, 0x04000802,
00191     0x04000802, 0x04200002, 0x04200002, 0x00000002,
00192     0x00200002, 0x04000000, 0x04000800, 0x00200000,
00193     0x04200800, 0x00000802, 0x00200802, 0x04200800,
00194     0x00000802, 0x04000002, 0x04200802, 0x04200000,
00195     0x00200800, 0x00000000, 0x00000002, 0x04200802,
00196     0x00000000, 0x00200802, 0x04200000, 0x00000800,
00197     0x04000002, 0x04000800, 0x00000800, 0x00200002
00198 };
00199 
00200 static const unsigned long SB8[64] =
00201 {
00202     0x10001040, 0x00001000, 0x00040000, 0x10041040,
00203     0x10000000, 0x10001040, 0x00000040, 0x10000000,
00204     0x00040040, 0x10040000, 0x10041040, 0x00041000,
00205     0x10041000, 0x00041040, 0x00001000, 0x00000040,
00206     0x10040000, 0x10000040, 0x10001000, 0x00001040,
00207     0x00041000, 0x00040040, 0x10040040, 0x10041000,
00208     0x00001040, 0x00000000, 0x00000000, 0x10040040,
00209     0x10000040, 0x10001000, 0x00041040, 0x00040000,
00210     0x00041040, 0x00040000, 0x10041000, 0x00001000,
00211     0x00000040, 0x10040040, 0x00001000, 0x00041040,
00212     0x10001000, 0x00000040, 0x10000040, 0x10040000,
00213     0x10040040, 0x10000000, 0x00040000, 0x10001040,
00214     0x00000000, 0x10041040, 0x00040040, 0x10000040,
00215     0x10040000, 0x10001000, 0x10001040, 0x00000000,
00216     0x10041040, 0x00041000, 0x00041000, 0x00001040,
00217     0x00001040, 0x00040040, 0x10000000, 0x10041000
00218 };
00219 
00220 /*
00221  * PC1: left and right halves bit-swap
00222  */
00223 static const unsigned long LHs[16] =
00224 {
00225     0x00000000, 0x00000001, 0x00000100, 0x00000101,
00226     0x00010000, 0x00010001, 0x00010100, 0x00010101,
00227     0x01000000, 0x01000001, 0x01000100, 0x01000101,
00228     0x01010000, 0x01010001, 0x01010100, 0x01010101
00229 };
00230 
00231 static const unsigned long RHs[16] =
00232 {
00233     0x00000000, 0x01000000, 0x00010000, 0x01010000,
00234     0x00000100, 0x01000100, 0x00010100, 0x01010100,
00235     0x00000001, 0x01000001, 0x00010001, 0x01010001,
00236     0x00000101, 0x01000101, 0x00010101, 0x01010101,
00237 };
00238 
00239 /*
00240  * Initial Permutation macro
00241  */
00242 #define DES_IP(X,Y)                                             \
00243 {                                                               \
00244     T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
00245     T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
00246     T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
00247     T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
00248     Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF;                    \
00249     T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T;                   \
00250     X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF;                    \
00251 }
00252 
00253 /*
00254  * Final Permutation macro
00255  */
00256 #define DES_FP(X,Y)                                             \
00257 {                                                               \
00258     X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF;                    \
00259     T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T;                   \
00260     Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF;                    \
00261     T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
00262     T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
00263     T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
00264     T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
00265 }
00266 
00267 /*
00268  * DES round macro
00269  */
00270 #define DES_ROUND(X,Y)                          \
00271 {                                               \
00272     T = *SK++ ^ X;                              \
00273     Y ^= SB8[ (T      ) & 0x3F ] ^              \
00274          SB6[ (T >>  8) & 0x3F ] ^              \
00275          SB4[ (T >> 16) & 0x3F ] ^              \
00276          SB2[ (T >> 24) & 0x3F ];               \
00277                                                 \
00278     T = *SK++ ^ ((X << 28) | (X >> 4));         \
00279     Y ^= SB7[ (T      ) & 0x3F ] ^              \
00280          SB5[ (T >>  8) & 0x3F ] ^              \
00281          SB3[ (T >> 16) & 0x3F ] ^              \
00282          SB1[ (T >> 24) & 0x3F ];               \
00283 }
00284 
00285 static void des_main_ks( unsigned long SK[32], unsigned char key[8] )
00286 {
00287     int i;
00288     unsigned long X, Y, T;
00289 
00290     GET_UINT32_BE( X, key, 0 );
00291     GET_UINT32_BE( Y, key, 4 );
00292 
00293     /*
00294      * Permuted Choice 1
00295      */
00296     T =  ((Y >>  4) ^ X) & 0x0F0F0F0F;  X ^= T; Y ^= (T <<  4);
00297     T =  ((Y      ) ^ X) & 0x10101010;  X ^= T; Y ^= (T      );
00298 
00299     X =   (LHs[ (X      ) & 0xF] << 3) | (LHs[ (X >>  8) & 0xF ] << 2)
00300         | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ]     )
00301         | (LHs[ (X >>  5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
00302         | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
00303 
00304     Y =   (RHs[ (Y >>  1) & 0xF] << 3) | (RHs[ (Y >>  9) & 0xF ] << 2)
00305         | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ]     )
00306         | (RHs[ (Y >>  4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
00307         | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
00308 
00309     X &= 0x0FFFFFFF;
00310     Y &= 0x0FFFFFFF;
00311 
00312     /*
00313      * calculate subkeys
00314      */
00315     for( i = 0; i < 16; i++ )
00316     {
00317         if( i < 2 || i == 8 || i == 15 )
00318         {
00319             X = ((X <<  1) | (X >> 27)) & 0x0FFFFFFF;
00320             Y = ((Y <<  1) | (Y >> 27)) & 0x0FFFFFFF;
00321         }
00322         else
00323         {
00324             X = ((X <<  2) | (X >> 26)) & 0x0FFFFFFF;
00325             Y = ((Y <<  2) | (Y >> 26)) & 0x0FFFFFFF;
00326         }
00327 
00328         *SK++ =   ((X <<  4) & 0x24000000) | ((X << 28) & 0x10000000)
00329                 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
00330                 | ((X <<  6) & 0x01000000) | ((X <<  9) & 0x00200000)
00331                 | ((X >>  1) & 0x00100000) | ((X << 10) & 0x00040000)
00332                 | ((X <<  2) & 0x00020000) | ((X >> 10) & 0x00010000)
00333                 | ((Y >> 13) & 0x00002000) | ((Y >>  4) & 0x00001000)
00334                 | ((Y <<  6) & 0x00000800) | ((Y >>  1) & 0x00000400)
00335                 | ((Y >> 14) & 0x00000200) | ((Y      ) & 0x00000100)
00336                 | ((Y >>  5) & 0x00000020) | ((Y >> 10) & 0x00000010)
00337                 | ((Y >>  3) & 0x00000008) | ((Y >> 18) & 0x00000004)
00338                 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
00339 
00340         *SK++ =   ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
00341                 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
00342                 | ((X >>  2) & 0x02000000) | ((X <<  1) & 0x01000000)
00343                 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
00344                 | ((X <<  3) & 0x00080000) | ((X >>  6) & 0x00040000)
00345                 | ((X << 15) & 0x00020000) | ((X >>  4) & 0x00010000)
00346                 | ((Y >>  2) & 0x00002000) | ((Y <<  8) & 0x00001000)
00347                 | ((Y >> 14) & 0x00000808) | ((Y >>  9) & 0x00000400)
00348                 | ((Y      ) & 0x00000200) | ((Y <<  7) & 0x00000100)
00349                 | ((Y >>  7) & 0x00000020) | ((Y >>  3) & 0x00000011)
00350                 | ((Y <<  2) & 0x00000004) | ((Y >> 21) & 0x00000002);
00351     }
00352 }
00353 
00354 /*
00355  * DES key schedule (56-bit)
00356  */
00357 void des_set_key( des_context *ctx, unsigned char key[8] )
00358 {
00359     int i;
00360 
00361     des_main_ks( ctx->esk, key );
00362 
00363     for( i = 0; i < 32; i += 2 )
00364     {
00365         ctx->dsk[i    ] = ctx->esk[30 - i];
00366         ctx->dsk[i + 1] = ctx->esk[31 - i];
00367     }
00368 }
00369 
00370 static void des_crypt( unsigned long SK[32],
00371                        unsigned char input[8],
00372                        unsigned char output[8] )
00373 {
00374     unsigned long X, Y, T;
00375 
00376     GET_UINT32_BE( X, input, 0 );
00377     GET_UINT32_BE( Y, input, 4 );
00378 
00379     DES_IP( X, Y );
00380 
00381     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00382     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00383     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00384     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00385     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00386     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00387     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00388     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00389 
00390     DES_FP( Y, X );
00391 
00392     PUT_UINT32_BE( Y, output, 0 );
00393     PUT_UINT32_BE( X, output, 4 );
00394 }
00395 
00396 /*
00397  * DES block encryption (ECB mode)
00398  */
00399 void des_encrypt( des_context *ctx,
00400                   unsigned char input[8],
00401                   unsigned char output[8] )
00402 {
00403     des_crypt( ctx->esk, input, output );
00404 }
00405 
00406 /*
00407  * DES block decryption (ECB mode)
00408  */
00409 void des_decrypt( des_context *ctx,
00410                   unsigned char input[8],
00411                   unsigned char output[8] )
00412 {
00413     des_crypt( ctx->dsk, input, output );
00414 }
00415 
00416 /*
00417  * DES-CBC buffer encryption
00418  */
00419 void des_cbc_encrypt( des_context *ctx,
00420                       unsigned char iv[8],
00421                       unsigned char *input,
00422                       unsigned char *output,
00423                       int len )
00424 {
00425     int i;
00426 
00427     while( len > 0 )
00428     {
00429         for( i = 0; i < 8; i++ )
00430             output[i] = input[i] ^ iv[i];
00431 
00432         des_crypt( ctx->esk, output, output );
00433         memcpy( iv, output, 8 );
00434 
00435         input  += 8;
00436         output += 8;
00437         len    -= 8;
00438     }
00439 }
00440 
00441 /*
00442  * DES-CBC buffer decryption
00443  */
00444 void des_cbc_decrypt( des_context *ctx,
00445                       unsigned char iv[8],
00446                       unsigned char *input,
00447                       unsigned char *output,
00448                       int len )
00449 {
00450     int i;
00451     unsigned char temp[8];
00452 
00453     while( len > 0 )
00454     {
00455         memcpy( temp, input, 8 );
00456         des_crypt( ctx->dsk, input, output );
00457 
00458         for( i = 0; i < 8; i++ )
00459             output[i] = output[i] ^ iv[i];
00460 
00461         memcpy( iv, temp, 8 );
00462 
00463         input  += 8;
00464         output += 8;
00465         len    -= 8;
00466     }
00467 }
00468 
00469 /*
00470  * Triple-DES key schedule (112-bit)
00471  */
00472 void des3_set_2keys( des3_context *ctx, unsigned char key[16] )
00473 {
00474     int i;
00475 
00476     des_main_ks( ctx->esk     , key     );
00477     des_main_ks( ctx->dsk + 32, key + 8 );
00478 
00479     for( i = 0; i < 32; i += 2 )
00480     {
00481         ctx->dsk[i     ] = ctx->esk[30 - i];
00482         ctx->dsk[i +  1] = ctx->esk[31 - i];
00483 
00484         ctx->esk[i + 32] = ctx->dsk[62 - i];
00485         ctx->esk[i + 33] = ctx->dsk[63 - i];
00486 
00487         ctx->esk[i + 64] = ctx->esk[     i];
00488         ctx->esk[i + 65] = ctx->esk[ 1 + i];
00489 
00490         ctx->dsk[i + 64] = ctx->dsk[     i];
00491         ctx->dsk[i + 65] = ctx->dsk[ 1 + i];
00492     }
00493 }
00494 
00495 /*
00496  * Triple-DES key schedule (168-bit)
00497  */
00498 void des3_set_3keys( des3_context *ctx, unsigned char key[24] )
00499 {
00500     int i;
00501 
00502     des_main_ks( ctx->esk     , key      );
00503     des_main_ks( ctx->dsk + 32, key +  8 );
00504     des_main_ks( ctx->esk + 64, key + 16 );
00505 
00506     for( i = 0; i < 32; i += 2 )
00507     {
00508         ctx->dsk[i     ] = ctx->esk[94 - i];
00509         ctx->dsk[i +  1] = ctx->esk[95 - i];
00510 
00511         ctx->esk[i + 32] = ctx->dsk[62 - i];
00512         ctx->esk[i + 33] = ctx->dsk[63 - i];
00513 
00514         ctx->dsk[i + 64] = ctx->esk[30 - i];
00515         ctx->dsk[i + 65] = ctx->esk[31 - i];
00516     }
00517 }
00518 
00519 static void des3_crypt( unsigned long SK[96],
00520                         unsigned char input[8],
00521                         unsigned char output[8] )
00522 {
00523     unsigned long X, Y, T;
00524 
00525     GET_UINT32_BE( X, input, 0 );
00526     GET_UINT32_BE( Y, input, 4 );
00527 
00528     DES_IP( X, Y );
00529 
00530     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00531     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00532     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00533     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00534     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00535     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00536     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00537     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00538 
00539     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00540     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00541     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00542     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00543     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00544     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00545     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00546     DES_ROUND( X, Y );  DES_ROUND( Y, X );
00547 
00548     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00549     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00550     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00551     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00552     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00553     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00554     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00555     DES_ROUND( Y, X );  DES_ROUND( X, Y );
00556 
00557     DES_FP( Y, X );
00558 
00559     PUT_UINT32_BE( Y, output, 0 );
00560     PUT_UINT32_BE( X, output, 4 );
00561 }
00562 
00563 /*
00564  * Triple-DES block encryption (ECB mode)
00565  */
00566 void des3_encrypt( des3_context *ctx,
00567                    unsigned char input[8],
00568                    unsigned char output[8] )
00569 {
00570     des3_crypt( ctx->esk, input, output );
00571 }
00572 
00573 /*
00574  * Triple-DES block decryption (ECB mode)
00575  */
00576 void des3_decrypt( des3_context *ctx,
00577                    unsigned char input[8],
00578                    unsigned char output[8] )
00579 {
00580     des3_crypt( ctx->dsk, input, output );
00581 }
00582 
00583 /*
00584  * 3DES-CBC buffer encryption
00585  */
00586 void des3_cbc_encrypt( des3_context *ctx,
00587                        unsigned char iv[8],
00588                        unsigned char *input,
00589                        unsigned char *output,
00590                        int len )
00591 {
00592     int i;
00593 
00594     while( len > 0 )
00595     {
00596         for( i = 0; i < 8; i++ )
00597             output[i] = input[i] ^ iv[i];
00598 
00599         des3_crypt( ctx->esk, output, output );
00600         memcpy( iv, output, 8 );
00601 
00602         input  += 8;
00603         output += 8;
00604         len    -= 8;
00605     }
00606 }
00607 
00608 /*
00609  * 3DES-CBC buffer decryption
00610  */
00611 void des3_cbc_decrypt( des3_context *ctx,
00612                        unsigned char iv[8],
00613                        unsigned char *input,
00614                        unsigned char *output,
00615                        int len )
00616 {
00617     int i;
00618     unsigned char temp[8];
00619 
00620     while( len > 0 )
00621     {
00622         memcpy( temp, input, 8 );
00623         des3_crypt( ctx->dsk, input, output );
00624 
00625         for( i = 0; i < 8; i++ )
00626             output[i] = output[i] ^ iv[i];
00627 
00628         memcpy( iv, temp, 8 );
00629 
00630         input  += 8;
00631         output += 8;
00632         len    -= 8;
00633     }
00634 }
00635 
00636 static const char _des_src[] = "_des_src";
00637 
00638 #if defined(SELF_TEST)
00639 
00640 #include <stdio.h>
00641 
00642 /*
00643  * DES/3DES test vectors (source: NIST, tripledes-vectors.zip)
00644  */
00645 static const unsigned char DES3_keys[24] =
00646 {
00647     0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
00648     0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
00649     0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
00650 };
00651 
00652 static const unsigned char DES3_init[8] =
00653 {
00654     0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
00655 };
00656 
00657 static const unsigned char DES3_enc_test[3][8] =
00658 {
00659     { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
00660     { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
00661     { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
00662 };
00663     
00664 static const unsigned char DES3_dec_test[3][8] =
00665 {
00666     { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
00667     { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
00668     { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
00669 };
00670 
00671 /*
00672  * Checkup routine
00673  */
00674 int des_self_test( int verbose )
00675 {
00676     int i, j, u, v;
00677     des_context ctx;
00678     des3_context ctx3;
00679     unsigned char buf[8];
00680 
00681     for( i = 0; i < 6; i++ )
00682     {
00683         u = i >> 1;
00684         v = i  & 1;
00685 
00686         if( verbose != 0 )
00687             printf( "  DES%c-EBC-%3d (%s): ",
00688                     ( u == 0 ) ? ' ' : '3', 64 + u * 64,
00689                     ( v == 0 ) ? "enc" : "dec" );
00690 
00691         memcpy( buf, DES3_init, 8 );
00692 
00693         if( u == 0 )
00694                des_set_key( &ctx,  (unsigned char *) DES3_keys );
00695 
00696         if( u == 1 )
00697             des3_set_2keys( &ctx3, (unsigned char *) DES3_keys );
00698 
00699         if( u == 2 )
00700             des3_set_3keys( &ctx3, (unsigned char *) DES3_keys );
00701 
00702         for( j = 0; j < 10000; j++ )
00703         {
00704             if( u == 0 )
00705             {
00706                 if( v == 0 ) des_encrypt( &ctx, buf, buf );
00707                 if( v == 1 ) des_decrypt( &ctx, buf, buf );
00708             }
00709             else
00710             {
00711                 if( v == 0 ) des3_encrypt( &ctx3, buf, buf );
00712                 if( v == 1 ) des3_decrypt( &ctx3, buf, buf );
00713             }
00714         }
00715 
00716         if( ( v == 0 && memcmp( buf, DES3_enc_test[u], 8 ) != 0 ) ||
00717             ( v == 1 && memcmp( buf, DES3_dec_test[u], 8 ) != 0 ) )
00718         {
00719             if( verbose != 0 )
00720                 printf( "failed\n" );
00721 
00722             return( 1 );
00723         }
00724 
00725         if( verbose != 0 )
00726             printf( "passed\n" );
00727     }
00728 
00729     if( verbose != 0 )
00730         printf( "\n" );
00731 
00732     return( 0 );
00733 }
00734 #else
00735 int des_self_test( int verbose )
00736 {
00737     return( 0 );
00738 }
00739 #endif

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4