Commit ee2c9258501f83d3ed0fd09ce5df1cec53312cf0

Authored by Shirish Pargaonkar
Committed by Steve French
1 parent d39454ffe4

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>

Showing 9 changed files with 97 additions and 286 deletions Side-by-side Diff

... ... @@ -5,7 +5,7 @@
5 5  
6 6 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
7 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 9 readdir.o ioctl.o sess.o export.o
10 10  
11 11 cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
fs/cifs/cifsencrypt.c
... ... @@ -36,11 +36,6 @@
36 36 /* Note that the smb header signature field on input contains the
37 37 sequence number before this function is called */
38 38  
39   -extern void mdfour(unsigned char *out, unsigned char *in, int n);
40   -extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
41   -extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
42   - unsigned char *p24);
43   -
44 39 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
45 40 struct TCP_Server_Info *server, char *signature)
46 41 {
... ... @@ -233,6 +228,7 @@
233 228 /* first calculate 24 bytes ntlm response and then 16 byte session key */
234 229 int setup_ntlm_response(struct cifsSesInfo *ses)
235 230 {
  231 + int rc = 0;
236 232 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
237 233 char temp_key[CIFS_SESS_KEY_SIZE];
238 234  
239 235  
240 236  
241 237  
... ... @@ -246,13 +242,26 @@
246 242 }
247 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 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 + }
251 252  
252   - E_md4hash(ses->password, temp_key);
253   - mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
  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 + }
254 258  
255   - return 0;
  259 + rc = 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);
  263 +
  264 + return rc;
256 265 }
257 266  
258 267 #ifdef CONFIG_CIFS_WEAK_PW_HASH
259 268  
... ... @@ -699,14 +708,13 @@
699 708 unsigned int size;
700 709  
701 710 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
702   - if (!server->secmech.hmacmd5 ||
703   - IS_ERR(server->secmech.hmacmd5)) {
  711 + if (IS_ERR(server->secmech.hmacmd5)) {
704 712 cERROR(1, "could not allocate crypto hmacmd5\n");
705 713 return PTR_ERR(server->secmech.hmacmd5);
706 714 }
707 715  
708 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 718 cERROR(1, "could not allocate crypto md5\n");
711 719 rc = PTR_ERR(server->secmech.md5);
712 720 goto crypto_allocate_md5_fail;
fs/cifs/cifsencrypt.h
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 */
26   -extern void mdfour(unsigned char *out, unsigned char *in, int n);
27   -/* smbdes.c */
28   -extern void E_P16(unsigned char *p14, unsigned char *p16);
29   -extern void E_P24(unsigned char *p21, const unsigned char *c8,
30   - unsigned char *p24);
... ... @@ -375,7 +375,7 @@
375 375 extern int cifs_verify_signature(struct smb_hdr *,
376 376 struct TCP_Server_Info *server,
377 377 __u32 expected_sequence_number);
378   -extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
  378 +extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
379 379 extern int setup_ntlm_response(struct cifsSesInfo *);
380 380 extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
381 381 extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
... ... @@ -425,5 +425,12 @@
425 425 extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
426 426 const unsigned char *path,
427 427 struct cifs_sb_info *cifs_sb, int xid);
  428 +extern int mdfour(unsigned char *, unsigned char *, int);
  429 +extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
  430 +extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
  431 + unsigned char *p24);
  432 +extern void E_P16(unsigned char *p14, unsigned char *p16);
  433 +extern void E_P24(unsigned char *p21, const unsigned char *c8,
  434 + unsigned char *p24);
