libsmb/smbdes.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003 
00004    a partial implementation of DES designed for use in the 
00005    SMB authentication protocol
00006 
00007    Copyright (C) Andrew Tridgell 1998
00008    
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013    
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018    
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 */
00023 
00024 #include "includes.h"
00025 
00026 /* NOTES: 
00027 
00028    This code makes no attempt to be fast! In fact, it is a very
00029    slow implementation 
00030 
00031    This code is NOT a complete DES implementation. It implements only
00032    the minimum necessary for SMB authentication, as used by all SMB
00033    products (including every copy of Microsoft Windows95 ever sold)
00034 
00035    In particular, it can only do a unchained forward DES pass. This
00036    means it is not possible to use this code for encryption/decryption
00037    of data, instead it is only useful as a "hash" algorithm.
00038 
00039    There is no entry point into this code that allows normal DES operation.
00040 
00041    I believe this means that this code does not come under ITAR
00042    regulations but this is NOT a legal opinion. If you are concerned
00043    about the applicability of ITAR regulations to this code then you
00044    should confirm it for yourself (and maybe let me know if you come
00045    up with a different answer to the one above)
00046 */
00047 
00048 
00049 #define uchar unsigned char
00050 
00051 static const uchar perm1[56] = {57, 49, 41, 33, 25, 17,  9,
00052                          1, 58, 50, 42, 34, 26, 18,
00053                         10,  2, 59, 51, 43, 35, 27,
00054                         19, 11,  3, 60, 52, 44, 36,
00055                         63, 55, 47, 39, 31, 23, 15,
00056                          7, 62, 54, 46, 38, 30, 22,
00057                         14,  6, 61, 53, 45, 37, 29,
00058                         21, 13,  5, 28, 20, 12,  4};
00059 
00060 static const uchar perm2[48] = {14, 17, 11, 24,  1,  5,
00061                          3, 28, 15,  6, 21, 10,
00062                         23, 19, 12,  4, 26,  8,
00063                         16,  7, 27, 20, 13,  2,
00064                         41, 52, 31, 37, 47, 55,
00065                         30, 40, 51, 45, 33, 48,
00066                         44, 49, 39, 56, 34, 53,
00067                         46, 42, 50, 36, 29, 32};
00068 
00069 static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10,  2,
00070                         60, 52, 44, 36, 28, 20, 12,  4,
00071                         62, 54, 46, 38, 30, 22, 14,  6,
00072                         64, 56, 48, 40, 32, 24, 16,  8,
00073                         57, 49, 41, 33, 25, 17,  9,  1,
00074                         59, 51, 43, 35, 27, 19, 11,  3,
00075                         61, 53, 45, 37, 29, 21, 13,  5,
00076                         63, 55, 47, 39, 31, 23, 15,  7};
00077 
00078 static const uchar perm4[48] = {   32,  1,  2,  3,  4,  5,
00079                             4,  5,  6,  7,  8,  9,
00080                             8,  9, 10, 11, 12, 13,
00081                            12, 13, 14, 15, 16, 17,
00082                            16, 17, 18, 19, 20, 21,
00083                            20, 21, 22, 23, 24, 25,
00084                            24, 25, 26, 27, 28, 29,
00085                            28, 29, 30, 31, 32,  1};
00086 
00087 static const uchar perm5[32] = {      16,  7, 20, 21,
00088                               29, 12, 28, 17,
00089                                1, 15, 23, 26,
00090                                5, 18, 31, 10,
00091                                2,  8, 24, 14,
00092                               32, 27,  3,  9,
00093                               19, 13, 30,  6,
00094                               22, 11,  4, 25};
00095 
00096 
00097 static const uchar perm6[64] ={ 40,  8, 48, 16, 56, 24, 64, 32,
00098                         39,  7, 47, 15, 55, 23, 63, 31,
00099                         38,  6, 46, 14, 54, 22, 62, 30,
00100                         37,  5, 45, 13, 53, 21, 61, 29,
00101                         36,  4, 44, 12, 52, 20, 60, 28,
00102                         35,  3, 43, 11, 51, 19, 59, 27,
00103                         34,  2, 42, 10, 50, 18, 58, 26,
00104                         33,  1, 41,  9, 49, 17, 57, 25};
00105 
00106 
00107 static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
00108 
00109 static const uchar sbox[8][4][16] = {
00110         {{14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
00111          {0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
00112          {4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
00113          {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13}},
00114 
00115         {{15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
00116          {3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
00117          {0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
00118          {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9}},
00119 
00120         {{10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
00121          {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
00122          {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
00123          {1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12}},
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         {{2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
00131          {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
00132          {4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
00133          {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3}},
00134 
00135         {{12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
00136          {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
00137          {9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
00138          {4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13}},
00139 
00140         {{4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
00141          {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
00142          {1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
00143          {6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12}},
00144 
00145         {{13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
00146          {1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
00147          {7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
00148          {2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}}};
00149 
00150 static void permute(char *out, const char *in, const uchar *p, int n)
00151 {
00152         int i;
00153         for (i=0;i<n;i++)
00154                 out[i] = in[p[i]-1];
00155 }
00156 
00157 static void lshift(char *d, int count, int n)
00158 {
00159         char out[64];
00160         int i;
00161         for (i=0;i<n;i++)
00162                 out[i] = d[(i+count)%n];
00163         for (i=0;i<n;i++)
00164                 d[i] = out[i];
00165 }
00166 
00167 static void concat(char *out, char *in1, char *in2, int l1, int l2)
00168 {
00169         while (l1--)
00170                 *out++ = *in1++;
00171         while (l2--)
00172                 *out++ = *in2++;
00173 }
00174 
00175 static void x_or(char *out, char *in1, char *in2, int n)
00176 {
00177         int i;
00178         for (i=0;i<n;i++)
00179                 out[i] = in1[i] ^ in2[i];
00180 }
00181 
00182 static void dohash(char *out, char *in, char *key, int forw)
00183 {
00184         int i, j, k;
00185         char pk1[56];
00186         char c[28];
00187         char d[28];
00188         char cd[56];
00189         char ki[16][48];
00190         char pd1[64];
00191         char l[32], r[32];
00192         char rl[64];
00193 
00194         permute(pk1, key, perm1, 56);
00195 
00196         for (i=0;i<28;i++)
00197                 c[i] = pk1[i];
00198         for (i=0;i<28;i++)
00199                 d[i] = pk1[i+28];
00200 
00201         for (i=0;i<16;i++) {
00202                 lshift(c, sc[i], 28);
00203                 lshift(d, sc[i], 28);
00204 
00205                 concat(cd, c, d, 28, 28); 
00206                 permute(ki[i], cd, perm2, 48); 
00207         }
00208 
00209         permute(pd1, in, perm3, 64);
00210 
00211         for (j=0;j<32;j++) {
00212                 l[j] = pd1[j];
00213                 r[j] = pd1[j+32];
00214         }
00215 
00216         for (i=0;i<16;i++) {
00217                 char er[48];
00218                 char erk[48];
00219                 char b[8][6];
00220                 char cb[32];
00221                 char pcb[32];
00222                 char r2[32];
00223 
00224                 permute(er, r, perm4, 48);
00225 
00226                 x_or(erk, er, ki[forw ? i : 15 - i], 48);
00227 
00228                 for (j=0;j<8;j++)
00229                         for (k=0;k<6;k++)
00230                                 b[j][k] = erk[j*6 + k];
00231 
00232                 for (j=0;j<8;j++) {
00233                         int m, n;
00234                         m = (b[j][0]<<1) | b[j][5];
00235 
00236                         n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; 
00237 
00238                         for (k=0;k<4;k++) 
00239                                 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; 
00240                 }
00241 
00242                 for (j=0;j<8;j++)
00243                         for (k=0;k<4;k++)
00244                                 cb[j*4+k] = b[j][k];
00245                 permute(pcb, cb, perm5, 32);
00246 
00247                 x_or(r2, l, pcb, 32);
00248 
00249                 for (j=0;j<32;j++)
00250                         l[j] = r[j];
00251 
00252                 for (j=0;j<32;j++)
00253                         r[j] = r2[j];
00254         }
00255 
00256         concat(rl, r, l, 32, 32);
00257 
00258         permute(out, rl, perm6, 64);
00259 }
00260 
00261 /* Convert a 7 byte string to an 8 byte key. */
00262 static void str_to_key(const unsigned char str[7], unsigned char key[8])
00263 {
00264         int i;
00265 
00266         key[0] = str[0]>>1;
00267         key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
00268         key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
00269         key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
00270         key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
00271         key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
00272         key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
00273         key[7] = str[6]&0x7F;
00274         for (i=0;i<8;i++) {
00275                 key[i] = (key[i]<<1);
00276         }
00277 }
00278 
00279 
00280 void des_crypt56(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
00281 {
00282         int i;
00283         char outb[64];
00284         char inb[64];
00285         char keyb[64];
00286         unsigned char key2[8];
00287 
00288         str_to_key(key, key2);
00289 
00290         for (i=0;i<64;i++) {
00291                 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
00292                 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
00293                 outb[i] = 0;
00294         }
00295 
00296         dohash(outb, inb, keyb, forw);
00297 
00298         for (i=0;i<8;i++) {
00299                 out[i] = 0;
00300         }
00301 
00302         for (i=0;i<64;i++) {
00303                 if (outb[i])
00304                         out[i/8] |= (1<<(7-(i%8)));
00305         }
00306 }
00307 
00308 void E_P16(const unsigned char *p14,unsigned char *p16)
00309 {
00310         unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
00311         des_crypt56(p16, sp8, p14, 1);
00312         des_crypt56(p16+8, sp8, p14+7, 1);
00313 }
00314 
00315 void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24)
00316 {
00317         des_crypt56(p24, c8, p21, 1);
00318         des_crypt56(p24+8, c8, p21+7, 1);
00319         des_crypt56(p24+16, c8, p21+14, 1);
00320 }
00321 
00322 void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out)
00323 {
00324         des_crypt56(out, in, p14, 0);
00325         des_crypt56(out+8, in+8, p14+7, 0);
00326 }
00327 
00328 void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out)
00329 {
00330         des_crypt56(out, in, p14, 1);
00331         des_crypt56(out+8, in+8, p14+7, 1);
00332 }
00333 
00334 /* forward des encryption with a 128 bit key */
00335 void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16])
00336 {
00337         unsigned char buf[8];
00338 
00339         des_crypt56(buf, in, key, 1);
00340         des_crypt56(out, buf, key+9, 1);
00341 }
00342 
00343 /* forward des encryption with a 64 bit key */
00344 void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8])
00345 {
00346         unsigned char buf[8];
00347         unsigned char key2[8];
00348 
00349         memset(key2,'\0',8);
00350         des_crypt56(buf, in, key, 1);
00351         key2[0] = key[7];
00352         des_crypt56(out, buf, key2, 1);
00353 }
00354 
00355 /* des encryption with a 112 bit (14 byte) key */
00356 /* Note that if the forw is 1, and key is actually 8 bytes of key, followed by 6 bytes of zeros,
00357    this is identical to des_crypt64(). JRA. */
00358 
00359 void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw)
00360 {
00361         unsigned char buf[8];
00362         des_crypt56(buf, in, key, forw);
00363         des_crypt56(out, buf, key+7, forw);
00364 }
00365 
00366 void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
00367 {
00368         unsigned char key2[8];
00369 
00370         memset(key2,'\0',8);
00371         des_crypt56(out, in, key, forw);
00372         key2[0] = key[7];
00373         des_crypt56(out + 8, in + 8, key2, forw);
00374 }
00375 
00376 /* des encryption of a 16 byte lump of data with a 112 bit key */
00377 /* Note that if the key is actually 8 bytes of key, followed by 6 bytes of zeros,
00378    this is identical to cred_hash3(). JRA. */
00379 
00380 void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw)
00381 {
00382         des_crypt56(out, in, key, forw);
00383         des_crypt56(out + 8, in + 8, key+7, forw);
00384 }
00385 
00386 /*****************************************************************
00387  arc4 crypt/decrypt with a 16 byte key.
00388 *****************************************************************/
00389 
00390 void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len)
00391 {
00392         unsigned char arc4_state[258];
00393 
00394         smb_arc4_init(arc4_state, key, 16);
00395         smb_arc4_crypt(arc4_state, data, len);
00396 }
00397 
00398 void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key)
00399 {
00400         unsigned char arc4_state[258];
00401 
00402         smb_arc4_init(arc4_state, key->data, key->length);
00403         smb_arc4_crypt(arc4_state, data, len);
00404 }
00405 
00406 /* Decode a sam password hash into a password.  The password hash is the
00407    same method used to store passwords in the NT registry.  The DES key
00408    used is based on the RID of the user. */
00409 
00410 void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw)
00411 {
00412         uchar s[14];
00413 
00414         s[0] = s[4] = s[8] = s[12] = (uchar)(rid & 0xFF);
00415         s[1] = s[5] = s[9] = s[13] = (uchar)((rid >> 8) & 0xFF);
00416         s[2] = s[6] = s[10]        = (uchar)((rid >> 16) & 0xFF);
00417         s[3] = s[7] = s[11]        = (uchar)((rid >> 24) & 0xFF);
00418 
00419         des_crypt56(out, in, s, forw);
00420         des_crypt56(out+8, in+8, s+7, forw);
00421 }

Sambaに対してSat Aug 29 21:23:06 2009に生成されました。  doxygen 1.4.7