]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/cifs/smbencrypt.c
UBUNTU: Ubuntu-4.13.0-45.50
[mirror_ubuntu-artful-kernel.git] / fs / cifs / smbencrypt.c
CommitLineData
790fe579 1/*
1da177e4
LT
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB parameters and setup
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
7 Modified by Jeremy Allison 1995.
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
50c2f753 10
1da177e4
LT
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
50c2f753 15
1da177e4
LT
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
50c2f753 20
1da177e4
LT
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
06deeec7 26#include <linux/crypto.h>
1da177e4 27#include <linux/module.h>
5a0e3ad6 28#include <linux/slab.h>
1da177e4
LT
29#include <linux/fs.h>
30#include <linux/string.h>
31#include <linux/kernel.h>
32#include <linux/random.h>
2baa2682 33#include "cifs_fs_sb.h"
1da177e4
LT
34#include "cifs_unicode.h"
35#include "cifspdu.h"
3979877e 36#include "cifsglob.h"
1da177e4 37#include "cifs_debug.h"
ee2c9258 38#include "cifsproto.h"
1da177e4 39
4b18f2a9
SF
40#ifndef false
41#define false 0
1da177e4 42#endif
4b18f2a9
SF
43#ifndef true
44#define true 1
1da177e4
LT
45#endif
46
47/* following came from the other byteorder.h to avoid include conflicts */
48#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
49#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
50#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
51
43988d76
SF
52static void
53str_to_key(unsigned char *str, unsigned char *key)
54{
55 int i;
56
57 key[0] = str[0] >> 1;
58 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
59 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
60 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
61 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
62 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
63 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
64 key[7] = str[6] & 0x7F;
65 for (i = 0; i < 8; i++)
66 key[i] = (key[i] << 1);
67}
68
69static int
70smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
71{
43988d76 72 unsigned char key2[8];
06deeec7 73 struct crypto_cipher *tfm_des;
43988d76
SF
74
75 str_to_key(key, key2);
76
06deeec7 77 tfm_des = crypto_alloc_cipher("des", 0, 0);
43988d76 78 if (IS_ERR(tfm_des)) {
9651ddba 79 cifs_dbg(VFS, "could not allocate des crypto API\n");
06deeec7 80 return PTR_ERR(tfm_des);
9651ddba 81 }
43988d76 82
06deeec7
AL
83 crypto_cipher_setkey(tfm_des, key2, 8);
84 crypto_cipher_encrypt_one(tfm_des, out, in);
85 crypto_free_cipher(tfm_des);
9651ddba 86
06deeec7 87 return 0;
43988d76
SF
88}
89
90static int
91E_P16(unsigned char *p14, unsigned char *p16)
92{
93 int rc;
94 unsigned char sp8[8] =
95 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
96
97 rc = smbhash(p16, sp8, p14);
98 if (rc)
99 return rc;
100 rc = smbhash(p16 + 8, sp8, p14 + 7);
101 return rc;
102}
103
104static int
105E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
106{
107 int rc;
108
109 rc = smbhash(p24, c8, p21);
110 if (rc)
111 return rc;
112 rc = smbhash(p24 + 8, c8, p21 + 7);
113 if (rc)
114 return rc;
115 rc = smbhash(p24 + 16, c8, p21 + 14);
116 return rc;
117}
118
ee2c9258
SP
119/* produce a md4 message digest from data of length n bytes */
120int
121mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
122{
123 int rc;
124 unsigned int size;
125 struct crypto_shash *md4;
126 struct sdesc *sdescmd4;
127
128 md4 = crypto_alloc_shash("md4", 0, 0);
129 if (IS_ERR(md4)) {
ffeb414a 130 rc = PTR_ERR(md4);
f96637be
JP
131 cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n",
132 __func__, rc);
ffeb414a 133 return rc;
ee2c9258
SP
134 }
135 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
136 sdescmd4 = kmalloc(size, GFP_KERNEL);
137 if (!sdescmd4) {
138 rc = -ENOMEM;
ee2c9258
SP
139 goto mdfour_err;
140 }
141 sdescmd4->shash.tfm = md4;
142 sdescmd4->shash.flags = 0x0;
143
144 rc = crypto_shash_init(&sdescmd4->shash);
145 if (rc) {
f96637be 146 cifs_dbg(VFS, "%s: Could not init md4 shash\n", __func__);
ee2c9258
SP
147 goto mdfour_err;
148 }
14cae324
SP
149 rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
150 if (rc) {
f96637be 151 cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__);
14cae324
SP
152 goto mdfour_err;
153 }
ee2c9258 154 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae324 155 if (rc)
f96637be 156 cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__);
1da177e4 157
ee2c9258
SP
158mdfour_err:
159 crypto_free_shash(md4);
160 kfree(sdescmd4);
161
162 return rc;
163}
164
1da177e4
LT
165/*
166 This implements the X/Open SMB password encryption
790fe579 167 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4
LT
168 encrypted password into p24 */
169/* Note that password must be uppercased and null terminated */
43988d76 170int
4e53a3fb 171SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4 172{
43988d76
SF
173 int rc;
174 unsigned char p14[14], p16[16], p21[21];
1da177e4 175
1da177e4 176 memset(p14, '\0', 14);
43988d76
SF
177 memset(p16, '\0', 16);
178 memset(p21, '\0', 21);
1da177e4 179
43988d76
SF
180 memcpy(p14, passwd, 14);
181 rc = E_P16(p14, p16);
182 if (rc)
183 return rc;
1da177e4 184
43988d76
SF
185 memcpy(p21, p16, 16);
186 rc = E_P24(p21, c8, p24);
50c2f753 187
43988d76 188 return rc;
1da177e4
LT
189}
190
790fe579 191/*
1da177e4
LT
192 * Creates the MD4 Hash of the users password in NT UNICODE.
193 */
194
ee2c9258 195int
9ef5992e
SP
196E_md4hash(const unsigned char *passwd, unsigned char *p16,
197 const struct nls_table *codepage)
1da177e4 198{
ee2c9258 199 int rc;
1da177e4 200 int len;
9c32c63b 201 __le16 wpwd[129];
1da177e4
LT
202
203 /* Password cannot be longer than 128 characters */
9ef5992e 204 if (passwd) /* Password must be converted to NT unicode */
acbbb76a 205 len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
9ef5992e 206 else {
1da177e4 207 len = 0;
9ef5992e
SP
208 *wpwd = 0; /* Ensure string is null terminated */
209 }
1da177e4 210
9c32c63b 211 rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
f99dbfa4 212 memzero_explicit(wpwd, sizeof(wpwd));
ee2c9258
SP
213
214 return rc;
1da177e4
LT
215}
216
1da177e4 217/* Does the NT MD4 hash then des encryption. */
ee2c9258 218int
9ef5992e
SP
219SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
220 const struct nls_table *codepage)
1da177e4 221{
ee2c9258 222 int rc;
43988d76 223 unsigned char p16[16], p21[21];
1da177e4 224
43988d76 225 memset(p16, '\0', 16);
1da177e4
LT
226 memset(p21, '\0', 21);
227
9ef5992e 228 rc = E_md4hash(passwd, p16, codepage);
ee2c9258 229 if (rc) {
f96637be
JP
230 cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
231 __func__, rc);
ee2c9258
SP
232 return rc;
233 }
43988d76
SF
234 memcpy(p21, p16, 16);
235 rc = E_P24(p21, c8, p24);
ee2c9258 236 return rc;
1da177e4 237}