diff options
Diffstat (limited to 'fs/cifs/cifsencrypt.c')
-rw-r--r-- | fs/cifs/cifsencrypt.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 08781a4698b4..e11d8c6bb227 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "md5.h" | 26 | #include "md5.h" |
27 | #include "cifs_unicode.h" | 27 | #include "cifs_unicode.h" |
28 | #include "cifsproto.h" | 28 | #include "cifsproto.h" |
29 | #include <linux/ctype.h> | ||
29 | 30 | ||
30 | /* Calculate and return the CIFS signature based on the mac key and the smb pdu */ | 31 | /* Calculate and return the CIFS signature based on the mac key and the smb pdu */ |
31 | /* the 16 byte signature must be allocated by the caller */ | 32 | /* the 16 byte signature must be allocated by the caller */ |
@@ -35,6 +36,8 @@ | |||
35 | 36 | ||
36 | extern void mdfour(unsigned char *out, unsigned char *in, int n); | 37 | extern void mdfour(unsigned char *out, unsigned char *in, int n); |
37 | extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); | 38 | extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); |
39 | extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, | ||
40 | unsigned char *p24); | ||
38 | 41 | ||
39 | static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, | 42 | static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, |
40 | const char * key, char * signature) | 43 | const char * key, char * signature) |
@@ -45,7 +48,7 @@ static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, | |||
45 | return -EINVAL; | 48 | return -EINVAL; |
46 | 49 | ||
47 | MD5Init(&context); | 50 | MD5Init(&context); |
48 | MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); | 51 | MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); |
49 | MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); | 52 | MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); |
50 | MD5Final(signature,&context); | 53 | MD5Final(signature,&context); |
51 | return 0; | 54 | return 0; |
@@ -90,7 +93,7 @@ static int cifs_calc_signature2(const struct kvec * iov, int n_vec, | |||
90 | return -EINVAL; | 93 | return -EINVAL; |
91 | 94 | ||
92 | MD5Init(&context); | 95 | MD5Init(&context); |
93 | MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); | 96 | MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); |
94 | for(i=0;i<n_vec;i++) { | 97 | for(i=0;i<n_vec;i++) { |
95 | if(iov[i].iov_base == NULL) { | 98 | if(iov[i].iov_base == NULL) { |
96 | cERROR(1,("null iovec entry")); | 99 | cERROR(1,("null iovec entry")); |
@@ -204,7 +207,7 @@ int cifs_calculate_mac_key(char * key, const char * rn, const char * password) | |||
204 | 207 | ||
205 | E_md4hash(password, temp_key); | 208 | E_md4hash(password, temp_key); |
206 | mdfour(key,temp_key,16); | 209 | mdfour(key,temp_key,16); |
207 | memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE); | 210 | memcpy(key+16,rn, CIFS_SESS_KEY_SIZE); |
208 | return 0; | 211 | return 0; |
209 | } | 212 | } |
210 | 213 | ||
@@ -261,6 +264,37 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_ | |||
261 | kfree(unicode_buf); | 264 | kfree(unicode_buf); |
262 | return 0; | 265 | return 0; |
263 | } | 266 | } |
267 | |||
268 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | ||
269 | void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key) | ||
270 | { | ||
271 | int i; | ||
272 | char password_with_pad[CIFS_ENCPWD_SIZE]; | ||
273 | |||
274 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); | ||
275 | strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); | ||
276 | |||
277 | /* calculate old style session key */ | ||
278 | /* calling toupper is less broken than repeatedly | ||
279 | calling nls_toupper would be since that will never | ||
280 | work for UTF8, but neither handles multibyte code pages | ||
281 | but the only alternative would be converting to UCS-16 (Unicode) | ||
282 | (using a routine something like UniStrupr) then | ||
283 | uppercasing and then converting back from Unicode - which | ||
284 | would only worth doing it if we knew it were utf8. Basically | ||
285 | utf8 and other multibyte codepages each need their own strupper | ||
286 | function since a byte at a time will ont work. */ | ||
287 | |||
288 | for(i = 0; i < CIFS_ENCPWD_SIZE; i++) { | ||
289 | password_with_pad[i] = toupper(password_with_pad[i]); | ||
290 | } | ||
291 | |||
292 | SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key); | ||
293 | /* clear password before we return/free memory */ | ||
294 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); | ||
295 | } | ||
296 | #endif /* CIFS_WEAK_PW_HASH */ | ||
297 | |||
264 | void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response) | 298 | void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response) |
265 | { | 299 | { |
266 | struct HMACMD5Context context; | 300 | struct HMACMD5Context context; |