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 }