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>
29 static void str_to_key(const uint8_t *str
,uint8_t *key
)
34 key
[1] = ((str
[0]&0x01)<<6) | (str
[1]>>2);
35 key
[2] = ((str
[1]&0x03)<<5) | (str
[2]>>3);
36 key
[3] = ((str
[2]&0x07)<<4) | (str
[3]>>4);
37 key
[4] = ((str
[3]&0x0F)<<3) | (str
[4]>>5);
38 key
[5] = ((str
[4]&0x1F)<<2) | (str
[5]>>6);
39 key
[6] = ((str
[5]&0x3F)<<1) | (str
[6]>>7);
46 int des_crypt56_gnutls(uint8_t out
[8], const uint8_t in
[8],
47 const uint8_t key_in
[7],
48 enum samba_gnutls_direction encrypt
)
51 * A single block DES-CBC op, with an all-zero IV is the same as DES
52 * because the IV is combined with the data using XOR.
53 * This allows us to use GNUTLS_CIPHER_DES_CBC from GnuTLS and not
54 * implement single-DES in Samba.
56 * In turn this is used to build DES-ECB, which is used
57 * for example in the NTLM challenge/response calculation.
59 static const uint8_t iv8
[8];
60 gnutls_datum_t iv
= { discard_const(iv8
), 8 };
62 gnutls_cipher_hd_t ctx
;
69 str_to_key(key_in
, key2
);
74 ret
= gnutls_global_init();
79 ret
= gnutls_cipher_init(&ctx
, GNUTLS_CIPHER_DES_CBC
, &key
, &iv
);
85 if (encrypt
== SAMBA_GNUTLS_ENCRYPT
) {
86 ret
= gnutls_cipher_encrypt(ctx
, outb
, 8);
88 ret
= gnutls_cipher_decrypt(ctx
, outb
, 8);
95 gnutls_cipher_deinit(ctx
);
100 int E_P16(const uint8_t *p14
,uint8_t *p16
)
102 const uint8_t sp8
[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
105 ret
= des_crypt56_gnutls(p16
, sp8
, p14
, SAMBA_GNUTLS_ENCRYPT
);
110 return des_crypt56_gnutls(p16
+8, sp8
, p14
+7, SAMBA_GNUTLS_ENCRYPT
);
113 int E_P24(const uint8_t *p21
, const uint8_t *c8
, uint8_t *p24
)
117 ret
= des_crypt56_gnutls(p24
, c8
, p21
, SAMBA_GNUTLS_ENCRYPT
);
122 ret
= des_crypt56_gnutls(p24
+8, c8
, p21
+7, SAMBA_GNUTLS_ENCRYPT
);
127 return des_crypt56_gnutls(p24
+16, c8
, p21
+14, SAMBA_GNUTLS_ENCRYPT
);
130 int E_old_pw_hash( uint8_t *p14
, const uint8_t *in
, uint8_t *out
)
134 ret
= des_crypt56_gnutls(out
, in
, p14
, SAMBA_GNUTLS_ENCRYPT
);
139 return des_crypt56_gnutls(out
+8, in
+8, p14
+7, SAMBA_GNUTLS_ENCRYPT
);
142 /* des encryption with a 128 bit key */
143 int des_crypt128(uint8_t out
[8], const uint8_t in
[8], const uint8_t key
[16])
148 ret
= des_crypt56_gnutls(buf
, in
, key
, SAMBA_GNUTLS_ENCRYPT
);
153 return des_crypt56_gnutls(out
, buf
, key
+9, SAMBA_GNUTLS_ENCRYPT
);
156 /* des encryption with a 112 bit (14 byte) key */
157 int des_crypt112(uint8_t out
[8], const uint8_t in
[8], const uint8_t key
[14],
158 enum samba_gnutls_direction encrypt
)
163 if (encrypt
== SAMBA_GNUTLS_ENCRYPT
) {
164 ret
= des_crypt56_gnutls(buf
, in
, key
, SAMBA_GNUTLS_ENCRYPT
);
169 return des_crypt56_gnutls(out
, buf
, key
+7, SAMBA_GNUTLS_ENCRYPT
);
172 ret
= des_crypt56_gnutls(buf
, in
, key
+7, SAMBA_GNUTLS_DECRYPT
);
177 return des_crypt56_gnutls(out
, buf
, key
, SAMBA_GNUTLS_DECRYPT
);
180 /* des encryption of a 16 byte lump of data with a 112 bit key */
181 int des_crypt112_16(uint8_t out
[16], const uint8_t in
[16], const uint8_t key
[14],
182 enum samba_gnutls_direction encrypt
)
186 ret
= des_crypt56_gnutls(out
, in
, key
, encrypt
);
191 return des_crypt56_gnutls(out
+ 8, in
+ 8, key
+7, encrypt
);
194 /* Decode a sam password hash into a password. The password hash is the
195 same method used to store passwords in the NT registry. The DES key
196 used is based on the RID of the user. */
197 int sam_rid_crypt(unsigned int rid
, const uint8_t *in
, uint8_t *out
,
198 enum samba_gnutls_direction encrypt
)
203 s
[0] = s
[4] = s
[8] = s
[12] = (uint8_t)(rid
& 0xFF);
204 s
[1] = s
[5] = s
[9] = s
[13] = (uint8_t)((rid
>> 8) & 0xFF);
205 s
[2] = s
[6] = s
[10] = (uint8_t)((rid
>> 16) & 0xFF);
206 s
[3] = s
[7] = s
[11] = (uint8_t)((rid
>> 24) & 0xFF);
208 ret
= des_crypt56_gnutls(out
, in
, s
, encrypt
);
212 return des_crypt56_gnutls(out
+8, in
+8, s
+7, encrypt
);