embedded IPsec source code documentation


des.c

Go to the documentation of this file.
00001 /*
00002  * embedded IPsec       
00003  * Copyright (c) 2003 Niklaus Schild and Christian Scheurer, HTI Biel/Bienne
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without modification,
00007  * are permitted provided that the following conditions are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright notice,
00010  *    this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright notice,
00012  *    this list of conditions and the following disclaimer in the documentation
00013  *    and/or other materials provided with the distribution.
00014  * 3. The name of the author may not be used to endorse or promote products
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00018  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00020  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00021  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00022  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00025  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00026  * OF SUCH DAMAGE.
00027  *
00028  */
00029 
00055 #include <string.h>
00056 
00057 #include "ipsec/des.h"
00058 #include "ipsec/debug.h"
00059 
00060 
00061 const DES_LONG DES_SPtrans[8][64]={
00062         {
00063         /* nibble 0 */
00064         0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
00065         0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
00066         0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
00067         0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
00068         0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
00069         0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
00070         0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
00071         0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
00072         0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
00073         0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
00074         0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
00075         0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
00076         0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
00077         0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
00078         0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
00079         0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
00080         },{
00081         /* nibble 1 */
00082         0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
00083         0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
00084         0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
00085         0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
00086         0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
00087         0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
00088         0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
00089         0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
00090         0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
00091         0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
00092         0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
00093         0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
00094         0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
00095         0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
00096         0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
00097         0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
00098         },{
00099         /* nibble 2 */
00100         0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
00101         0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
00102         0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
00103         0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
00104         0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
00105         0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
00106         0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
00107         0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
00108         0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
00109         0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
00110         0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
00111         0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
00112         0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
00113         0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
00114         0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
00115         0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
00116         },{
00117         /* nibble 3 */
00118         0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
00119         0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
00120         0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
00121         0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
00122         0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
00123         0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
00124         0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
00125         0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
00126         0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
00127         0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
00128         0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
00129         0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
00130         0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
00131         0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
00132         0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
00133         0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
00134         },{
00135         /* nibble 4 */
00136         0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
00137         0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
00138         0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
00139         0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
00140         0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
00141         0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
00142         0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
00143         0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
00144         0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
00145         0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
00146         0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
00147         0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
00148         0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
00149         0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
00150         0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
00151         0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
00152         },{
00153         /* nibble 5 */
00154         0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
00155         0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
00156         0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
00157         0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
00158         0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
00159         0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
00160         0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
00161         0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
00162         0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
00163         0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
00164         0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
00165         0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
00166         0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
00167         0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
00168         0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
00169         0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
00170         },{
00171         /* nibble 6 */
00172         0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
00173         0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
00174         0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
00175         0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
00176         0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
00177         0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
00178         0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
00179         0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
00180         0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
00181         0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
00182         0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
00183         0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
00184         0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
00185         0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
00186         0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
00187         0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
00188         },{
00189         /* nibble 7 */
00190         0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
00191         0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
00192         0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
00193         0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
00194         0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
00195         0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
00196         0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
00197         0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
00198         0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
00199         0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
00200         0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
00201         0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
00202         0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
00203         0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
00204         0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
00205         0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
00206         }};
00207 
00208 
00209 
00210 /* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
00211 void DES_cbc_encrypt(const unsigned char *input,unsigned char *output,
00212                      long length,DES_key_schedule *schedule,DES_cblock *ivec,
00213                      int enc);
00214 void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
00215                       long length,DES_key_schedule *schedule,DES_cblock *ivec,
00216                       int enc);
00217 void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc);
00218 void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc);
00219 
00220 void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
00221                   DES_key_schedule *ks2, DES_key_schedule *ks3);
00222 void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
00223                   DES_key_schedule *ks2, DES_key_schedule *ks3);
00224 void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output,
00225                           long length,
00226                           DES_key_schedule *ks1,DES_key_schedule *ks2,
00227                           DES_key_schedule *ks3,DES_cblock *ivec,int enc);
00228 void DES_set_odd_parity(DES_cblock *key);
00229 int DES_check_key_parity(const_DES_cblock *key);
00230 int DES_is_weak_key(const_DES_cblock *key);
00231 int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
00232 int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule);
00233 int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule);
00234 void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
00235 
00236 #define DES_KEY_SZ      (sizeof(DES_cblock))
00237 #define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
00238 
00239 
00240 #define ITERATIONS 16
00241 #define HALF_ITERATIONS 8
00242 
00243 
00244 /* char to long */
00245 #define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
00246                          l|=((DES_LONG)(*((c)++)))<< 8L, \
00247                          l|=((DES_LONG)(*((c)++)))<<16L, \
00248                          l|=((DES_LONG)(*((c)++)))<<24L)
00249 
00250 /* NOTE - c is not incremented as per c2l */
00251 
00252 /* char to long network order */
00253 #define c2ln(c,l1,l2,n) { \
00254                         c+=n; \
00255                         l1=l2=0; \
00256                         switch (n) { \
00257                         case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
00258                         case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
00259                         case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
00260                         case 5: l2|=((DES_LONG)(*(--(c))));     \
00261                         case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
00262                         case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
00263                         case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
00264                         case 1: l1|=((DES_LONG)(*(--(c))));     \
00265                                 } \
00266                         }
00267 
00268 
00269 /* long to char */
00270 #define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
00271                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
00272                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
00273                          *((c)++)=(unsigned char)(((l)>>24L)&0xff))
00274 
00275 /* replacements for htonl and ntohl since I have no idea what to do
00276  * when faced with machines with 8 byte longs. */
00277 #define HDRSIZE 4
00278 
00279 
00280 /* network to long */
00281 #define n2l(c,l)        (l =((DES_LONG)(*((c)++)))<<24L, \
00282                          l|=((DES_LONG)(*((c)++)))<<16L, \
00283                          l|=((DES_LONG)(*((c)++)))<< 8L, \
00284                          l|=((DES_LONG)(*((c)++))))
00285 
00286 
00287 /* long to network */
00288 #define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
00289                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
00290                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
00291                          *((c)++)=(unsigned char)(((l)     )&0xff))
00292 
00293 /* NOTE - c is not incremented as per l2c */
00294 
00295 /* long to char network */
00296 #define l2cn(l1,l2,c,n) { \
00297                         c+=n; \
00298                         switch (n) { \
00299                         case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
00300                         case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
00301                         case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
00302                         case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
00303                         case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
00304                         case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
00305                         case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
00306                         case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
00307                                 } \
00308                         }
00309 
00310 
00311 /* ALARM: check this out carefully
00312  * keep an eye on that when porting to 16 bit
00313  *
00314  *
00315  */
00316 #ifndef ROTATE
00317 #define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
00318 #endif
00319 
00320 #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
00321 #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
00322         u=R^s[S  ]; \
00323         t=R^s[S+1]
00324 
00325 #define D_ENCRYPT(LL,R,S) {\
00326         LOAD_DATA_tmp(R,S,u,t,E0,E1); \
00327         t=ROTATE(t,4); \
00328         LL^=\
00329                 DES_SPtrans[0][(u>> 2L)&0x3f]^ \
00330                 DES_SPtrans[2][(u>>10L)&0x3f]^ \
00331                 DES_SPtrans[4][(u>>18L)&0x3f]^ \
00332                 DES_SPtrans[6][(u>>26L)&0x3f]^ \
00333                 DES_SPtrans[1][(t>> 2L)&0x3f]^ \
00334                 DES_SPtrans[3][(t>>10L)&0x3f]^ \
00335                 DES_SPtrans[5][(t>>18L)&0x3f]^ \
00336                 DES_SPtrans[7][(t>>26L)&0x3f]; }
00337 
00338 
00339 
00340         /* IP and FP
00341          * The problem is more of a geometric problem that random bit fiddling.
00342          0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
00343          8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
00344         16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
00345         24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
00346 
00347         32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
00348         40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
00349         48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
00350         56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
00351 
00352         The output has been subject to swaps of the form
00353         0 1 -> 3 1 but the odd and even bits have been put into
00354         2 3    2 0
00355         different words.  The main trick is to remember that
00356         t=((l>>size)^r)&(mask);
00357         r^=t;
00358         l^=(t<<size);
00359         can be used to swap and move bits between words.
00360 
00361         So l =  0  1  2  3  r = 16 17 18 19
00362                 4  5  6  7      20 21 22 23
00363                 8  9 10 11      24 25 26 27
00364                12 13 14 15      28 29 30 31
00365         becomes (for size == 2 and mask == 0x3333)
00366            t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
00367                  6^20  7^21 -- --        4  5 20 21       6  7 22 23
00368                 10^24 11^25 -- --        8  9 24 25      10 11 24 25
00369                 14^28 15^29 -- --       12 13 28 29      14 15 28 29
00370 
00371         Thanks for hints from Richard Outerbridge - he told me IP&FP
00372         could be done in 15 xor, 10 shifts and 5 ands.
00373         When I finally started to think of the problem in 2D
00374         I first got ~42 operations without xors.  When I remembered
00375         how to use xors :-) I got it to its final state.
00376         */
00377 
00378 
00379 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
00380         (b)^=(t),\
00381         (a)^=((t)<<(n)))
00382 
00383 #define IP(l,r) \
00384         { \
00385         DES_LONG tt; \
00386         PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
00387         PERM_OP(l,r,tt,16,0x0000ffffL); \
00388         PERM_OP(r,l,tt, 2,0x33333333L); \
00389         PERM_OP(l,r,tt, 8,0x00ff00ffL); \
00390         PERM_OP(r,l,tt, 1,0x55555555L); \
00391         }
00392 
00393 #define FP(l,r) \
00394         { \
00395         DES_LONG tt; \
00396         PERM_OP(l,r,tt, 1,0x55555555L); \
00397         PERM_OP(r,l,tt, 8,0x00ff00ffL); \
00398         PERM_OP(l,r,tt, 2,0x33333333L); \
00399         PERM_OP(r,l,tt,16,0x0000ffffL); \
00400         PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
00401         }
00402 
00403 
00404 
00405 // des cbc encryption, we use this for IPsec
00406 void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
00407                      DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
00408 {
00409         DES_LONG tin0,tin1;
00410         DES_LONG tout0,tout1,xor0,xor1;
00411         long l=length;
00412         DES_LONG tin[2];
00413         unsigned char *iv;
00414 
00415         iv = &(*ivec)[0];
00416 
00417         if (enc)
00418                 {
00419                 c2l(iv,tout0);
00420                 c2l(iv,tout1);
00421                 for (l-=8; l>=0; l-=8)
00422                         {
00423                         c2l(in,tin0);
00424                         c2l(in,tin1);
00425                         tin0^=tout0; tin[0]=tin0;
00426                         tin1^=tout1; tin[1]=tin1;
00427                         DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
00428                         tout0=tin[0]; l2c(tout0,out);
00429                         tout1=tin[1]; l2c(tout1,out);
00430                         }
00431                 if (l != -8)
00432                         {
00433                         c2ln(in,tin0,tin1,l+8);
00434                         tin0^=tout0; tin[0]=tin0;
00435                         tin1^=tout1; tin[1]=tin1;
00436                         DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
00437                         tout0=tin[0]; l2c(tout0,out);
00438                         tout1=tin[1]; l2c(tout1,out);
00439                         }
00440                 iv = &(*ivec)[0];                               // next 3 lines ifndef CBC_ENC_C__DONT_UPDATE_IV
00441                 l2c(tout0,iv);
00442                 l2c(tout1,iv);
00443                 }
00444         else
00445                 {
00446                 c2l(iv,xor0);
00447                 c2l(iv,xor1);
00448                 for (l-=8; l>=0; l-=8)
00449                         {
00450                         c2l(in,tin0); tin[0]=tin0;
00451                         c2l(in,tin1); tin[1]=tin1;
00452                         DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
00453                         tout0=tin[0]^xor0;
00454                         tout1=tin[1]^xor1;
00455                         l2c(tout0,out);
00456                         l2c(tout1,out);
00457                         xor0=tin0;
00458                         xor1=tin1;
00459                         }
00460                 if (l != -8)
00461                         {
00462                         c2l(in,tin0); tin[0]=tin0;
00463                         c2l(in,tin1); tin[1]=tin1;
00464                         DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
00465                         tout0=tin[0]^xor0;
00466                         tout1=tin[1]^xor1;
00467                         l2cn(tout0,tout1,out,l+8);
00468 
00469                         xor0=tin0;                              // next 2 lines #ifndef CBC_ENC_C__DONT_UPDATE_IV
00470                         xor1=tin1;
00471                         }
00472                 iv = &(*ivec)[0];                       // next 3 lines #ifndef CBC_ENC_C__DONT_UPDATE_IV
00473                 l2c(xor0,iv);
00474                 l2c(xor1,iv);
00475                 }
00476         tin0=tin1=tout0=tout1=xor0=xor1=0;
00477         tin[0]=tin[1]=0;
00478 }
00479 
00480 
00481 // normal DES encryption routine
00482 void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
00483 {
00484         DES_LONG l,r,t,u;
00485         int i;
00486         DES_LONG *s;
00487         r=data[0];
00488         l=data[1];
00489         IP(r,l);
00490         /* Things have been modified so that the initial rotate is
00491          * done outside the loop.  This required the
00492          * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
00493          * One perl script later and things have a 5% speed up on a sparc2.
00494          * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
00495          * for pointing this out. */
00496         /* clear the top bits on machines with 8byte longs */
00497         /* shift left by 2 */
00498         r=ROTATE(r,29)&0xffffffffL;
00499         l=ROTATE(l,29)&0xffffffffL;
00500         s=ks->ks->deslong;
00501         /* I don't know if it is worth the effort of loop unrolling the
00502          * inner loop */
00503         if (enc)
00504                 {
00505                 for (i=0; i<32; i+=8)
00506                         {
00507                         D_ENCRYPT(l,r,i+0); /*  1 */
00508                         D_ENCRYPT(r,l,i+2); /*  2 */
00509                         D_ENCRYPT(l,r,i+4); /*  3 */
00510                         D_ENCRYPT(r,l,i+6); /*  4 */
00511                         }
00512                 }
00513         else
00514                 {
00515                 for (i=30; i>0; i-=8)
00516                         {
00517                         D_ENCRYPT(l,r,i-0); /* 16 */
00518                         D_ENCRYPT(r,l,i-2); /* 15 */
00519                         D_ENCRYPT(l,r,i-4); /* 14 */
00520                         D_ENCRYPT(r,l,i-6); /* 13 */
00521                         }
00522                 }
00523         /* rotate and clear the top bits on machines with 8byte longs */
00524         l=ROTATE(l,3)&0xffffffffL;
00525         r=ROTATE(r,3)&0xffffffffL;
00526         FP(r,l);
00527         data[0]=l;
00528         data[1]=r;
00529         l=r=t=u=0;
00530 }
00531 
00532 // another DES encryption function
00533 void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
00534 {
00535         DES_LONG l,r,t,u;
00536         int i;
00537         DES_LONG *s;
00538         r=data[0];
00539         l=data[1];
00540         /* Things have been modified so that the initial rotate is
00541          * done outside the loop.  This required the
00542          * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
00543          * One perl script later and things have a 5% speed up on a sparc2.
00544          * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
00545          * for pointing this out. */
00546         /* clear the top bits on machines with 8byte longs */
00547         r=ROTATE(r,29)&0xffffffffL;
00548         l=ROTATE(l,29)&0xffffffffL;
00549         s=ks->ks->deslong;
00550         /* I don't know if it is worth the effort of loop unrolling the
00551          * inner loop */
00552         if (enc)
00553                 {
00554                 for (i=0; i<32; i+=8)
00555                         {
00556                         D_ENCRYPT(l,r,i+0); /*  1 */
00557                         D_ENCRYPT(r,l,i+2); /*  2 */
00558                         D_ENCRYPT(l,r,i+4); /*  3 */
00559                         D_ENCRYPT(r,l,i+6); /*  4 */
00560                         }
00561                 }
00562         else
00563                 {
00564                 for (i=30; i>0; i-=8)
00565                         {
00566                         D_ENCRYPT(l,r,i-0); /* 16 */
00567                         D_ENCRYPT(r,l,i-2); /* 15 */
00568                         D_ENCRYPT(l,r,i-4); /* 14 */
00569                         D_ENCRYPT(r,l,i-6); /* 13 */
00570                         }
00571                 }
00572         /* rotate and clear the top bits on machines with 8byte longs */
00573         data[0]=ROTATE(l,3)&0xffffffffL;
00574         data[1]=ROTATE(r,3)&0xffffffffL;
00575         l=r=t=u=0;
00576 }
00577 
00578 // 3DES encrypt
00579 void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
00580                   DES_key_schedule *ks2, DES_key_schedule *ks3)
00581 {
00582         DES_LONG l,r;
00583         l=data[0];
00584         r=data[1];
00585         IP(l,r);
00586         data[0]=l;
00587         data[1]=r;
00588         DES_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
00589         DES_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
00590         DES_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
00591         l=data[0];
00592         r=data[1];
00593         FP(r,l);
00594         data[0]=l;
00595         data[1]=r;
00596 }
00597 
00598 // 3DES decrypt
00599 void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
00600                   DES_key_schedule *ks2, DES_key_schedule *ks3)
00601 {
00602         DES_LONG l,r;
00603         l=data[0];
00604         r=data[1];
00605         IP(l,r);
00606         data[0]=l;
00607         data[1]=r;
00608         DES_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
00609         DES_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
00610         DES_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
00611         l=data[0];
00612         r=data[1];
00613         FP(r,l);
00614         data[0]=l;
00615         data[1]=r;
00616 }
00617 #ifndef DES_DEFAULT_OPTIONS
00618 //#undef CBC_ENC_C__DONT_UPDATE_IV
00619 
00620 // 3DES CBC encrypt/decrypt fuctnion, we USE that for IPsec
00621 void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
00622                           long length, DES_key_schedule *ks1,
00623                           DES_key_schedule *ks2, DES_key_schedule *ks3,
00624                           DES_cblock *ivec, int enc)
00625 {
00626         DES_LONG tin0,tin1;
00627         DES_LONG tout0,tout1,xor0,xor1;
00628         const unsigned char *in;
00629         unsigned char *out;
00630         long l=length;
00631         DES_LONG tin[2];
00632         unsigned char *iv;
00633         in=input;
00634         out=output;
00635         iv = &(*ivec)[0];
00636         if (enc)
00637                 {
00638                 c2l(iv,tout0);
00639                 c2l(iv,tout1);
00640                 for (l-=8; l>=0; l-=8)
00641                         {
00642                         c2l(in,tin0);
00643                         c2l(in,tin1);
00644                         tin0^=tout0;
00645                         tin1^=tout1;
00646                         tin[0]=tin0;
00647                         tin[1]=tin1;
00648                         DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
00649                         tout0=tin[0];
00650                         tout1=tin[1];
00651                         l2c(tout0,out);
00652                         l2c(tout1,out);
00653                         }
00654                 if (l != -8)
00655                         {
00656                         c2ln(in,tin0,tin1,l+8);
00657                         tin0^=tout0;
00658                         tin1^=tout1;
00659                         tin[0]=tin0;
00660                         tin[1]=tin1;
00661                         DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
00662                         tout0=tin[0];
00663                         tout1=tin[1];
00664                         l2c(tout0,out);
00665                         l2c(tout1,out);
00666                         }
00667                 iv = &(*ivec)[0];
00668                 l2c(tout0,iv);
00669                 l2c(tout1,iv);
00670                 }
00671         else
00672                 {
00673                 DES_LONG t0,t1;
00674                 c2l(iv,xor0);
00675                 c2l(iv,xor1);
00676                 for (l-=8; l>=0; l-=8)
00677                         {
00678                         c2l(in,tin0);
00679                         c2l(in,tin1);
00680                         t0=tin0;
00681                         t1=tin1;
00682                         tin[0]=tin0;
00683                         tin[1]=tin1;
00684                         DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
00685                         tout0=tin[0];
00686                         tout1=tin[1];
00687                         tout0^=xor0;
00688                         tout1^=xor1;
00689                         l2c(tout0,out);
00690                         l2c(tout1,out);
00691                         xor0=t0;
00692                         xor1=t1;
00693                         }
00694                 if (l != -8)
00695                         {
00696                         c2l(in,tin0);
00697                         c2l(in,tin1);
00698                         
00699                         t0=tin0;
00700                         t1=tin1;
00701                         tin[0]=tin0;
00702                         tin[1]=tin1;
00703                         DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
00704                         tout0=tin[0];
00705                         tout1=tin[1];
00706                 
00707                         tout0^=xor0;
00708                         tout1^=xor1;
00709                         l2cn(tout0,tout1,out,l+8);
00710                         xor0=t0;
00711                         xor1=t1;
00712                         }
00713                 iv = &(*ivec)[0];
00714                 l2c(xor0,iv);
00715                 l2c(xor1,iv);
00716                 }
00717         tin0=tin1=tout0=tout1=xor0=xor1=0;
00718         tin[0]=tin[1]=0;
00719 }
00720 #endif /* DES_DEFAULT_OPTIONS */
00721 
00722 
00723 int _shadow_DES_check_key;
00724 
00725 static const unsigned char odd_parity[256]={
00726   1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
00727  16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
00728  32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
00729  49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
00730  64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
00731  81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
00732  97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
00733 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
00734 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
00735 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
00736 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
00737 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
00738 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
00739 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
00740 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
00741 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
00742 
00743 void DES_set_odd_parity(DES_cblock *key)
00744 {
00745         int i;
00746 
00747         for (i=0; i<DES_KEY_SZ; i++)
00748                 (*key)[i]=odd_parity[(*key)[i]];
00749 }
00750 
00751 int DES_check_key_parity(const_DES_cblock *key)
00752 {
00753         int i;
00754 
00755         for (i=0; i<DES_KEY_SZ; i++)
00756                 {
00757                 if ((*key)[i] != odd_parity[(*key)[i]])
00758                         return(0);
00759                 }
00760         return(1);
00761 }
00762 
00763 /* Weak and semi week keys as take from
00764  * %A D.W. Davies
00765  * %A W.L. Price
00766  * %T Security for Computer Networks
00767  * %I John Wiley & Sons
00768  * %D 1984
00769  * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
00770  * (and actual cblock values).
00771  */
00772 #define NUM_WEAK_KEY    16
00773 static DES_cblock weak_keys[NUM_WEAK_KEY]={
00774         /* weak keys */
00775         {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
00776         {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
00777         {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
00778         {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
00779         /* semi-weak keys */
00780         {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
00781         {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
00782         {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
00783         {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
00784         {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
00785         {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
00786         {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
00787         {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
00788         {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
00789         {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
00790         {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
00791         {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
00792 
00793 int DES_is_weak_key(const_DES_cblock *key)
00794 {
00795         int i;
00796 
00797         for (i=0; i<NUM_WEAK_KEY; i++)
00798                 /* Added == 0 to comparison, I obviously don't run
00799                  * this section very often :-(, thanks to
00800                  * engineering@MorningStar.Com for the fix
00801                  * eay 93/06/29
00802                  * Another problem, I was comparing only the first 4
00803                  * bytes, 97/03/18 */
00804                 if (memcmp(weak_keys[i],key,sizeof(DES_cblock)) == 0) return(1);
00805         return(0);
00806 }
00807 
00808 /* NOW DEFINED IN des_local.h
00809  * See ecb_encrypt.c for a pseudo description of these macros. 
00810  * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
00811  *      (b)^=(t),\
00812  *      (a)=((a)^((t)<<(n))))
00813  */
00814 
00815 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
00816         (a)=(a)^(t)^(t>>(16-(n))))
00817 
00818 static const DES_LONG des_skb[8][64]={
00819         {
00820         /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
00821         0x00000000L,0x00000010L,0x20000000L,0x20000010L,
00822         0x00010000L,0x00010010L,0x20010000L,0x20010010L,
00823         0x00000800L,0x00000810L,0x20000800L,0x20000810L,
00824         0x00010800L,0x00010810L,0x20010800L,0x20010810L,
00825         0x00000020L,0x00000030L,0x20000020L,0x20000030L,
00826         0x00010020L,0x00010030L,0x20010020L,0x20010030L,
00827         0x00000820L,0x00000830L,0x20000820L,0x20000830L,
00828         0x00010820L,0x00010830L,0x20010820L,0x20010830L,
00829         0x00080000L,0x00080010L,0x20080000L,0x20080010L,
00830         0x00090000L,0x00090010L,0x20090000L,0x20090010L,
00831         0x00080800L,0x00080810L,0x20080800L,0x20080810L,
00832         0x00090800L,0x00090810L,0x20090800L,0x20090810L,
00833         0x00080020L,0x00080030L,0x20080020L,0x20080030L,
00834         0x00090020L,0x00090030L,0x20090020L,0x20090030L,
00835         0x00080820L,0x00080830L,0x20080820L,0x20080830L,
00836         0x00090820L,0x00090830L,0x20090820L,0x20090830L,
00837         },{
00838         /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
00839         0x00000000L,0x02000000L,0x00002000L,0x02002000L,
00840         0x00200000L,0x02200000L,0x00202000L,0x02202000L,
00841         0x00000004L,0x02000004L,0x00002004L,0x02002004L,
00842         0x00200004L,0x02200004L,0x00202004L,0x02202004L,
00843         0x00000400L,0x02000400L,0x00002400L,0x02002400L,
00844         0x00200400L,0x02200400L,0x00202400L,0x02202400L,
00845         0x00000404L,0x02000404L,0x00002404L,0x02002404L,
00846         0x00200404L,0x02200404L,0x00202404L,0x02202404L,
00847         0x10000000L,0x12000000L,0x10002000L,0x12002000L,
00848         0x10200000L,0x12200000L,0x10202000L,0x12202000L,
00849         0x10000004L,0x12000004L,0x10002004L,0x12002004L,
00850         0x10200004L,0x12200004L,0x10202004L,0x12202004L,
00851         0x10000400L,0x12000400L,0x10002400L,0x12002400L,
00852         0x10200400L,0x12200400L,0x10202400L,0x12202400L,
00853         0x10000404L,0x12000404L,0x10002404L,0x12002404L,
00854         0x10200404L,0x12200404L,0x10202404L,0x12202404L,
00855         },{
00856         /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
00857         0x00000000L,0x00000001L,0x00040000L,0x00040001L,
00858         0x01000000L,0x01000001L,0x01040000L,0x01040001L,
00859         0x00000002L,0x00000003L,0x00040002L,0x00040003L,
00860         0x01000002L,0x01000003L,0x01040002L,0x01040003L,
00861         0x00000200L,0x00000201L,0x00040200L,0x00040201L,
00862         0x01000200L,0x01000201L,0x01040200L,0x01040201L,
00863         0x00000202L,0x00000203L,0x00040202L,0x00040203L,
00864         0x01000202L,0x01000203L,0x01040202L,0x01040203L,
00865         0x08000000L,0x08000001L,0x08040000L,0x08040001L,
00866         0x09000000L,0x09000001L,0x09040000L,0x09040001L,
00867         0x08000002L,0x08000003L,0x08040002L,0x08040003L,
00868         0x09000002L,0x09000003L,0x09040002L,0x09040003L,
00869         0x08000200L,0x08000201L,0x08040200L,0x08040201L,
00870         0x09000200L,0x09000201L,0x09040200L,0x09040201L,
00871         0x08000202L,0x08000203L,0x08040202L,0x08040203L,
00872         0x09000202L,0x09000203L,0x09040202L,0x09040203L,
00873         },{
00874         /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
00875         0x00000000L,0x00100000L,0x00000100L,0x00100100L,
00876         0x00000008L,0x00100008L,0x00000108L,0x00100108L,
00877         0x00001000L,0x00101000L,0x00001100L,0x00101100L,
00878         0x00001008L,0x00101008L,0x00001108L,0x00101108L,
00879         0x04000000L,0x04100000L,0x04000100L,0x04100100L,
00880         0x04000008L,0x04100008L,0x04000108L,0x04100108L,
00881         0x04001000L,0x04101000L,0x04001100L,0x04101100L,
00882         0x04001008L,0x04101008L,0x04001108L,0x04101108L,
00883         0x00020000L,0x00120000L,0x00020100L,0x00120100L,
00884         0x00020008L,0x00120008L,0x00020108L,0x00120108L,
00885         0x00021000L,0x00121000L,0x00021100L,0x00121100L,
00886         0x00021008L,0x00121008L,0x00021108L,0x00121108L,
00887         0x04020000L,0x04120000L,0x04020100L,0x04120100L,
00888         0x04020008L,0x04120008L,0x04020108L,0x04120108L,
00889         0x04021000L,0x04121000L,0x04021100L,0x04121100L,
00890         0x04021008L,0x04121008L,0x04021108L,0x04121108L,
00891         },{
00892         /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
00893         0x00000000L,0x10000000L,0x00010000L,0x10010000L,
00894         0x00000004L,0x10000004L,0x00010004L,0x10010004L,
00895         0x20000000L,0x30000000L,0x20010000L,0x30010000L,
00896         0x20000004L,0x30000004L,0x20010004L,0x30010004L,
00897         0x00100000L,0x10100000L,0x00110000L,0x10110000L,
00898         0x00100004L,0x10100004L,0x00110004L,0x10110004L,
00899         0x20100000L,0x30100000L,0x20110000L,0x30110000L,
00900         0x20100004L,0x30100004L,0x20110004L,0x30110004L,
00901         0x00001000L,0x10001000L,0x00011000L,0x10011000L,
00902         0x00001004L,0x10001004L,0x00011004L,0x10011004L,
00903         0x20001000L,0x30001000L,0x20011000L,0x30011000L,
00904         0x20001004L,0x30001004L,0x20011004L,0x30011004L,
00905         0x00101000L,0x10101000L,0x00111000L,0x10111000L,
00906         0x00101004L,0x10101004L,0x00111004L,0x10111004L,
00907         0x20101000L,0x30101000L,0x20111000L,0x30111000L,
00908         0x20101004L,0x30101004L,0x20111004L,0x30111004L,
00909         },{
00910         /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
00911         0x00000000L,0x08000000L,0x00000008L,0x08000008L,
00912         0x00000400L,0x08000400L,0x00000408L,0x08000408L,
00913         0x00020000L,0x08020000L,0x00020008L,0x08020008L,
00914         0x00020400L,0x08020400L,0x00020408L,0x08020408L,
00915         0x00000001L,0x08000001L,0x00000009L,0x08000009L,
00916         0x00000401L,0x08000401L,0x00000409L,0x08000409L,
00917         0x00020001L,0x08020001L,0x00020009L,0x08020009L,
00918         0x00020401L,0x08020401L,0x00020409L,0x08020409L,
00919         0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
00920         0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
00921         0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
00922         0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
00923         0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
00924         0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
00925         0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
00926         0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
00927         },{
00928         /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
00929         0x00000000L,0x00000100L,0x00080000L,0x00080100L,
00930         0x01000000L,0x01000100L,0x01080000L,0x01080100L,
00931         0x00000010L,0x00000110L,0x00080010L,0x00080110L,
00932         0x01000010L,0x01000110L,0x01080010L,0x01080110L,
00933         0x00200000L,0x00200100L,0x00280000L,0x00280100L,
00934         0x01200000L,0x01200100L,0x01280000L,0x01280100L,
00935         0x00200010L,0x00200110L,0x00280010L,0x00280110L,
00936         0x01200010L,0x01200110L,0x01280010L,0x01280110L,
00937         0x00000200L,0x00000300L,0x00080200L,0x00080300L,
00938         0x01000200L,0x01000300L,0x01080200L,0x01080300L,
00939         0x00000210L,0x00000310L,0x00080210L,0x00080310L,
00940         0x01000210L,0x01000310L,0x01080210L,0x01080310L,
00941         0x00200200L,0x00200300L,0x00280200L,0x00280300L,
00942         0x01200200L,0x01200300L,0x01280200L,0x01280300L,
00943         0x00200210L,0x00200310L,0x00280210L,0x00280310L,
00944         0x01200210L,0x01200310L,0x01280210L,0x01280310L,
00945         },{
00946         /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
00947         0x00000000L,0x04000000L,0x00040000L,0x04040000L,
00948         0x00000002L,0x04000002L,0x00040002L,0x04040002L,
00949         0x00002000L,0x04002000L,0x00042000L,0x04042000L,
00950         0x00002002L,0x04002002L,0x00042002L,0x04042002L,
00951         0x00000020L,0x04000020L,0x00040020L,0x04040020L,
00952         0x00000022L,0x04000022L,0x00040022L,0x04040022L,
00953         0x00002020L,0x04002020L,0x00042020L,0x04042020L,
00954         0x00002022L,0x04002022L,0x00042022L,0x04042022L,
00955         0x00000800L,0x04000800L,0x00040800L,0x04040800L,
00956         0x00000802L,0x04000802L,0x00040802L,0x04040802L,
00957         0x00002800L,0x04002800L,0x00042800L,0x04042800L,
00958         0x00002802L,0x04002802L,0x00042802L,0x04042802L,
00959         0x00000820L,0x04000820L,0x00040820L,0x04040820L,
00960         0x00000822L,0x04000822L,0x00040822L,0x04040822L,
00961         0x00002820L,0x04002820L,0x00042820L,0x04042820L,
00962         0x00002822L,0x04002822L,0x00042822L,0x04042822L,
00963         }};
00964 
00965 int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
00966 {
00967         if (_shadow_DES_check_key)
00968                 {
00969                 return DES_set_key_checked(key, schedule);
00970                 }
00971         else
00972                 {
00973                 DES_set_key_unchecked(key, schedule);
00974                 return 0;
00975                 }
00976 }
00977 
00978 /* return 0 if key parity is odd (correct),
00979  * return -1 if key parity error,
00980  * return -2 if illegal weak key.
00981  */
00982 int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
00983 {
00984         if (!DES_check_key_parity(key))
00985                 return(-1);
00986         if (DES_is_weak_key(key))
00987                 return(-2);
00988         DES_set_key_unchecked(key, schedule);
00989         return 0;
00990 }
00991 
00992 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
00993 {
00994         static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
00995         DES_LONG c,d,t,s,t2;
00996         const unsigned char *in;
00997         DES_LONG *k;
00998         int i;
00999 
01000         k = &schedule->ks->deslong[0];
01001         in = &(*key)[0];
01002 
01003         c2l(in,c);
01004         c2l(in,d);
01005 
01006         /* do PC1 in 47 simple operations :-)
01007          * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
01008          * for the inspiration. :-) */
01009         PERM_OP (d,c,t,4,0x0f0f0f0fL);
01010         HPERM_OP(c,t,-2,0xcccc0000L);
01011         HPERM_OP(d,t,-2,0xcccc0000L);
01012         PERM_OP (d,c,t,1,0x55555555L);
01013         PERM_OP (c,d,t,8,0x00ff00ffL);
01014         PERM_OP (d,c,t,1,0x55555555L);
01015         d=      (((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
01016                  ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
01017         c&=0x0fffffffL;
01018 
01019         for (i=0; i<ITERATIONS; i++)
01020                 {
01021                 if (shifts2[i])
01022                         { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
01023                 else
01024                         { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
01025                 c&=0x0fffffffL;
01026                 d&=0x0fffffffL;
01027                 /* could be a few less shifts but I am to lazy at this
01028                  * point in time to investigate */
01029                 s=      des_skb[0][ (c    )&0x3f                ]|
01030                         des_skb[1][((c>> 6L)&0x03)|((c>> 7L)&0x3c)]|
01031                         des_skb[2][((c>>13L)&0x0f)|((c>>14L)&0x30)]|
01032                         des_skb[3][((c>>20L)&0x01)|((c>>21L)&0x06) |
01033                                                   ((c>>22L)&0x38)];
01034                 t=      des_skb[4][ (d    )&0x3f                ]|
01035                         des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
01036                         des_skb[6][ (d>>15L)&0x3f                ]|
01037                         des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
01038 
01039                 /* table contained 0213 4657 */
01040                 t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
01041                 *(k++)=ROTATE(t2,30)&0xffffffffL;
01042 
01043                 t2=((s>>16L)|(t&0xffff0000L));
01044                 *(k++)=ROTATE(t2,26)&0xffffffffL;
01045                 }
01046 }
01047 
01048 int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
01049 {
01050         return(DES_set_key(key,schedule));
01051 }
01052 
01053 
01054 
01067 void cipher_3des_cbc(unsigned char* text, int text_len, 
01068                      unsigned char* key, unsigned char* iv, int mode, unsigned char*  output)
01069 {
01070         int ret_val;
01071         DES_key_schedule ks1, ks2, ks3;
01072 
01073         IPSEC_LOG_TRC(IPSEC_TRACE_ENTER, 
01074                       "cipher_3des_cbc", 
01075                                   ("text=%p, text_len=%d, key=%p, iv=%p, mode=%d, output=%p",
01076                               (void *)text, text_len, (void *)key, (void *)iv, mode, (void *)output)
01077                                  );
01078 
01079         ret_val = DES_set_key_checked((const_DES_cblock*)(key + 0*8), &ks1);
01080         if(ret_val != 0) {
01081                 IPSEC_LOG_ERR("ipsec_esp_decapsulate", IPSEC_STATUS_BAD_KEY, ("DES_set_key_checked(&cbc1_key,&ks1) could not set 1st 3DES key - ret_val = %d\n", ret_val)) ;
01082                 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "cipher_3des_cbc", ("void") );
01083                 return;
01084         }
01085 
01086         ret_val = DES_set_key_checked((const_DES_cblock*)(key + 1*8), &ks2);
01087         if(ret_val != 0) {
01088                 IPSEC_LOG_ERR("ipsec_esp_decapsulate", IPSEC_STATUS_BAD_KEY, ("DES_set_key_checked(&cbc2_key,&ks2) could not set 2nd 3DES key - ret_val = %d\n", ret_val)) ;
01089                 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "cipher_3des_cbc", ("void") );
01090                 return;
01091         }
01092 
01093         ret_val = DES_set_key_checked((const_DES_cblock*)(key + 2*8), &ks3);
01094         if(ret_val != 0) {
01095                 IPSEC_LOG_ERR("ipsec_esp_decapsulate", IPSEC_STATUS_BAD_KEY, ("DES_set_key_checked(&cbc3_key,&ks3) could not set 3rd 3DES key - ret_val = %d\n", ret_val)) ;
01096                 IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "cipher_3des_cbc", ("void") );
01097                 return;
01098         }
01099 
01100         DES_ede3_cbc_encrypt(text, output, text_len, (DES_key_schedule *)&ks1 ,(DES_key_schedule *)&ks2, (DES_key_schedule *)&ks3, (DES_cblock*)iv, mode);
01101 
01102         IPSEC_LOG_TRC(IPSEC_TRACE_RETURN, "cipher_3des_cbc", ("void") );
01103 }
01104 

Copyright 2003 by Christian Scheurer and Niklaus Schild