Main Page | Directories | File List | Globals

DES.c

Go to the documentation of this file.
00001 /*
00002  * kernel_libs/crypt/DES.c
00003  *
00004  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  *
00007  * * DES Algorithm
00008  * * Implemented by Lukasz Dembinski <dembol@nasa.com.pl>
00009  * * 2002
00010  * 
00011  * Date:        2002
00012  * Author:      Lukasz Dembinski
00013  * Info:        DES.c core file
00014  * Contact:     mailto: <dembol@linux.net>
00015  * Status:      implemented
00016  */
00017 
00018 #include <agnix/agnix.h>
00019 #include <agnix/memory.h>
00020 #include <agnix/crypt.h>
00021 
00022 u8 PSW[] = {    64, 60, 56, 52, 48, 44, 40, 36,
00023                 32, 28, 24, 20, 16, 12,  8,  4,
00024                 63, 59, 55, 51, 47, 43, 39, 35,
00025                 31, 27, 23, 19, 15, 11,  7,  3,
00026                 62, 58, 54, 50, 46, 42, 38, 34,
00027                 30, 26, 22, 18, 14, 10,  6,  2,
00028                 61, 57, 53, 49, 45, 41, 37, 33,
00029                 29, 25, 21, 17, 13,  9,  5,  1};
00030 
00031 u8 IP[] =  {    58, 50, 42, 34, 26, 18, 10,  2,
00032                 60, 52, 44, 36, 28, 20, 12,  4,
00033                 62, 54, 46, 38, 30, 22, 14,  6,
00034                 64, 56, 48, 40, 32, 24, 16,  8,
00035                 57, 49, 41, 33, 25, 17,  9,  1,
00036                 59, 51, 43, 35, 27, 19, 11,  3,
00037                 61, 53, 45, 37, 29, 21, 13,  5,
00038                 63, 55, 47, 39, 31, 23, 15,  7};
00039 
00040 u8 IPR[] = {    40,  8, 48, 16, 56, 24, 64, 32,
00041                 39,  7, 47, 15, 55, 23, 63, 31,
00042                 38,  6, 46, 14, 54, 22, 62, 30,
00043                 37,  5, 45, 13, 53, 21, 61, 29,
00044                 36,  4, 44, 12, 52, 20, 60, 28,
00045                 35,  3, 43, 11, 51, 19, 59, 27,
00046                 34,  2, 42, 10, 50, 18, 58, 26,
00047                 33,  1, 41,  9, 49, 17, 57, 25};
00048 
00049 u8 PC1[] = {    57, 49, 41, 33, 25, 17, 9,
00050                  1, 58, 50, 42, 34, 26, 18,
00051                 10,  2, 59, 51, 43, 35, 27,
00052                 19, 11,  3, 60, 52, 44, 36,
00053                 63, 55, 47, 39, 31, 23, 15,
00054                  7, 62, 54, 46, 38, 30, 22,
00055                 14,  6, 61, 53, 45, 37, 29,
00056                 21, 13,  5, 28, 20, 12,  4 };
00057 
00058 u8 PC2[] = {    14, 17, 11, 24,  1,  5,
00059                  3, 28, 15,  6, 21, 10,
00060                 23, 19, 12,  4, 21,  8,
00061                 16,  7, 27, 20, 13,  2,
00062                 41, 52, 31, 37, 47, 55,
00063                 30, 40, 51, 45, 33, 48,
00064                 44, 49, 39, 56, 34, 53,
00065                 46, 42, 50, 36, 29, 32 };
00066 
00067 u8 tab_rotate[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
00068         
00069 u8 E[] = {      32,  1,  2,  3,  4,  5,
00070                  4,  5,  6,  7,  8,  9,
00071                  8,  9, 10, 11, 12, 13,
00072                 12, 13, 14, 15, 16, 17,
00073                 16, 17, 18, 19, 20, 21,
00074                 20, 21, 22, 23, 24, 25,
00075                 24, 25, 26, 27, 28, 29,
00076                 28, 29, 30, 31, 32,  1 };
00077 
00078 /* S-Boxes */    
00079 u8 S1[] = {     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
00080                  0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
00081                  4,  1, 14,  8, 13,  6,  2, 11, 15,  2,  9,  7,  3, 10,  5,  0,
00082                 15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13};
00083 
00084 u8 S2[] = {   15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
00085                  3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
00086                  0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
00087                 13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9};
00088 
00089 u8 S3[] = {   10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
00090                 13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
00091                 13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
00092                  1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12};
00093 
00094 u8 S4[] = {      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5,  1, 12,  4, 15,
00095                 13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
00096                 10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
00097                  3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14};
00098 
00099 u8 S5[] = {      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
00100                 14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
00101                  4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
00102                 11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3};
00103 
00104 u8 S6[] = {     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
00105                 10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
00106                  9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
00107                  4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13};
00108 
00109 u8 S7[] = {      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
00110                 13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
00111                  1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
00112                  6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12};
00113 
00114 u8 S8[] = {     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
00115                  1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
00116                  7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
00117                  2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11};
00118 
00119 
00120 u8 P[] = {      16,  7, 20, 21,
00121                 29, 12, 28, 17,
00122                  1, 15, 23, 26,
00123                  5, 18, 31, 10,
00124                  2,  8, 24, 14,
00125                 32, 27,  3,  9,
00126                 19, 13, 30,  6,
00127                 22, 11,  4, 25 };
00128 
00129 int DES_d;
00130 
00131 static inline void keys_gen(u8 *keys, u8 *des_key)
00132 {
00133     u8 PCP[58]; //56
00134     u8 PCR[58]; //56
00135     u8 cycle;
00136     u8 r;
00137     u8 j;
00138     u8 l;
00139     
00140     memset(PCP, 0, sizeof(PCP));
00141     memset(PCR, 0, sizeof(PCR));
00142 
00143     for (j = 0; j < 56; j++)
00144     {
00145         l = PC1[j] - 1;
00146         PCP[j] = (des_key[l >> 3] >> (l & 7)) & 1;
00147     }
00148 
00149     for ( cycle = 0; cycle < 16; cycle++)
00150     {
00151     for ( j = 0; j < 28; j++)
00152     {
00153         r = j + tab_rotate[cycle];
00154         if (r >= 28)
00155              r -= 28;
00156         PCR[j] = PCP[r];
00157     }
00158     
00159     for ( j = 28; j < 56; j++)
00160     {
00161         r = j + tab_rotate[cycle];
00162         if (r >= 56)
00163             r -= 28;
00164         PCR[j] = PCP[r];
00165     }
00166 
00167     for ( j = 0; j < 56; j++)
00168         PCP[j] = PCR[j];
00169 
00170     for ( j = 0; j < 48; j++)
00171     {
00172         l = PC2[j] - 1;
00173         keys[j >> 3] |= (PCR[l] << (j & 7));
00174     }
00175         keys += 6;
00176     }
00177 }
00178 
00179 static inline void s_box(u8 *PES, u8 *PE, u8 *S)
00180 {
00181     u8 w;
00182     u8 k;
00183     u8 l;
00184     u8 eS;
00185     u8 i;
00186     
00187     w = (PE[5] << 1) + PE[0];
00188     k = (PE[4] << 3) + (PE[3] << 2) + (PE[2] << 1) + PE[1];
00189     l = (w << 4) + k;
00190     
00191     eS = S[l];
00192     
00193     for (i = 0; i < 4; i++)
00194         PES[i] = (eS >> i) & 1;
00195 }
00196 
00197 static inline void f(u8 *Ri, u8 *Ki, u8 *PP)
00198 {
00199     u8 PES[34]; //32
00200     u8 PE[50];  //48
00201     int i, l;
00202 
00203     memset(PE,  0, sizeof(PE));
00204     memset(PES, 0, sizeof(PES));
00205     
00206     for (i = 0; i < 48; i++)
00207     {
00208         l = E[i] - 1;
00209         PE[i] =  (Ri[l >> 3] >> (l & 7)) & 1;
00210         PE[i] ^= (Ki[i >> 3] >> (i & 7)) & 1;
00211     }
00212     
00213     s_box(PES, PE, S8);
00214     s_box(PES + 4, PE + 6, S7);
00215     s_box(PES + 8, PE + 12, S6);
00216     s_box(PES + 12, PE + 18, S5);
00217     s_box(PES + 16, PE + 24, S4);
00218     s_box(PES + 20, PE + 30, S3);
00219     s_box(PES + 24, PE + 36, S2);
00220     s_box(PES + 28, PE + 42, S1);
00221     
00222     for (i = 0; i < 32; i++)
00223     {
00224         l = P[i] - 1;
00225         PP[i >> 3] |= PES[l] << (i & 7);
00226     }
00227 }
00228 
00229 static inline void one_cycle(u8 *L, u8 *R, u8 *key)
00230 {
00231     int i;
00232     u8 PP[6]; 
00233 
00234     memset(PP, 0, sizeof(PP));
00235     
00236     f(R, key, PP);
00237     for (i = 0; i < 32; i++)
00238     {
00239         L[i] ^= (PP[i >> 3] >> (i & 7)) & 1;
00240     }
00241 }
00242 
00243 static inline void generate_key(u8 *des_key, char *passwd)
00244 {
00245 //    u32 key_l;    
00246 //    u32 key_h;    
00247     int i, j;
00248     
00249     for (i = 0, j = 0; passwd[i] != 0; i++)
00250     {
00251         des_key[j] += passwd[j];
00252         j++;
00253         if (j >= 8) j = 0;
00254     }
00255 }
00256 
00257 static inline void rotate_key(u8 *des_key)
00258 {
00259     int i, l;
00260     u8 des_key2[10];
00261     
00262     memset(des_key2, 0, sizeof(des_key2));
00263     for (i = 0; i < 64; i++)
00264     {
00265         l = PSW[i] - 1;
00266         des_key2[i >> 3] |= ((des_key[l >> 3] >> (l & 7)) & 1) << (i & 7);
00267     }
00268 
00269     for (i = 0; i < 8; i++)
00270         des_key[i] ^= des_key2[i] + 1;
00271 }
00272 
00273 int DES_crypt(char *in_buf, char *out_buf, char *passwd, int size)
00274 {
00275     u32 ile;
00276     int i;
00277     int l;
00278     u8 PIP[72];
00279     u8 PIPr[72];
00280     u8 keys[6*16];
00281     u8 des_key[10];
00282 //    u8 *out_buf = (u8 *)get_free_pages(0);
00283 //    u8 *out_buf_ptr = out_buf;
00284 
00285     if (size > PAGE_SIZE)
00286         return -1;
00287 
00288     memset(PIP, 0, sizeof(PIP));
00289     memset(out_buf, 0, size + 2);    
00290     memset(des_key, 0, sizeof(des_key));
00291 
00292     generate_key(des_key, passwd);
00293 
00294     for (ile = 0; ile <= ((size - 1) >> 3); ile++)
00295     {
00296 
00297 //        rotate_key(des_key);  /* changed by dembol */
00298         memset(keys, 0, sizeof(keys));
00299     
00300         keys_gen(keys, des_key);
00301 
00302         for (i = 0; i < 8; i++)
00303         {
00304             des_key[i] = keys[i];
00305             des_key[i] ^= keys[i + 4];
00306         }
00307 
00308         for (i = 0; i < 64; i++)
00309         {
00310             l = IP[i] - 1;
00311             PIP[i] = (in_buf[l >> 3] >> (l & 7)) & 1;
00312         }
00313 
00314         for (i = 0; i < 8; i++)
00315         {
00316             one_cycle(PIP + 32, PIP, keys + i * 2 * 6);
00317             one_cycle(PIP, PIP + 32, keys + i * 2 * 6 + 6);
00318         }
00319 
00320         for (i = 0; i < 32; i++)
00321         {
00322             PIPr[i] = PIP[32 + i];
00323             PIPr[i + 32] = PIP[i];
00324         }
00325 
00326         for (i = 0; i < 64; i++)
00327         {
00328             l = IPR[i] - 1;
00329             out_buf[i >> 3] |= PIPr[l] << (i & 7);
00330         }
00331     
00332         in_buf += 8;
00333         out_buf += 8;
00334     }
00335 
00336 //    memcpy(in_buf, out_buf_ptr, size);
00337 //    put_free_pages((u32)out_buf_ptr, 0);
00338 
00339     return 0;
00340 }
00341 
00342 int DES_decrypt(char *in_buf, char *out_buf, char *passwd, int size)
00343 {
00344     u32 ile;
00345     int i;
00346     int j;
00347     int l;
00348     u8 PIP[70];
00349     u8 PIPr[70];
00350     u8 keys[6*16];
00351     u8 des_key[10];
00352 //    u8 *out_buf = (u8 *)get_free_pages(0);
00353 //    u8 *out_buf_ptr = out_buf;
00354 
00355     if (size > PAGE_SIZE)
00356         return -1;
00357     
00358     memset(PIP, 0, sizeof(PIP));
00359     memset(out_buf, 0, size + 2);    
00360     memset(des_key, 0, sizeof(des_key));
00361 
00362     generate_key(des_key, passwd);
00363 
00364     for (ile = 0; ile <= ((size - 1) >> 3); ile++)
00365     {
00366 
00367 //      rotate_key(des_key);
00368         memset(keys, 0, sizeof(keys));
00369         keys_gen(keys, des_key);
00370 
00371         for (i = 0; i < 8; i++)
00372         {
00373             des_key[i] = keys[i];
00374             des_key[i] ^= keys[i + 4];
00375         }
00376 
00377         for (i = 0; i < 64; i++)
00378         {
00379             l = IP[i] - 1;
00380             PIP[i] = (in_buf[l >> 3] >> (l & 7)) & 1;
00381         }
00382 
00383         j = 7;
00384         for (i = 0; i < 8; i++)
00385         {
00386             one_cycle(PIP + 32, PIP, keys + j * 2 * 6 + 6);
00387             one_cycle(PIP, PIP + 32, keys + j * 2 * 6);
00388             j--;
00389         }
00390 
00391         for (i = 0; i < 32; i++)
00392         {
00393             PIPr[i] = PIP[32 + i];
00394             PIPr[i + 32] = PIP[i];
00395         }
00396 
00397         for (i = 0; i < 64; i++)
00398         {
00399             l = IPR[i] - 1;
00400             out_buf[i >> 3] |= PIPr[l] << (i & 7);
00401         }
00402 
00403         in_buf += 8;
00404         out_buf += 8;
00405     }
00406 
00407     return 0;
00408 }
00409 
00410 int DES_setup(void)
00411 {
00412     return 0;
00413 }
00414 
00415 struct crypt_algo_s DES_algo = {
00416     "DES",
00417     DES_setup,
00418     DES_crypt,
00419     DES_decrypt
00420 };
00421 
00422 int DES_init(void)
00423 {
00424     DES_d = register_crypt_algo(&DES_algo);
00425     
00426     if (DES_d < 0)
00427         return -1;
00428     
00429     return 0;
00430 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix