aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smbencrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smbencrypt.c')
-rw-r--r--fs/cifs/smbencrypt.c186
1 files changed, 148 insertions, 38 deletions
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 192ea51af20f..1c5b770c3141 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -32,9 +32,8 @@
32#include "cifs_unicode.h" 32#include "cifs_unicode.h"
33#include "cifspdu.h" 33#include "cifspdu.h"
34#include "cifsglob.h" 34#include "cifsglob.h"
35#include "md5.h"
36#include "cifs_debug.h" 35#include "cifs_debug.h"
37#include "cifsencrypt.h" 36#include "cifsproto.h"
38 37
39#ifndef false 38#ifndef false
40#define false 0 39#define false 0
@@ -48,36 +47,150 @@
48#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) 47#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
49#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) 48#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
50 49
51/*The following definitions come from libsmb/smbencrypt.c */ 50static void
51str_to_key(unsigned char *str, unsigned char *key)
52{
53 int i;
54
55 key[0] = str[0] >> 1;
56 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
57 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
58 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
59 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
60 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
61 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
62 key[7] = str[6] & 0x7F;
63 for (i = 0; i < 8; i++)
64 key[i] = (key[i] << 1);
65}
66
67static int
68smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
69{
70 int rc;
71 unsigned char key2[8];
72 struct crypto_blkcipher *tfm_des;
73 struct scatterlist sgin, sgout;
74 struct blkcipher_desc desc;
75
76 str_to_key(key, key2);
77
78 tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
79 if (IS_ERR(tfm_des)) {
80 rc = PTR_ERR(tfm_des);
81 cERROR(1, "could not allocate des crypto API\n");
82 goto smbhash_err;
83 }
84
85 desc.tfm = tfm_des;
86
87 crypto_blkcipher_setkey(tfm_des, key2, 8);
88
89 sg_init_one(&sgin, in, 8);
90 sg_init_one(&sgout, out, 8);
52 91
53void SMBencrypt(unsigned char *passwd, const unsigned char *c8, 92 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8);
54 unsigned char *p24); 93 if (rc)
55void E_md4hash(const unsigned char *passwd, unsigned char *p16); 94 cERROR(1, "could not encrypt crypt key rc: %d\n", rc);
56static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, 95
57 unsigned char p24[24]); 96 crypto_free_blkcipher(tfm_des);
58void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 97smbhash_err:
98 return rc;
99}
100
101static int
102E_P16(unsigned char *p14, unsigned char *p16)
103{
104 int rc;
105 unsigned char sp8[8] =
106 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
107
108 rc = smbhash(p16, sp8, p14);
109 if (rc)
110 return rc;
111 rc = smbhash(p16 + 8, sp8, p14 + 7);
112 return rc;
113}
114
115static int
116E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
117{
118 int rc;
119
120 rc = smbhash(p24, c8, p21);
121 if (rc)
122 return rc;
123 rc = smbhash(p24 + 8, c8, p21 + 7);
124 if (rc)
125 return rc;
126 rc = smbhash(p24 + 16, c8, p21 + 14);
127 return rc;
128}
129
130/* produce a md4 message digest from data of length n bytes */
131int
132mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
133{
134 int rc;
135 unsigned int size;
136 struct crypto_shash *md4;
137 struct sdesc *sdescmd4;
138
139 md4 = crypto_alloc_shash("md4", 0, 0);
140 if (IS_ERR(md4)) {
141 rc = PTR_ERR(md4);
142 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
143 return rc;
144 }
145 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
146 sdescmd4 = kmalloc(size, GFP_KERNEL);
147 if (!sdescmd4) {
148 rc = -ENOMEM;
149 cERROR(1, "%s: Memory allocation failure\n", __func__);
150 goto mdfour_err;
151 }
152 sdescmd4->shash.tfm = md4;
153 sdescmd4->shash.flags = 0x0;
154
155 rc = crypto_shash_init(&sdescmd4->shash);
156 if (rc) {
157 cERROR(1, "%s: Could not init md4 shash\n", __func__);
158 goto mdfour_err;
159 }
160 crypto_shash_update(&sdescmd4->shash, link_str, link_len);
161 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
162
163mdfour_err:
164 crypto_free_shash(md4);
165 kfree(sdescmd4);
166
167 return rc;
168}
59 169
60/* 170/*
61 This implements the X/Open SMB password encryption 171 This implements the X/Open SMB password encryption
62 It takes a password, a 8 byte "crypt key" and puts 24 bytes of 172 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
63 encrypted password into p24 */ 173 encrypted password into p24 */
64/* Note that password must be uppercased and null terminated */ 174/* Note that password must be uppercased and null terminated */
65void 175int
66SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) 176SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
67{ 177{
68 unsigned char p14[15], p21[21]; 178 int rc;
179 unsigned char p14[14], p16[16], p21[21];
69 180
70 memset(p21, '\0', 21);
71 memset(p14, '\0', 14); 181 memset(p14, '\0', 14);
72 strncpy((char *) p14, (char *) passwd, 14); 182 memset(p16, '\0', 16);
183 memset(p21, '\0', 21);
73 184
74/* strupper((char *)p14); *//* BB at least uppercase the easy range */ 185 memcpy(p14, passwd, 14);
75 E_P16(p14, p21); 186 rc = E_P16(p14, p16);
187 if (rc)
188 return rc;
76 189
77 SMBOWFencrypt(p21, c8, p24); 190 memcpy(p21, p16, 16);
191 rc = E_P24(p21, c8, p24);
78 192
79 memset(p14, 0, 15); 193 return rc;
80 memset(p21, 0, 21);
81} 194}
82 195
83/* Routines for Windows NT MD4 Hash functions. */ 196/* Routines for Windows NT MD4 Hash functions. */
@@ -118,9 +231,10 @@ _my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
118 * Creates the MD4 Hash of the users password in NT UNICODE. 231 * Creates the MD4 Hash of the users password in NT UNICODE.
119 */ 232 */
120 233
121void 234int
122E_md4hash(const unsigned char *passwd, unsigned char *p16) 235E_md4hash(const unsigned char *passwd, unsigned char *p16)
123{ 236{
237 int rc;
124 int len; 238 int len;
125 __u16 wpwd[129]; 239 __u16 wpwd[129];
126 240
@@ -139,8 +253,10 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
139 /* Calculate length in bytes */ 253 /* Calculate length in bytes */
140 len = _my_wcslen(wpwd) * sizeof(__u16); 254 len = _my_wcslen(wpwd) * sizeof(__u16);
141 255
142 mdfour(p16, (unsigned char *) wpwd, len); 256 rc = mdfour(p16, (unsigned char *) wpwd, len);
143 memset(wpwd, 0, 129 * 2); 257 memset(wpwd, 0, 129 * 2);
258
259 return rc;
144} 260}
145 261
146#if 0 /* currently unused */ 262#if 0 /* currently unused */
@@ -212,19 +328,6 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
212} 328}
213#endif 329#endif
214 330
215/* Does the des encryption from the NT or LM MD4 hash. */
216static void
217SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
218 unsigned char p24[24])
219{
220 unsigned char p21[21];
221
222 memset(p21, '\0', 21);
223
224 memcpy(p21, passwd, 16);
225 E_P24(p21, c8, p24);
226}
227
228/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 331/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
229#if 0 /* currently unused */ 332#if 0 /* currently unused */
230static void 333static void
@@ -242,16 +345,23 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
242#endif 345#endif
243 346
244/* Does the NT MD4 hash then des encryption. */ 347/* Does the NT MD4 hash then des encryption. */
245 348int
246void
247SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) 349SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
248{ 350{
249 unsigned char p21[21]; 351 int rc;
352 unsigned char p16[16], p21[21];
250 353
354 memset(p16, '\0', 16);
251 memset(p21, '\0', 21); 355 memset(p21, '\0', 21);
252 356
253 E_md4hash(passwd, p21); 357 rc = E_md4hash(passwd, p16);
254 SMBOWFencrypt(p21, c8, p24); 358 if (rc) {
359 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
360 return rc;
361 }
362 memcpy(p21, p16, 16);
363 rc = E_P24(p21, c8, p24);
364 return rc;
255} 365}
256 366
257 367