s3:dbwrap_watch: prepare dbwrap_watched_record_storev() to store watchers if requested
[Samba.git] / libcli / auth / smbdes.c
blobc6c4441930630ac0fffdc0c9084fe1d2efe748f8
1 /*
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/>.
23 #include "includes.h"
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)
31 int i;
33 key[0] = str[0]>>1;
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);
40 key[7] = str[6]&0x7F;
41 for (i=0;i<8;i++) {
42 key[i] = (key[i]<<1);
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 };
61 gnutls_datum_t key;
62 gnutls_cipher_hd_t ctx;
63 uint8_t key2[8];
64 uint8_t outb[8];
65 int ret;
67 memset(out, 0, 8);
69 str_to_key(key_in, key2);
71 key.data = key2;
72 key.size = 8;
74 ret = gnutls_global_init();
75 if (ret != 0) {
76 return ret;
79 ret = gnutls_cipher_init(&ctx, GNUTLS_CIPHER_DES_CBC, &key, &iv);
80 if (ret != 0) {
81 return ret;
84 memcpy(outb, in, 8);
85 if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
86 ret = gnutls_cipher_encrypt(ctx, outb, 8);
87 } else {
88 ret = gnutls_cipher_decrypt(ctx, outb, 8);
91 if (ret == 0) {
92 memcpy(out, outb, 8);
95 gnutls_cipher_deinit(ctx);
97 return ret;
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};
103 int ret;
105 ret = des_crypt56_gnutls(p16, sp8, p14, SAMBA_GNUTLS_ENCRYPT);
106 if (ret != 0) {
107 return ret;
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)
115 int ret;
117 ret = des_crypt56_gnutls(p24, c8, p21, SAMBA_GNUTLS_ENCRYPT);
118 if (ret != 0) {
119 return ret;
122 ret = des_crypt56_gnutls(p24+8, c8, p21+7, SAMBA_GNUTLS_ENCRYPT);
123 if (ret != 0) {
124 return ret;
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)
132 int ret;
134 ret = des_crypt56_gnutls(out, in, p14, SAMBA_GNUTLS_ENCRYPT);
135 if (ret != 0) {
136 return ret;
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])
145 uint8_t buf[8];
146 int ret;
148 ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
149 if (ret != 0) {
150 return ret;
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)
160 uint8_t buf[8];
161 int ret;
163 if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
164 ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
165 if (ret != 0) {
166 return ret;
169 return des_crypt56_gnutls(out, buf, key+7, SAMBA_GNUTLS_ENCRYPT);
172 ret = des_crypt56_gnutls(buf, in, key+7, SAMBA_GNUTLS_DECRYPT);
173 if (ret != 0) {
174 return ret;
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)
184 int ret;
186 ret = des_crypt56_gnutls(out, in, key, encrypt);
187 if (ret != 0) {
188 return ret;
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)
200 uint8_t s[14];
201 int ret;
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);
209 if (ret != 0) {
210 return ret;
212 return des_crypt56_gnutls(out+8, in+8, s+7, encrypt);