root/src/vfs/smbfs/helpers/libsmb/smbdes.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. permute
  2. lshift
  3. concat
  4. xor
  5. dohash
  6. str_to_key
  7. smbhash
  8. E_P16
  9. E_P24
  10. D_P16
  11. E_old_pw_hash
  12. cred_hash1
  13. cred_hash2
  14. cred_hash3
  15. SamOEMhash

   1 /*
   2    Unix SMB/Netbios implementation.
   3    Version 1.9.
   4 
   5    a partial implementation of DES designed for use in the 
   6    SMB authentication protocol
   7 
   8    Copyright (C) Andrew Tridgell 1998
   9 
  10    Copyright (C) 2011-2019
  11    Free Software Foundation, Inc.
  12 
  13    This file is part of the Midnight Commander.
  14 
  15    The Midnight Commander is free software: you can redistribute it
  16    and/or modify it under the terms of the GNU General Public License as
  17    published by the Free Software Foundation, either version 3 of the License,
  18    or (at your option) any later version.
  19 
  20    The Midnight Commander is distributed in the hope that it will be useful,
  21    but WITHOUT ANY WARRANTY; without even the implied warranty of
  22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23    GNU General Public License for more details.
  24 
  25    You should have received a copy of the GNU General Public License
  26    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  27  */
  28 
  29 #include "includes.h"
  30 
  31 /* NOTES: 
  32 
  33    This code makes no attempt to be fast! In fact, it is a very
  34    slow implementation 
  35 
  36    This code is NOT a complete DES implementation. It implements only
  37    the minimum necessary for SMB authentication, as used by all SMB
  38    products (including every copy of Microsoft Windows95 ever sold)
  39 
  40    In particular, it can only do a unchained forward DES pass. This
  41    means it is not possible to use this code for encryption/decryption
  42    of data, instead it is only useful as a "hash" algorithm.
  43 
  44    There is no entry point into this code that allows normal DES operation.
  45 
  46    I believe this means that this code does not come under ITAR
  47    regulations but this is NOT a legal opinion. If you are concerned
  48    about the applicability of ITAR regulations to this code then you
  49    should confirm it for yourself (and maybe let me know if you come
  50    up with a different answer to the one above)
  51  */
  52 
  53 #undef  uchar
  54 #define uchar const unsigned char
  55 
  56 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
  57     1, 58, 50, 42, 34, 26, 18,
  58     10, 2, 59, 51, 43, 35, 27,
  59     19, 11, 3, 60, 52, 44, 36,
  60     63, 55, 47, 39, 31, 23, 15,
  61     7, 62, 54, 46, 38, 30, 22,
  62     14, 6, 61, 53, 45, 37, 29,
  63     21, 13, 5, 28, 20, 12, 4
  64 };
  65 
  66 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
  67     3, 28, 15, 6, 21, 10,
  68     23, 19, 12, 4, 26, 8,
  69     16, 7, 27, 20, 13, 2,
  70     41, 52, 31, 37, 47, 55,
  71     30, 40, 51, 45, 33, 48,
  72     44, 49, 39, 56, 34, 53,
  73     46, 42, 50, 36, 29, 32
  74 };
  75 
  76 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
  77     60, 52, 44, 36, 28, 20, 12, 4,
  78     62, 54, 46, 38, 30, 22, 14, 6,
  79     64, 56, 48, 40, 32, 24, 16, 8,
  80     57, 49, 41, 33, 25, 17, 9, 1,
  81     59, 51, 43, 35, 27, 19, 11, 3,
  82     61, 53, 45, 37, 29, 21, 13, 5,
  83     63, 55, 47, 39, 31, 23, 15, 7
  84 };
  85 
  86 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
  87     4, 5, 6, 7, 8, 9,
  88     8, 9, 10, 11, 12, 13,
  89     12, 13, 14, 15, 16, 17,
  90     16, 17, 18, 19, 20, 21,
  91     20, 21, 22, 23, 24, 25,
  92     24, 25, 26, 27, 28, 29,
  93     28, 29, 30, 31, 32, 1
  94 };
  95 
  96 static uchar perm5[32] = { 16, 7, 20, 21,
  97     29, 12, 28, 17,
  98     1, 15, 23, 26,
  99     5, 18, 31, 10,
 100     2, 8, 24, 14,
 101     32, 27, 3, 9,
 102     19, 13, 30, 6,
 103     22, 11, 4, 25
 104 };
 105 
 106 
 107 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
 108     39, 7, 47, 15, 55, 23, 63, 31,
 109     38, 6, 46, 14, 54, 22, 62, 30,
 110     37, 5, 45, 13, 53, 21, 61, 29,
 111     36, 4, 44, 12, 52, 20, 60, 28,
 112     35, 3, 43, 11, 51, 19, 59, 27,
 113     34, 2, 42, 10, 50, 18, 58, 26,
 114     33, 1, 41, 9, 49, 17, 57, 25
 115 };
 116 
 117 
 118 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
 119 
 120 static uchar sbox[8][4][16] = {
 121     {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
 122      {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
 123      {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
 124      {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
 125 
 126     {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
 127      {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
 128      {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
 129      {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
 130 
 131     {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
 132      {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
 133      {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
 134      {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
 135 
 136     {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
 137      {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
 138      {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
 139      {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
 140 
 141     {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
 142      {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
 143      {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
 144      {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
 145 
 146     {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
 147      {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
 148      {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
 149      {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
 150 
 151     {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
 152      {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
 153      {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
 154      {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
 155 
 156     {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
 157      {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
 158      {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
 159      {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
 160 };
 161 
 162 static void
 163 permute (char *out, char *in, uchar * p, int n)
     /* [previous][next][first][last][top][bottom][index][help]  */
 164 {
 165     int i;
 166     for (i = 0; i < n; i++)
 167         out[i] = in[p[i] - 1];
 168 }
 169 
 170 static void
 171 lshift (char *d, int count, int n)
     /* [previous][next][first][last][top][bottom][index][help]  */
 172 {
 173     char out[64];
 174     int i;
 175     for (i = 0; i < n; i++)
 176         out[i] = d[(i + count) % n];
 177     for (i = 0; i < n; i++)
 178         d[i] = out[i];
 179 }
 180 
 181 static void
 182 concat (char *out, char *in1, char *in2, int l1, int l2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 183 {
 184     while (l1--)
 185         *out++ = *in1++;
 186     while (l2--)
 187         *out++ = *in2++;
 188 }
 189 
 190 static void
 191 xor (char *out, char *in1, char *in2, int n)
     /* [previous][next][first][last][top][bottom][index][help]  */
 192 {
 193     int i;
 194     for (i = 0; i < n; i++)
 195         out[i] = in1[i] ^ in2[i];
 196 }
 197 
 198 static void
 199 dohash (char *out, char *in, char *key, int forw)
     /* [previous][next][first][last][top][bottom][index][help]  */
 200 {
 201     int i, j, k;
 202     char pk1[56];
 203     char c[28];
 204     char d[28];
 205     char cd[56];
 206     char ki[16][48];
 207     char pd1[64];
 208     char l[32], r[32];
 209     char rl[64];
 210 
 211     permute (pk1, key, perm1, 56);
 212 
 213     for (i = 0; i < 28; i++)
 214         c[i] = pk1[i];
 215     for (i = 0; i < 28; i++)
 216         d[i] = pk1[i + 28];
 217 
 218     for (i = 0; i < 16; i++)
 219     {
 220         lshift (c, sc[i], 28);
 221         lshift (d, sc[i], 28);
 222 
 223         concat (cd, c, d, 28, 28);
 224         permute (ki[i], cd, perm2, 48);
 225     }
 226 
 227     permute (pd1, in, perm3, 64);
 228 
 229     for (j = 0; j < 32; j++)
 230     {
 231         l[j] = pd1[j];
 232         r[j] = pd1[j + 32];
 233     }
 234 
 235     for (i = 0; i < 16; i++)
 236     {
 237         char er[48];
 238         char erk[48];
 239         char b[8][6];
 240         char cb[32];
 241         char pcb[32];
 242         char r2[32];
 243 
 244         permute (er, r, perm4, 48);
 245 
 246         xor (erk, er, ki[forw ? i : 15 - i], 48);
 247 
 248         for (j = 0; j < 8; j++)
 249             for (k = 0; k < 6; k++)
 250                 b[j][k] = erk[j * 6 + k];
 251 
 252         for (j = 0; j < 8; j++)
 253         {
 254             int m, n;
 255             m = (b[j][0] << 1) | b[j][5];
 256 
 257             n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4];
 258 
 259             for (k = 0; k < 4; k++)
 260                 b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
 261         }
 262 
 263         for (j = 0; j < 8; j++)
 264             for (k = 0; k < 4; k++)
 265                 cb[j * 4 + k] = b[j][k];
 266         permute (pcb, cb, perm5, 32);
 267 
 268         xor (r2, l, pcb, 32);
 269 
 270         for (j = 0; j < 32; j++)
 271             l[j] = r[j];
 272 
 273         for (j = 0; j < 32; j++)
 274             r[j] = r2[j];
 275     }
 276 
 277     concat (rl, r, l, 32, 32);
 278 
 279     permute (out, rl, perm6, 64);
 280 }
 281 
 282 static void
 283 str_to_key (unsigned char *str, unsigned char *key)
     /* [previous][next][first][last][top][bottom][index][help]  */
 284 {
 285     int i;
 286 
 287     key[0] = str[0] >> 1;
 288     key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
 289     key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
 290     key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
 291     key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
 292     key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
 293     key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
 294     key[7] = str[6] & 0x7F;
 295     for (i = 0; i < 8; i++)
 296     {
 297         key[i] = (key[i] << 1);
 298     }
 299 }
 300 
 301 
 302 static void
 303 smbhash (unsigned char *out, unsigned char *in, unsigned char *key, int forw)
     /* [previous][next][first][last][top][bottom][index][help]  */
 304 {
 305     int i;
 306     char outb[64];
 307     char inb[64];
 308     char keyb[64];
 309     unsigned char key2[8];
 310 
 311     str_to_key (key, key2);
 312 
 313     for (i = 0; i < 64; i++)
 314     {
 315         inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
 316         keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
 317         outb[i] = 0;
 318     }
 319 
 320     dohash (outb, inb, keyb, forw);
 321 
 322     for (i = 0; i < 8; i++)
 323     {
 324         out[i] = 0;
 325     }
 326 
 327     for (i = 0; i < 64; i++)
 328     {
 329         if (outb[i])
 330             out[i / 8] |= (1 << (7 - (i % 8)));
 331     }
 332 }
 333 
 334 void
 335 E_P16 (unsigned char *p14, unsigned char *p16)
     /* [previous][next][first][last][top][bottom][index][help]  */
 336 {
 337     unsigned char sp8[8] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
 338     smbhash (p16, sp8, p14, 1);
 339     smbhash (p16 + 8, sp8, p14 + 7, 1);
 340 }
 341 
 342 void
 343 E_P24 (unsigned char *p21, unsigned char *c8, unsigned char *p24)
     /* [previous][next][first][last][top][bottom][index][help]  */
 344 {
 345     smbhash (p24, c8, p21, 1);
 346     smbhash (p24 + 8, c8, p21 + 7, 1);
 347     smbhash (p24 + 16, c8, p21 + 14, 1);
 348 }
 349 
 350 #if 0
 351 void
 352 D_P16 (unsigned char *p14, unsigned char *in, unsigned char *out)
     /* [previous][next][first][last][top][bottom][index][help]  */
 353 {
 354     smbhash (out, in, p14, 0);
 355     smbhash (out + 8, in + 8, p14 + 7, 0);
 356 }
 357 
 358 void
 359 E_old_pw_hash (unsigned char *p14, unsigned char *in, unsigned char *out)
     /* [previous][next][first][last][top][bottom][index][help]  */
 360 {
 361     smbhash (out, in, p14, 1);
 362     smbhash (out + 8, in + 8, p14 + 7, 1);
 363 }
 364 
 365 void
 366 cred_hash1 (unsigned char *out, unsigned char *in, unsigned char *key)
     /* [previous][next][first][last][top][bottom][index][help]  */
 367 {
 368     unsigned char buf[8];
 369 
 370     smbhash (buf, in, key, 1);
 371     smbhash (out, buf, key + 9, 1);
 372 }
 373 
 374 void
 375 cred_hash2 (unsigned char *out, unsigned char *in, unsigned char *key)
     /* [previous][next][first][last][top][bottom][index][help]  */
 376 {
 377     unsigned char buf[8];
 378     static unsigned char key2[8];
 379 
 380     smbhash (buf, in, key, 1);
 381     key2[0] = key[7];
 382     smbhash (out, buf, key2, 1);
 383 }
 384 
 385 void
 386 cred_hash3 (unsigned char *out, unsigned char *in, unsigned char *key, int forw)
     /* [previous][next][first][last][top][bottom][index][help]  */
 387 {
 388     static unsigned char key2[8];
 389 
 390     smbhash (out, in, key, forw);
 391     key2[0] = key[7];
 392     smbhash (out + 8, in + 8, key2, forw);
 393 }
 394 
 395 void
 396 SamOEMhash (unsigned char *data, unsigned char *key, int val)
     /* [previous][next][first][last][top][bottom][index][help]  */
 397 {
 398     unsigned char s_box[256];
 399     unsigned char index_i = 0;
 400     unsigned char index_j = 0;
 401     unsigned char j = 0;
 402     int ind;
 403 
 404     for (ind = 0; ind < 256; ind++)
 405     {
 406         s_box[ind] = (unsigned char) ind;
 407     }
 408 
 409     for (ind = 0; ind < 256; ind++)
 410     {
 411         unsigned char tc;
 412 
 413         j += (s_box[ind] + key[ind % 16]);
 414 
 415         tc = s_box[ind];
 416         s_box[ind] = s_box[j];
 417         s_box[j] = tc;
 418     }
 419     for (ind = 0; ind < (val ? 516 : 16); ind++)
 420     {
 421         unsigned char tc;
 422         unsigned char t;
 423 
 424         index_i++;
 425         index_j += s_box[index_i];
 426 
 427         tc = s_box[index_i];
 428         s_box[index_i] = s_box[index_j];
 429         s_box[index_j] = tc;
 430 
 431         t = s_box[index_i] + s_box[index_j];
 432         data[ind] = data[ind] ^ s_box[t];
 433     }
 434 }
 435 #endif /* 0 */

/* [previous][next][first][last][top][bottom][index][help]  */