428 435 #endif /* _CIFSPROTO_H */
... ... @@ -55,9 +55,6 @@
55 55 /* SMB echo "timeout" -- FIXME: tunable? */
56 56 #define SMB_ECHO_INTERVAL (60 * HZ)
57 57  
58   -extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
59   - unsigned char *p24);
60   -
61 58 extern mempool_t *cifs_req_poolp;
62 59  
63 60 struct smb_vol {
... ... @@ -2990,7 +2987,8 @@
2990 2987 bcc_ptr);
2991 2988 else
2992 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 2993 bcc_ptr += CIFS_AUTH_RESP_SIZE;
2996 2994 if (ses->capabilities & CAP_UNICODE) {
... ... @@ -54,10 +54,9 @@
54 54 struct sdesc *sdescmd5;
55 55  
56 56 md5 = crypto_alloc_shash("md5", 0, 0);
57   - if (!md5 || IS_ERR(md5)) {
58   - rc = PTR_ERR(md5);
  57 + if (IS_ERR(md5)) {
59 58 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
60   - return rc;
  59 + return PTR_ERR(md5);
61 60 }
62 61 size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
63 62 sdescmd5 = kmalloc(size, GFP_KERNEL);
fs/cifs/md4.c
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   -
28   -static __u32
29   -F(__u32 X, __u32 Y, __u32 Z)
30   -{
31   - return (X & Y) | ((~X) & Z);
32   -}
33   -
34   -static __u32
35   -G(__u32 X, __u32 Y, __u32 Z)
36   -{
37   - return (X & Y) | (X & Z) | (Y & Z);
38   -}
39   -
40   -static __u32
41   -H(__u32 X, __u32 Y, __u32 Z)
42   -{
43   - return X ^ Y ^ Z;
44   -}
45   -
46   -static __u32
47   -lshift(__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 */
58   -static void
59   -mdfour64(__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   -
139   -static void
140   -copy64(__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   -
149   -static void
150   -copy4(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 */
159   -void
160   -mdfour(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   -}
... ... @@ -45,7 +45,6 @@
45 45 up with a different answer to the one above)
46 46 */
47 47 #include <linux/slab.h>
48   -#include "cifsencrypt.h"
49 48 #define uchar unsigned char
50 49  
51 50 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
fs/cifs/smbencrypt.c
... ... @@ -33,7 +33,7 @@
33 33 #include "cifspdu.h"
34 34 #include "cifsglob.h"
35 35 #include "cifs_debug.h"
36   -#include "cifsencrypt.h"
  36 +#include "cifsproto.h"
37 37  
38 38 #ifndef false
39 39 #define false 0
40 40  
41 41  
... ... @@ -47,15 +47,58 @@
47 47 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
48 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 */
  51 +int
  52 +mdfour(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;
51 58  
52   -void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
53   - unsigned char *p24);
54   -void E_md4hash(const unsigned char *passwd, unsigned char *p16);
55   -static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
56   - unsigned char p24[24]);
57   -void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
  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;
58 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);
  81 +
  82 +mdfour_err:
  83 + crypto_free_shash(md4);
  84 + kfree(sdescmd4);
  85 +
  86 + return rc;
  87 +}
  88 +
  89 +/* Does the des encryption from the NT or LM MD4 hash. */
  90 +static void
  91 +SMBOWFencrypt(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 +}
  101 +
59 102 /*
60 103 This implements the X/Open SMB password encryption
61 104 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
62 105  
... ... @@ -117,9 +160,10 @@
117 160 * Creates the MD4 Hash of the users password in NT UNICODE.
118 161 */
119 162  
120   -void
  163 +int
121 164 E_md4hash(const unsigned char *passwd, unsigned char *p16)
122 165 {
  166 + int rc;
123 167 int len;
124 168 __u16 wpwd[129];
125 169  
126 170  
... ... @@ -138,8 +182,10 @@
138 182 /* Calculate length in bytes */
139 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 186 memset(wpwd, 0, 129 * 2);
  187 +
  188 + return rc;
143 189 }
144 190  
145 191 #if 0 /* currently unused */
... ... @@ -211,19 +257,6 @@
211 257 }
212 258 #endif
213 259  
214   -/* Does the des encryption from the NT or LM MD4 hash. */
215   -static void
216   -SMBOWFencrypt(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 260 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
228 261 #if 0 /* currently unused */
229 262 static void
230 263  
231 264  
232 265  
... ... @@ -241,16 +274,21 @@
241 274 #endif
242 275  
243 276 /* Does the NT MD4 hash then des encryption. */
244   -
245   -void
  277 +int
246 278 SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
247 279 {
  280 + int rc;
248 281 unsigned char p21[21];
249 282  
250 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 290 SMBOWFencrypt(p21, c8, p24);
  291 + return rc;
254 292 }
255 293  
256 294