Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : a partial implementation of DES designed for use in the
5 : SMB authentication protocol
6 :
7 : Copyright (C) Andrew Tridgell 1998
8 :
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.
13 :
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.
18 :
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/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "libcli/auth/libcli_auth.h"
25 :
26 : #include <gnutls/gnutls.h>
27 : #include <gnutls/crypto.h>
28 :
29 187733 : static void str_to_key(const uint8_t *str,uint8_t *key)
30 : {
31 3745 : int i;
32 :
33 187733 : key[0] = str[0]>>1;
34 187733 : key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
35 187733 : key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
36 187733 : key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
37 187733 : key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
38 187733 : key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
39 187733 : key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
40 187733 : key[7] = str[6]&0x7F;
41 1689597 : for (i=0;i<8;i++) {
42 1501864 : key[i] = (key[i]<<1);
43 : }
44 187733 : }
45 :
46 187733 : 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)
49 : {
50 : /*
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.
55 : *
56 : * In turn this is used to build DES-ECB, which is used
57 : * for example in the NTLM challenge/response calculation.
58 : */
59 3745 : static const uint8_t iv8[8];
60 187733 : gnutls_datum_t iv = { discard_const(iv8), 8 };
61 3745 : gnutls_datum_t key;
62 3745 : gnutls_cipher_hd_t ctx;
63 3745 : uint8_t key2[8];
64 3745 : uint8_t outb[8];
65 3745 : int ret;
66 :
67 187733 : memset(out, 0, 8);
68 :
69 187733 : str_to_key(key_in, key2);
70 :
71 187733 : key.data = key2;
72 187733 : key.size = 8;
73 :
74 187733 : ret = gnutls_global_init();
75 187733 : if (ret != 0) {
76 0 : return ret;
77 : }
78 :
79 187733 : ret = gnutls_cipher_init(&ctx, GNUTLS_CIPHER_DES_CBC, &key, &iv);
80 187733 : if (ret != 0) {
81 0 : return ret;
82 : }
83 :
84 187733 : memcpy(outb, in, 8);
85 187733 : if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
86 155420 : ret = gnutls_cipher_encrypt(ctx, outb, 8);
87 : } else {
88 32313 : ret = gnutls_cipher_decrypt(ctx, outb, 8);
89 : }
90 :
91 187733 : if (ret == 0) {
92 187733 : memcpy(out, outb, 8);
93 : }
94 :
95 187733 : gnutls_cipher_deinit(ctx);
96 :
97 187733 : return ret;
98 : }
99 :
100 10221 : int E_P16(const uint8_t *p14,uint8_t *p16)
101 : {
102 10221 : const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
103 15 : int ret;
104 :
105 10221 : ret = des_crypt56_gnutls(p16, sp8, p14, SAMBA_GNUTLS_ENCRYPT);
106 10221 : if (ret != 0) {
107 0 : return ret;
108 : }
109 :
110 10221 : return des_crypt56_gnutls(p16+8, sp8, p14+7, SAMBA_GNUTLS_ENCRYPT);
111 : }
112 :
113 11981 : int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24)
114 : {
115 19 : int ret;
116 :
117 11981 : ret = des_crypt56_gnutls(p24, c8, p21, SAMBA_GNUTLS_ENCRYPT);
118 11981 : if (ret != 0) {
119 0 : return ret;
120 : }
121 :
122 11981 : ret = des_crypt56_gnutls(p24+8, c8, p21+7, SAMBA_GNUTLS_ENCRYPT);
123 11981 : if (ret != 0) {
124 0 : return ret;
125 : }
126 :
127 11981 : return des_crypt56_gnutls(p24+16, c8, p21+14, SAMBA_GNUTLS_ENCRYPT);
128 : }
129 :
130 3361 : int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out)
131 : {
132 1 : int ret;
133 :
134 3361 : ret = des_crypt56_gnutls(out, in, p14, SAMBA_GNUTLS_ENCRYPT);
135 3361 : if (ret != 0) {
136 0 : return ret;
137 : }
138 :
139 3361 : return des_crypt56_gnutls(out+8, in+8, p14+7, SAMBA_GNUTLS_ENCRYPT);
140 : }
141 :
142 : /* des encryption with a 128 bit key */
143 460 : int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16])
144 : {
145 49 : uint8_t buf[8];
146 49 : int ret;
147 :
148 460 : ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
149 460 : if (ret != 0) {
150 0 : return ret;
151 : }
152 :
153 460 : return des_crypt56_gnutls(out, buf, key+9, SAMBA_GNUTLS_ENCRYPT);
154 : }
155 :
156 : /* des encryption with a 112 bit (14 byte) key */
157 27772 : int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14],
158 : enum samba_gnutls_direction encrypt)
159 : {
160 1734 : uint8_t buf[8];
161 1734 : int ret;
162 :
163 27772 : if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
164 27771 : ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
165 27771 : if (ret != 0) {
166 0 : return ret;
167 : }
168 :
169 27771 : return des_crypt56_gnutls(out, buf, key+7, SAMBA_GNUTLS_ENCRYPT);
170 : }
171 :
172 1 : ret = des_crypt56_gnutls(buf, in, key+7, SAMBA_GNUTLS_DECRYPT);
173 1 : if (ret != 0) {
174 0 : return ret;
175 : }
176 :
177 1 : return des_crypt56_gnutls(out, buf, key, SAMBA_GNUTLS_DECRYPT);
178 : }
179 :
180 : /* des encryption of a 16 byte lump of data with a 112 bit key */
181 371 : int des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14],
182 : enum samba_gnutls_direction encrypt)
183 : {
184 35 : int ret;
185 :
186 371 : ret = des_crypt56_gnutls(out, in, key, encrypt);
187 371 : if (ret != 0) {
188 0 : return ret;
189 : }
190 :
191 371 : return des_crypt56_gnutls(out + 8, in + 8, key+7, encrypt);
192 : }
193 :
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 18833 : int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out,
198 : enum samba_gnutls_direction encrypt)
199 : {
200 5 : uint8_t s[14];
201 5 : int ret;
202 :
203 18833 : s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF);
204 18833 : s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF);
205 18833 : s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF);
206 18833 : s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF);
207 :
208 18833 : ret = des_crypt56_gnutls(out, in, s, encrypt);
209 18833 : if (ret != 0) {
210 0 : return ret;
211 : }
212 18833 : return des_crypt56_gnutls(out+8, in+8, s+7, encrypt);
213 : }
|