2 Unix SMB/CIFS implementation.
4 a partial implementation of DES designed for use in the
5 SMB authentication protocol
7 Copyright (C) Andrew Tridgell 1998
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libcli/auth/libcli_auth.h"
26 #include <gnutls/gnutls.h>
27 #include <gnutls/crypto.h>
31 This code makes no attempt to be fast! In fact, it is a very
34 This code is NOT a complete DES implementation. It implements only
35 the minimum necessary for SMB authentication, as used by all SMB
36 products (including every copy of Microsoft Windows95 ever sold)
38 In particular, it can only do a unchained forward DES pass. This
39 means it is not possible to use this code for encryption/decryption
40 of data, instead it is only useful as a "hash" algorithm.
42 There is no entry point into this code that allows normal DES operation.
44 I believe this means that this code does not come under ITAR
45 regulations but this is NOT a legal opinion. If you are concerned
46 about the applicability of ITAR regulations to this code then you
47 should confirm it for yourself (and maybe let me know if you come
48 up with a different answer to the one above)
52 static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9,
53 1, 58, 50, 42, 34, 26, 18,
54 10, 2, 59, 51, 43, 35, 27,
55 19, 11, 3, 60, 52, 44, 36,
56 63, 55, 47, 39, 31, 23, 15,
57 7, 62, 54, 46, 38, 30, 22,
58 14, 6, 61, 53, 45, 37, 29,
59 21, 13, 5, 28, 20, 12, 4};
61 static const uint8_t perm2[48] = {14, 17, 11, 24, 1, 5,
65 41, 52, 31, 37, 47, 55,
66 30, 40, 51, 45, 33, 48,
67 44, 49, 39, 56, 34, 53,
68 46, 42, 50, 36, 29, 32};
70 static const uint8_t perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
71 60, 52, 44, 36, 28, 20, 12, 4,
72 62, 54, 46, 38, 30, 22, 14, 6,
73 64, 56, 48, 40, 32, 24, 16, 8,
74 57, 49, 41, 33, 25, 17, 9, 1,
75 59, 51, 43, 35, 27, 19, 11, 3,
76 61, 53, 45, 37, 29, 21, 13, 5,
77 63, 55, 47, 39, 31, 23, 15, 7};
79 static const uint8_t perm4[48] = { 32, 1, 2, 3, 4, 5,
82 12, 13, 14, 15, 16, 17,
83 16, 17, 18, 19, 20, 21,
84 20, 21, 22, 23, 24, 25,
85 24, 25, 26, 27, 28, 29,
86 28, 29, 30, 31, 32, 1};
88 static const uint8_t perm5[32] = { 16, 7, 20, 21,
98 static const uint8_t perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
99 39, 7, 47, 15, 55, 23, 63, 31,
100 38, 6, 46, 14, 54, 22, 62, 30,
101 37, 5, 45, 13, 53, 21, 61, 29,
102 36, 4, 44, 12, 52, 20, 60, 28,
103 35, 3, 43, 11, 51, 19, 59, 27,
104 34, 2, 42, 10, 50, 18, 58, 26,
105 33, 1, 41, 9, 49, 17, 57, 25};
108 static const uint8_t sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
110 static const uint8_t sbox[8][4][16] = {
111 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
112 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
113 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
114 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
116 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
117 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
118 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
119 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
121 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
122 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
123 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
124 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
126 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
127 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
128 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
129 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
131 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
132 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
133 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
134 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
136 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
137 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
138 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
139 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
141 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
142 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
143 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
144 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
146 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
147 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
148 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
149 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
151 static void permute(char *out, const char *in, const uint8_t *p, int n)
158 static void lshift(char *d, int count, int n)
163 out[i] = d[(i+count)%n];
168 static void concat(char *out, char *in1, char *in2, int l1, int l2)
176 static void xor(char *out, char *in1, char *in2, int n)
180 out[i] = in1[i] ^ in2[i];
183 static void dohash(char *out, char *in, char *key, int forw)
195 permute(pk1, key, perm1, 56);
203 lshift(c, sc[i], 28);
204 lshift(d, sc[i], 28);
206 concat(cd, c, d, 28, 28);
207 permute(ki[i], cd, perm2, 48);
210 permute(pd1, in, perm3, 64);
225 permute(er, r, perm4, 48);
227 xor(erk, er, ki[forw ? i : 15 - i], 48);
231 b[j][k] = erk[j*6 + k];
235 m = (b[j][0]<<1) | b[j][5];
237 n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
240 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
246 permute(pcb, cb, perm5, 32);
257 concat(rl, r, l, 32, 32);
259 permute(out, rl, perm6, 64);
262 static void str_to_key(const uint8_t *str,uint8_t *key)
267 key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
268 key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
269 key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
270 key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
271 key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
272 key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
273 key[7] = str[6]&0x7F;
275 key[i] = (key[i]<<1);
279 int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8],
280 const uint8_t key_in[7],
281 enum samba_gnutls_direction encrypt)
284 * A single block DES-CBC op, with an all-zero IV is the same as DES
285 * because the IV is combined with the data using XOR.
286 * This allows us to use GNUTLS_CIPHER_DES_CBC from GnuTLS and not
287 * implement single-DES in Samba.
289 * In turn this is used to build DES-ECB, which is used
290 * for example in the NTLM challenge/response calculation.
292 static const uint8_t iv8[8];
293 gnutls_datum_t iv = { discard_const(iv8), 8 };
295 gnutls_cipher_hd_t ctx;
302 str_to_key(key_in, key2);
307 ret = gnutls_global_init();
312 ret = gnutls_cipher_init(&ctx, GNUTLS_CIPHER_DES_CBC, &key, &iv);
318 if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
319 ret = gnutls_cipher_encrypt(ctx, outb, 8);
321 ret = gnutls_cipher_decrypt(ctx, outb, 8);
325 memcpy(out, outb, 8);
328 gnutls_cipher_deinit(ctx);
334 basic des crypt using a 56 bit (7 byte) key
336 void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw)
344 str_to_key(key, key2);
347 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
348 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
352 dohash(outb, inb, keyb, forw);
360 out[i/8] |= (1<<(7-(i%8)));
364 int E_P16(const uint8_t *p14,uint8_t *p16)
366 const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
369 ret = des_crypt56_gnutls(p16, sp8, p14, SAMBA_GNUTLS_ENCRYPT);
374 return des_crypt56_gnutls(p16+8, sp8, p14+7, SAMBA_GNUTLS_ENCRYPT);
377 int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24)
381 ret = des_crypt56_gnutls(p24, c8, p21, SAMBA_GNUTLS_ENCRYPT);
386 ret = des_crypt56_gnutls(p24+8, c8, p21+7, SAMBA_GNUTLS_ENCRYPT);
391 return des_crypt56_gnutls(p24+16, c8, p21+14, SAMBA_GNUTLS_ENCRYPT);
394 int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out)
398 ret = des_crypt56_gnutls(out, in, p14, SAMBA_GNUTLS_ENCRYPT);
403 return des_crypt56_gnutls(out+8, in+8, p14+7, SAMBA_GNUTLS_ENCRYPT);
406 /* des encryption with a 128 bit key */
407 int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16])
412 ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
417 return des_crypt56_gnutls(out, buf, key+9, SAMBA_GNUTLS_ENCRYPT);
420 /* des encryption with a 112 bit (14 byte) key */
421 int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14],
422 enum samba_gnutls_direction encrypt)
427 if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
428 ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
433 return des_crypt56_gnutls(out, buf, key+7, SAMBA_GNUTLS_ENCRYPT);
436 ret = des_crypt56_gnutls(buf, in, key+7, SAMBA_GNUTLS_DECRYPT);
441 return des_crypt56_gnutls(out, buf, key, SAMBA_GNUTLS_DECRYPT);
444 /* des encryption of a 16 byte lump of data with a 112 bit key */
445 void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw)
447 des_crypt56(out, in, key, forw);
448 des_crypt56(out + 8, in + 8, key+7, forw);
451 /* Decode a sam password hash into a password. The password hash is the
452 same method used to store passwords in the NT registry. The DES key
453 used is based on the RID of the user. */
454 int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out,
455 enum samba_gnutls_direction encrypt)
460 s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF);
461 s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF);
462 s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF);
463 s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF);
465 ret = des_crypt56_gnutls(out, in, s, encrypt);
469 return des_crypt56_gnutls(out+8, in+8, s+7, encrypt);