aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorShirish Pargaonkar <shirishpargaonkar@gmail.com>2011-01-27 10:58:04 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-27 14:58:13 -0500
commitee2c9258501f83d3ed0fd09ce5df1cec53312cf0 (patch)
tree2690ab3e75343be23a4969846a0c71f0df842dc7 /fs/cifs
parentd39454ffe4a3c85428483b8a8a8e5e797b6363d5 (diff)
cifs: More crypto cleanup (try #2)
Replaced md4 hashing function local to cifs module with kernel crypto APIs. As a result, md4 hashing function and its supporting functions in file md4.c are not needed anymore. Cleaned up function declarations, removed forward function declarations, and removed a header file that is being deleted from being included. Verified that sec=ntlm/i, sec=ntlmv2/i, and sec=ntlmssp/i work correctly. Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/Makefile2
-rw-r--r--fs/cifs/cifsencrypt.c32
-rw-r--r--fs/cifs/cifsencrypt.h33
-rw-r--r--fs/cifs/cifsproto.h9
-rw-r--r--fs/cifs/connect.c6
-rw-r--r--fs/cifs/link.c5
-rw-r--r--fs/cifs/md4.c205
-rw-r--r--fs/cifs/smbdes.c1
-rw-r--r--fs/cifs/smbencrypt.c90
9 files changed, 97 insertions, 286 deletions
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index e1322296cb69..d87558448e3d 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_CIFS) += cifs.o
5 5
6cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 6cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ 7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
8 md4.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 8 cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
9 readdir.o ioctl.o sess.o export.o 9 readdir.o ioctl.o sess.o export.o
10 10
11cifs-$(CONFIG_CIFS_ACL) += cifsacl.o 11cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 35bf329c90e1..0db5f1de0227 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -36,11 +36,6 @@
36/* Note that the smb header signature field on input contains the 36/* Note that the smb header signature field on input contains the
37 sequence number before this function is called */ 37 sequence number before this function is called */
38 38
39extern void mdfour(unsigned char *out, unsigned char *in, int n);
40extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
41extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
42 unsigned char *p24);
43
44static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 39static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
45 struct TCP_Server_Info *server, char *signature) 40 struct TCP_Server_Info *server, char *signature)
46{ 41{
@@ -233,6 +228,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
233/* first calculate 24 bytes ntlm response and then 16 byte session key */ 228/* first calculate 24 bytes ntlm response and then 16 byte session key */
234int setup_ntlm_response(struct cifsSesInfo *ses) 229int setup_ntlm_response(struct cifsSesInfo *ses)
235{ 230{
231 int rc = 0;
236 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; 232 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
237 char temp_key[CIFS_SESS_KEY_SIZE]; 233 char temp_key[CIFS_SESS_KEY_SIZE];
238 234
@@ -246,13 +242,26 @@ int setup_ntlm_response(struct cifsSesInfo *ses)
246 } 242 }
247 ses->auth_key.len = temp_len; 243 ses->auth_key.len = temp_len;
248 244
249 SMBNTencrypt(ses->password, ses->server->cryptkey, 245 rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
250 ses->auth_key.response + CIFS_SESS_KEY_SIZE); 246 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
247 if (rc) {
248 cFYI(1, "%s Can't generate NTLM response, error: %d",
249 __func__, rc);
250 return rc;
251 }
252
253 rc = E_md4hash(ses->password, temp_key);
254 if (rc) {
255 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
256 return rc;
257 }
251 258
252 E_md4hash(ses->password, temp_key); 259 rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
253 mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE); 260 if (rc)
261 cFYI(1, "%s Can't generate NTLM session key, error: %d",
262 __func__, rc);
254 263
255 return 0; 264 return rc;
256} 265}
257 266
258#ifdef CONFIG_CIFS_WEAK_PW_HASH 267#ifdef CONFIG_CIFS_WEAK_PW_HASH
@@ -699,14 +708,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
699 unsigned int size; 708 unsigned int size;
700 709
701 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 710 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
702 if (!server->secmech.hmacmd5 || 711 if (IS_ERR(server->secmech.hmacmd5)) {
703 IS_ERR(server->secmech.hmacmd5)) {
704 cERROR(1, "could not allocate crypto hmacmd5\n"); 712 cERROR(1, "could not allocate crypto hmacmd5\n");
705 return PTR_ERR(server->secmech.hmacmd5); 713 return PTR_ERR(server->secmech.hmacmd5);
706 } 714 }
707 715
708 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); 716 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
709 if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) { 717 if (IS_ERR(server->secmech.md5)) {
710 cERROR(1, "could not allocate crypto md5\n"); 718 cERROR(1, "could not allocate crypto md5\n");
711 rc = PTR_ERR(server->secmech.md5); 719 rc = PTR_ERR(server->secmech.md5);
712 goto crypto_allocate_md5_fail; 720 goto crypto_allocate_md5_fail;
diff --git a/fs/cifs/cifsencrypt.h b/fs/cifs/cifsencrypt.h
deleted file mode 100644
index 15d2ec006474..000000000000
--- a/fs/cifs/cifsencrypt.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * fs/cifs/cifsencrypt.h
3 *
4 * Copyright (c) International Business Machines Corp., 2005
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * Externs for misc. small encryption routines
8 * so we do not have to put them in cifsproto.h
9 *
10 * This library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published
12 * by the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
18 * the GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25/* md4.c */
26extern void mdfour(unsigned char *out, unsigned char *in, int n);
27/* smbdes.c */
28extern void E_P16(unsigned char *p14, unsigned char *p16);
29extern void E_P24(unsigned char *p21, const unsigned char *c8,
30 unsigned char *p24);
31
32
33
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 35c989f4924f..8096f27ad9a8 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -375,7 +375,7 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
375extern int cifs_verify_signature(struct smb_hdr *, 375extern int cifs_verify_signature(struct smb_hdr *,
376 struct TCP_Server_Info *server, 376 struct TCP_Server_Info *server,
377 __u32 expected_sequence_number); 377 __u32 expected_sequence_number);
378extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); 378extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
379extern int setup_ntlm_response(struct cifsSesInfo *); 379extern int setup_ntlm_response(struct cifsSesInfo *);
380extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); 380extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
381extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); 381extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
@@ -425,4 +425,11 @@ extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
425extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, 425extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
426 const unsigned char *path, 426 const unsigned char *path,
427 struct cifs_sb_info *cifs_sb, int xid); 427 struct cifs_sb_info *cifs_sb, int xid);
428extern int mdfour(unsigned char *, unsigned char *, int);
429extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
430extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
431 unsigned char *p24);
432extern void E_P16(unsigned char *p14, unsigned char *p16);
433extern void E_P24(unsigned char *p21, const unsigned char *c8,
434 unsigned char *p24);
428#endif /* _CIFSPROTO_H */ 435#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 47034af67b09..47d8ff623683 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -55,9 +55,6 @@
55/* SMB echo "timeout" -- FIXME: tunable? */ 55/* SMB echo "timeout" -- FIXME: tunable? */
56#define SMB_ECHO_INTERVAL (60 * HZ) 56#define SMB_ECHO_INTERVAL (60 * HZ)
57 57
58extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
59 unsigned char *p24);
60
61extern mempool_t *cifs_req_poolp; 58extern mempool_t *cifs_req_poolp;
62 59
63struct smb_vol { 60struct smb_vol {
@@ -2990,7 +2987,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2990 bcc_ptr); 2987 bcc_ptr);
2991 else 2988 else
2992#endif /* CIFS_WEAK_PW_HASH */ 2989#endif /* CIFS_WEAK_PW_HASH */
2993 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr); 2990 rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
2991 bcc_ptr);
2994 2992
2995 bcc_ptr += CIFS_AUTH_RESP_SIZE; 2993 bcc_ptr += CIFS_AUTH_RESP_SIZE;
2996 if (ses->capabilities & CAP_UNICODE) { 2994 if (ses->capabilities & CAP_UNICODE) {
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index d3444ea6ac71..02cd60aefbff 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -54,10 +54,9 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
54 struct sdesc *sdescmd5; 54 struct sdesc *sdescmd5;
55 55
56 md5 = crypto_alloc_shash("md5", 0, 0); 56 md5 = crypto_alloc_shash("md5", 0, 0);
57 if (!md5 || IS_ERR(md5)) { 57 if (IS_ERR(md5)) {
58 rc = PTR_ERR(md5);
59 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); 58 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
60 return rc; 59 return PTR_ERR(md5);
61 } 60 }
62 size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); 61 size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
63 sdescmd5 = kmalloc(size, GFP_KERNEL); 62 sdescmd5 = kmalloc(size, GFP_KERNEL);
diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c
deleted file mode 100644
index a725c2609d67..000000000000
--- a/fs/cifs/md4.c
+++ /dev/null
@@ -1,205 +0,0 @@
1/*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 a implementation of MD4 designed for use in the SMB authentication protocol
5 Copyright (C) Andrew Tridgell 1997-1998.
6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22#include <linux/module.h>
23#include <linux/fs.h>
24#include "cifsencrypt.h"
25
26/* NOTE: This code makes no attempt to be fast! */
27
28static __u32
29F(__u32 X, __u32 Y, __u32 Z)
30{
31 return (X & Y) | ((~X) & Z);
32}
33
34static __u32
35G(__u32 X, __u32 Y, __u32 Z)
36{
37 return (X & Y) | (X & Z) | (Y & Z);
38}
39
40static __u32
41H(__u32 X, __u32 Y, __u32 Z)
42{
43 return X ^ Y ^ Z;
44}
45
46static __u32
47lshift(__u32 x, int s)
48{
49 x &= 0xFFFFFFFF;
50 return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
51}
52
53#define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)
54#define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s)
55#define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s)
56
57/* this applies md4 to 64 byte chunks */
58static void
59mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D)
60{
61 int j;
62 __u32 AA, BB, CC, DD;
63 __u32 X[16];
64
65
66 for (j = 0; j < 16; j++)
67 X[j] = M[j];
68
69 AA = *A;
70 BB = *B;
71 CC = *C;
72 DD = *D;
73
74 ROUND1(A, B, C, D, 0, 3);
75 ROUND1(D, A, B, C, 1, 7);
76 ROUND1(C, D, A, B, 2, 11);
77 ROUND1(B, C, D, A, 3, 19);
78 ROUND1(A, B, C, D, 4, 3);
79 ROUND1(D, A, B, C, 5, 7);
80 ROUND1(C, D, A, B, 6, 11);
81 ROUND1(B, C, D, A, 7, 19);
82 ROUND1(A, B, C, D, 8, 3);
83 ROUND1(D, A, B, C, 9, 7);
84 ROUND1(C, D, A, B, 10, 11);
85 ROUND1(B, C, D, A, 11, 19);
86 ROUND1(A, B, C, D, 12, 3);
87 ROUND1(D, A, B, C, 13, 7);
88 ROUND1(C, D, A, B, 14, 11);
89 ROUND1(B, C, D, A, 15, 19);
90
91 ROUND2(A, B, C, D, 0, 3);
92 ROUND2(D, A, B, C, 4, 5);
93 ROUND2(C, D, A, B, 8, 9);
94 ROUND2(B, C, D, A, 12, 13);
95 ROUND2(A, B, C, D, 1, 3);
96 ROUND2(D, A, B, C, 5, 5);
97 ROUND2(C, D, A, B, 9, 9);
98 ROUND2(B, C, D, A, 13, 13);
99 ROUND2(A, B, C, D, 2, 3);
100 ROUND2(D, A, B, C, 6, 5);
101 ROUND2(C, D, A, B, 10, 9);
102 ROUND2(B, C, D, A, 14, 13);
103 ROUND2(A, B, C, D, 3, 3);
104 ROUND2(D, A, B, C, 7, 5);
105 ROUND2(C, D, A, B, 11, 9);
106 ROUND2(B, C, D, A, 15, 13);
107
108 ROUND3(A, B, C, D, 0, 3);
109 ROUND3(D, A, B, C, 8, 9);
110 ROUND3(C, D, A, B, 4, 11);
111 ROUND3(B, C, D, A, 12, 15);
112 ROUND3(A, B, C, D, 2, 3);
113 ROUND3(D, A, B, C, 10, 9);
114 ROUND3(C, D, A, B, 6, 11);
115 ROUND3(B, C, D, A, 14, 15);
116 ROUND3(A, B, C, D, 1, 3);
117 ROUND3(D, A, B, C, 9, 9);
118 ROUND3(C, D, A, B, 5, 11);
119 ROUND3(B, C, D, A, 13, 15);
120 ROUND3(A, B, C, D, 3, 3);
121 ROUND3(D, A, B, C, 11, 9);
122 ROUND3(C, D, A, B, 7, 11);
123 ROUND3(B, C, D, A, 15, 15);
124
125 *A += AA;
126 *B += BB;
127 *C += CC;
128 *D += DD;
129
130 *A &= 0xFFFFFFFF;
131 *B &= 0xFFFFFFFF;
132 *C &= 0xFFFFFFFF;
133 *D &= 0xFFFFFFFF;
134
135 for (j = 0; j < 16; j++)
136 X[j] = 0;
137}
138
139static void
140copy64(__u32 *M, unsigned char *in)
141{
142 int i;
143
144 for (i = 0; i < 16; i++)
145 M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
146 (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
147}
148
149static void
150copy4(unsigned char *out, __u32 x)
151{
152 out[0] = x & 0xFF;
153 out[1] = (x >> 8) & 0xFF;
154 out[2] = (x >> 16) & 0xFF;
155 out[3] = (x >> 24) & 0xFF;
156}
157
158/* produce a md4 message digest from data of length n bytes */
159void
160mdfour(unsigned char *out, unsigned char *in, int n)
161{
162 unsigned char buf[128];
163 __u32 M[16];
164 __u32 b = n * 8;
165 int i;
166 __u32 A = 0x67452301;
167 __u32 B = 0xefcdab89;
168 __u32 C = 0x98badcfe;
169 __u32 D = 0x10325476;
170
171 while (n > 64) {
172 copy64(M, in);
173 mdfour64(M, &A, &B, &C, &D);
174 in += 64;
175 n -= 64;
176 }
177
178 for (i = 0; i < 128; i++)
179 buf[i] = 0;
180 memcpy(buf, in, n);
181 buf[n] = 0x80;
182
183 if (n <= 55) {
184 copy4(buf + 56, b);
185 copy64(M, buf);
186 mdfour64(M, &A, &B, &C, &D);
187 } else {
188 copy4(buf + 120, b);
189 copy64(M, buf);
190 mdfour64(M, &A, &B, &C, &D);
191 copy64(M, buf + 64);
192 mdfour64(M, &A, &B, &C, &D);
193 }
194
195 for (i = 0; i < 128; i++)
196 buf[i] = 0;
197 copy64(M, buf);
198
199 copy4(out, A);
200 copy4(out + 4, B);
201 copy4(out + 8, C);
202 copy4(out + 12, D);
203
204 A = B = C = D = 0;
205}
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index b6b6dcb500bf..04721485925d 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -45,7 +45,6 @@
45 up with a different answer to the one above) 45 up with a different answer to the one above)
46*/ 46*/
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include "cifsencrypt.h"
49#define uchar unsigned char 48#define uchar unsigned char
50 49
51static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9, 50static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 30135005e4f3..b5450e9f40c0 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -33,7 +33,7 @@
33#include "cifspdu.h" 33#include "cifspdu.h"
34#include "cifsglob.h" 34#include "cifsglob.h"
35#include "cifs_debug.h" 35#include "cifs_debug.h"
36#include "cifsencrypt.h" 36#include "cifsproto.h"
37 37
38#ifndef false 38#ifndef false
39#define false 0 39#define false 0
@@ -47,14 +47,57 @@
47#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)
48#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) 48#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
49 49
50/*The following definitions come from libsmb/smbencrypt.c */ 50/* produce a md4 message digest from data of length n bytes */
51int
52mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
53{
54 int rc;
55 unsigned int size;
56 struct crypto_shash *md4;
57 struct sdesc *sdescmd4;
58
59 md4 = crypto_alloc_shash("md4", 0, 0);
60 if (IS_ERR(md4)) {
61 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
62 return PTR_ERR(md4);
63 }
64 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
65 sdescmd4 = kmalloc(size, GFP_KERNEL);
66 if (!sdescmd4) {
67 rc = -ENOMEM;
68 cERROR(1, "%s: Memory allocation failure\n", __func__);
69 goto mdfour_err;
70 }
71 sdescmd4->shash.tfm = md4;
72 sdescmd4->shash.flags = 0x0;
73
74 rc = crypto_shash_init(&sdescmd4->shash);
75 if (rc) {
76 cERROR(1, "%s: Could not init md4 shash\n", __func__);
77 goto mdfour_err;
78 }
79 crypto_shash_update(&sdescmd4->shash, link_str, link_len);
80 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
51 81
52void SMBencrypt(unsigned char *passwd, const unsigned char *c8, 82mdfour_err:
53 unsigned char *p24); 83 crypto_free_shash(md4);
54void E_md4hash(const unsigned char *passwd, unsigned char *p16); 84 kfree(sdescmd4);
55static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, 85
56 unsigned char p24[24]); 86 return rc;
57void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 87}
88
89/* Does the des encryption from the NT or LM MD4 hash. */
90static void
91SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
92 unsigned char p24[24])
93{
94 unsigned char p21[21];
95
96 memset(p21, '\0', 21);
97
98 memcpy(p21, passwd, 16);
99 E_P24(p21, c8, p24);
100}
58 101
59/* 102/*
60 This implements the X/Open SMB password encryption 103 This implements the X/Open SMB password encryption
@@ -117,9 +160,10 @@ _my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
117 * Creates the MD4 Hash of the users password in NT UNICODE. 160 * Creates the MD4 Hash of the users password in NT UNICODE.
118 */ 161 */
119 162
120void 163int
121E_md4hash(const unsigned char *passwd, unsigned char *p16) 164E_md4hash(const unsigned char *passwd, unsigned char *p16)
122{ 165{
166 int rc;
123 int len; 167 int len;
124 __u16 wpwd[129]; 168 __u16 wpwd[129];
125 169
@@ -138,8 +182,10 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
138 /* Calculate length in bytes */ 182 /* Calculate length in bytes */
139 len = _my_wcslen(wpwd) * sizeof(__u16); 183 len = _my_wcslen(wpwd) * sizeof(__u16);
140 184
141 mdfour(p16, (unsigned char *) wpwd, len); 185 rc = mdfour(p16, (unsigned char *) wpwd, len);
142 memset(wpwd, 0, 129 * 2); 186 memset(wpwd, 0, 129 * 2);
187
188 return rc;
143} 189}
144 190
145#if 0 /* currently unused */ 191#if 0 /* currently unused */
@@ -211,19 +257,6 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
211} 257}
212#endif 258#endif
213 259
214/* Does the des encryption from the NT or LM MD4 hash. */
215static void
216SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
217 unsigned char p24[24])
218{
219 unsigned char p21[21];
220
221 memset(p21, '\0', 21);
222
223 memcpy(p21, passwd, 16);
224 E_P24(p21, c8, p24);
225}
226
227/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 260/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
228#if 0 /* currently unused */ 261#if 0 /* currently unused */
229static void 262static void
@@ -241,16 +274,21 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
241#endif 274#endif
242 275
243/* Does the NT MD4 hash then des encryption. */ 276/* Does the NT MD4 hash then des encryption. */
244 277int
245void
246SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) 278SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
247{ 279{
280 int rc;
248 unsigned char p21[21]; 281 unsigned char p21[21];
249 282
250 memset(p21, '\0', 21); 283 memset(p21, '\0', 21);
251 284
252 E_md4hash(passwd, p21); 285 rc = E_md4hash(passwd, p21);
286 if (rc) {
287 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
288 return rc;
289 }
253 SMBOWFencrypt(p21, c8, p24); 290 SMBOWFencrypt(p21, c8, p24);
291 return rc;
254} 292}
255 293
256 294