/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/library/des.c

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

Generated on Tue Jul 1 15:29:59 2008 for Mobile-C by  doxygen 1.5.4