00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #include <string.h>
00020 #include <kswap.h>
00021 #include "des.h"
00022 
00023 static void permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock);
00024 static void permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock);
00025 static void perminit_ip (DES_KEY * key);
00026 static void spinit (DES_KEY * key);
00027 static void perminit_fp (DES_KEY * key);
00028 static Q_UINT32 f (DES_KEY * key,  Q_UINT32 r,  char *subkey);
00029 
00030 
00031 
00032 
00033 
00034 static const char ip[] = {
00035   58, 50, 42, 34, 26, 18, 10, 2,
00036   60, 52, 44, 36, 28, 20, 12, 4,
00037   62, 54, 46, 38, 30, 22, 14, 6,
00038   64, 56, 48, 40, 32, 24, 16, 8,
00039   57, 49, 41, 33, 25, 17, 9, 1,
00040   59, 51, 43, 35, 27, 19, 11, 3,
00041   61, 53, 45, 37, 29, 21, 13, 5,
00042   63, 55, 47, 39, 31, 23, 15, 7
00043 };
00044 
00045 
00046 static const char fp[] = {
00047   40, 8, 48, 16, 56, 24, 64, 32,
00048   39, 7, 47, 15, 55, 23, 63, 31,
00049   38, 6, 46, 14, 54, 22, 62, 30,
00050   37, 5, 45, 13, 53, 21, 61, 29,
00051   36, 4, 44, 12, 52, 20, 60, 28,
00052   35, 3, 43, 11, 51, 19, 59, 27,
00053   34, 2, 42, 10, 50, 18, 58, 26,
00054   33, 1, 41, 9, 49, 17, 57, 25
00055 };
00056 
00057 
00058 
00059 
00060 
00061 #ifdef notdef
00062 static const char ei[] = {
00063   32, 1, 2, 3, 4, 5,
00064   4, 5, 6, 7, 8, 9,
00065   8, 9, 10, 11, 12, 13,
00066   12, 13, 14, 15, 16, 17,
00067   16, 17, 18, 19, 20, 21,
00068   20, 21, 22, 23, 24, 25,
00069   24, 25, 26, 27, 28, 29,
00070   28, 29, 30, 31, 32, 1
00071 };
00072 #endif
00073 
00074 
00075 static const char pc1[] = {
00076   57, 49, 41, 33, 25, 17, 9,
00077   1, 58, 50, 42, 34, 26, 18,
00078   10, 2, 59, 51, 43, 35, 27,
00079   19, 11, 3, 60, 52, 44, 36,
00080 
00081   63, 55, 47, 39, 31, 23, 15,
00082   7, 62, 54, 46, 38, 30, 22,
00083   14, 6, 61, 53, 45, 37, 29,
00084   21, 13, 5, 28, 20, 12, 4
00085 };
00086 
00087 
00088 static const char totrot[] = {
00089   1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
00090 };
00091 
00092 
00093 static const char pc2[] = {
00094   14, 17, 11, 24, 1, 5,
00095   3, 28, 15, 6, 21, 10,
00096   23, 19, 12, 4, 26, 8,
00097   16, 7, 27, 20, 13, 2,
00098   41, 52, 31, 37, 47, 55,
00099   30, 40, 51, 45, 33, 48,
00100   44, 49, 39, 56, 34, 53,
00101   46, 42, 50, 36, 29, 32
00102 };
00103 
00104 
00105 static const char si[8][64] = {
00106   
00107   {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
00108    0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
00109    4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
00110    15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
00111 
00112   
00113   {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
00114    3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
00115    0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
00116    13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
00117 
00118   
00119   {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
00120    13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
00121    13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
00122    1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
00123 
00124   
00125   {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
00126    13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
00127    10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
00128    3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
00129 
00130   
00131   {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
00132    14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
00133    4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
00134    11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
00135 
00136   
00137   {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
00138    10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
00139    9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
00140    4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
00141 
00142   
00143   {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
00144    13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
00145    1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
00146    6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
00147 
00148   
00149   {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
00150    1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
00151    7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
00152    2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
00153 
00154 };
00155 
00156 
00157 static const char p32i[] = {
00158   16, 7, 20, 21,
00159   29, 12, 28, 17,
00160   1, 15, 23, 26,
00161   5, 18, 31, 10,
00162   2, 8, 24, 14,
00163   32, 27, 3, 9,
00164   19, 13, 30, 6,
00165   22, 11, 4, 25
00166 };
00167 
00168 
00169 
00170 
00171 
00172 
00173 static const int bytebit[] = {
00174   0200, 0100, 040, 020, 010, 04, 02, 01
00175 };
00176 
00177 static const int nibblebit[] = {
00178   010, 04, 02, 01
00179 };
00180 
00181 
00182 
00183 
00184 static int
00185 desinit (DES_KEY * key)
00186 {
00187 
00188   spinit (key);
00189   perminit_ip (key);
00190   perminit_fp (key);
00191 
00192   return 0;
00193 }
00194 
00195 
00196 
00197 int
00198 ntlm_des_set_key (DES_KEY * dkey, char *user_key, int )
00199 {
00200   char pc1m[56];        
00201   char pcr[56];         
00202    int i, j, l;
00203   int m;
00204 
00205   memset(dkey, 0, sizeof (DES_KEY));
00206   desinit (dkey);
00207 
00208   
00209 
00210 
00211   for (j = 0; j < 56; j++)
00212     {               
00213       l = pc1[j] - 1;       
00214       m = l & 07;       
00215       pc1m[j] = (user_key[l >> 3] & 
00216          bytebit[m])    
00217     ? 1 : 0;        
00218 
00219     }
00220   for (i = 0; i < 16; i++)
00221     {               
00222       for (j = 0; j < 56; j++)  
00223     pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28];
00224       
00225       for (j = 0; j < 48; j++)
00226     {           
00227       
00228       if (pcr[pc2[j] - 1])
00229         {
00230           
00231           l = j % 6;
00232           dkey->kn[i][j / 6] |= bytebit[l] >> 2;
00233         }
00234     }
00235     }
00236   return 0;
00237 }
00238 
00239 
00240 static void
00241 ntlm_des_encrypt (DES_KEY * key, unsigned char *block)
00242 {
00243   Q_UINT32 left, right;
00244   char *knp;
00245   Q_UINT32 work[2];     
00246 
00247   permute_ip (block, key, (unsigned char *) work);  
00248   left = KFromToBigEndian(work[0]);
00249   right = KFromToBigEndian(work[1]);
00250   
00251   
00252 
00253 
00254 
00255 
00256   knp = &key->kn[0][0];
00257   left ^= f (key, right, knp);
00258   knp += 8;
00259   right ^= f (key, left, knp);
00260   knp += 8;
00261   left ^= f (key, right, knp);
00262   knp += 8;
00263   right ^= f (key, left, knp);
00264   knp += 8;
00265   left ^= f (key, right, knp);
00266   knp += 8;
00267   right ^= f (key, left, knp);
00268   knp += 8;
00269   left ^= f (key, right, knp);
00270   knp += 8;
00271   right ^= f (key, left, knp);
00272   knp += 8;
00273   left ^= f (key, right, knp);
00274   knp += 8;
00275   right ^= f (key, left, knp);
00276   knp += 8;
00277   left ^= f (key, right, knp);
00278   knp += 8;
00279   right ^= f (key, left, knp);
00280   knp += 8;
00281   left ^= f (key, right, knp);
00282   knp += 8;
00283   right ^= f (key, left, knp);
00284   knp += 8;
00285   left ^= f (key, right, knp);
00286   knp += 8;
00287   right ^= f (key, left, knp);
00288 
00289   
00290   work[1] = KFromToBigEndian( left );
00291   work[0] = KFromToBigEndian( right );
00292 
00293   permute_fp ((unsigned char *) work, key, block);  
00294 }
00295 
00296 
00297 static void
00298 permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock)
00299 {
00300    unsigned char *ib, *ob;  
00301    char *p, *q;
00302    int j;
00303 
00304   
00305   memset(outblock, 0, 8);
00306 
00307   ib = inblock;
00308   for (j = 0; j < 16; j += 2, ib++)
00309     {               
00310       ob = outblock;
00311       p = key->iperm[j][(*ib >> 4) & 0xf];
00312       q = key->iperm[j + 1][*ib & 0xf];
00313       
00314       *ob++ |= *p++ | *q++;
00315       *ob++ |= *p++ | *q++;
00316       *ob++ |= *p++ | *q++;
00317       *ob++ |= *p++ | *q++;
00318       *ob++ |= *p++ | *q++;
00319       *ob++ |= *p++ | *q++;
00320       *ob++ |= *p++ | *q++;
00321       *ob++ |= *p++ | *q++;
00322     }
00323 }
00324 
00325 
00326 static void
00327 permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock)
00328 {
00329    unsigned char *ib, *ob;  
00330    char *p, *q;
00331    int j;
00332 
00333   
00334   memset(outblock, 0, 8);
00335 
00336   ib = inblock;
00337   for (j = 0; j < 16; j += 2, ib++)
00338     {               
00339       ob = outblock;
00340       p = key->fperm[j][(*ib >> 4) & 0xf];
00341       q = key->fperm[j + 1][*ib & 0xf];
00342       
00343       *ob++ |= *p++ | *q++;
00344       *ob++ |= *p++ | *q++;
00345       *ob++ |= *p++ | *q++;
00346       *ob++ |= *p++ | *q++;
00347       *ob++ |= *p++ | *q++;
00348       *ob++ |= *p++ | *q++;
00349       *ob++ |= *p++ | *q++;
00350       *ob++ |= *p++ | *q++;
00351     }
00352 }
00353 
00354 
00355 static Q_UINT32
00356 f (DES_KEY * key,  Q_UINT32 r,  char *subkey)
00357 {
00358    Q_UINT32 *spp;
00359    Q_UINT32 rval, rt;
00360    int er;
00361 
00362 #ifdef  TRACE
00363   printf ("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
00364       r,
00365       subkey[0], subkey[1], subkey[2],
00366       subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
00367 #endif
00368   
00369 
00370 
00371 
00372 
00373   subkey += 7;
00374 
00375   
00376   er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0);
00377   spp = &key->sp[7][0];
00378   rval = spp[(er ^ *subkey--) & 0x3f];
00379   spp -= 64;
00380   rt = (Q_UINT32) r >> 3;
00381   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00382   spp -= 64;
00383   rt >>= 4;
00384   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00385   spp -= 64;
00386   rt >>= 4;
00387   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00388   spp -= 64;
00389   rt >>= 4;
00390   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00391   spp -= 64;
00392   rt >>= 4;
00393   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00394   spp -= 64;
00395   rt >>= 4;
00396   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00397   spp -= 64;
00398   rt >>= 4;
00399   rt |= (r & 1) << 5;
00400   rval |= spp[((int) rt ^ *subkey) & 0x3f];
00401 #ifdef  TRACE
00402   printf (" %08lx\n", rval);
00403 #endif
00404   return rval;
00405 }
00406 
00407 
00408 static void
00409 perminit_ip (DES_KEY * key)
00410 {
00411    int l, j, k;
00412   int i, m;
00413 
00414   
00415   memset(key->iperm, 0, 16 * 16 * 8);
00416 
00417   for (i = 0; i < 16; i++)  
00418     for (j = 0; j < 16; j++)    
00419       for (k = 0; k < 64; k++)
00420     {           
00421       l = ip[k] - 1;    
00422       if ((l >> 2) != i)    
00423         continue;       
00424       if (!(j & nibblebit[l & 3]))
00425         continue;       
00426       m = k & 07;       
00427       key->iperm[i][j][k >> 3] |= bytebit[m];
00428     }
00429 }
00430 
00431 static void
00432 perminit_fp (DES_KEY * key)
00433 {
00434   int l, j, k;
00435   int i, m;
00436 
00437   
00438   memset(key->fperm, 0, 16 * 16 * 8);
00439 
00440   for (i = 0; i < 16; i++)  
00441     for (j = 0; j < 16; j++)    
00442       for (k = 0; k < 64; k++)
00443     {           
00444       l = fp[k] - 1;    
00445       if ((l >> 2) != i)    
00446         continue;       
00447       if (!(j & nibblebit[l & 3]))
00448         continue;       
00449       m = k & 07;       
00450       key->fperm[i][j][k >> 3] |= bytebit[m];
00451     }
00452 }
00453 
00454 
00455 static void
00456 spinit (DES_KEY * key)
00457 {
00458   char pbox[32];
00459   int p, i, s, j, rowcol;
00460   Q_UINT32 val;
00461 
00462   
00463 
00464 
00465   for (p = 0; p < 32; p++)
00466     {
00467       for (i = 0; i < 32; i++)
00468     {
00469       if (p32i[i] - 1 == p)
00470         {
00471           pbox[p] = i;
00472           break;
00473         }
00474     }
00475     }
00476   for (s = 0; s < 8; s++)
00477     {               
00478       for (i = 0; i < 64; i++)
00479     {           
00480       val = 0;
00481       
00482 
00483 
00484       rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
00485       for (j = 0; j < 4; j++)
00486         {           
00487           if (si[s][rowcol] & (8 >> j))
00488         {
00489           val |= 1L << (31 - pbox[4 * s + j]);
00490         }
00491         }
00492       key->sp[s][i] = val;
00493     }
00494     }
00495 }
00496 
00497 int
00498 ntlm_des_ecb_encrypt (const void *plaintext, int len, DES_KEY * akey,
00499               unsigned char output[8])
00500 {
00501   int j;
00502   const unsigned char *plain = (const unsigned char *) plaintext;
00503 
00504   for (j = 0; j < len / 8; j++)
00505     {
00506       memcpy (&output[j * 8], &plain[j * 8], 8);
00507       ntlm_des_encrypt (akey, &output[j * 8]);
00508     }
00509 
00510   if (j == 0 && len != 0)
00511     return -1;          
00512   return 0;
00513 }