diff options
| -rw-r--r-- | fs/cifs/cifsencrypt.c | 8 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 8 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 2 | ||||
| -rw-r--r-- | fs/cifs/sess.c | 2 | ||||
| -rw-r--r-- | fs/cifs/smbencrypt.c | 63 |
5 files changed, 23 insertions, 60 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 2cfb695d1f89..5d9b9acc5fce 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
| @@ -204,7 +204,7 @@ int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | /* first calculate 24 bytes ntlm response and then 16 byte session key */ | 206 | /* first calculate 24 bytes ntlm response and then 16 byte session key */ |
| 207 | int setup_ntlm_response(struct cifs_ses *ses) | 207 | int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp) |
| 208 | { | 208 | { |
| 209 | int rc = 0; | 209 | int rc = 0; |
| 210 | unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; | 210 | unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; |
| @@ -221,14 +221,14 @@ int setup_ntlm_response(struct cifs_ses *ses) | |||
| 221 | ses->auth_key.len = temp_len; | 221 | ses->auth_key.len = temp_len; |
| 222 | 222 | ||
| 223 | rc = SMBNTencrypt(ses->password, ses->server->cryptkey, | 223 | rc = SMBNTencrypt(ses->password, ses->server->cryptkey, |
| 224 | ses->auth_key.response + CIFS_SESS_KEY_SIZE); | 224 | ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); |
| 225 | if (rc) { | 225 | if (rc) { |
| 226 | cFYI(1, "%s Can't generate NTLM response, error: %d", | 226 | cFYI(1, "%s Can't generate NTLM response, error: %d", |
| 227 | __func__, rc); | 227 | __func__, rc); |
| 228 | return rc; | 228 | return rc; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | rc = E_md4hash(ses->password, temp_key); | 231 | rc = E_md4hash(ses->password, temp_key, nls_cp); |
| 232 | if (rc) { | 232 | if (rc) { |
| 233 | cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); | 233 | cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); |
| 234 | return rc; | 234 | return rc; |
| @@ -404,7 +404,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, | |||
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | /* calculate md4 hash of password */ | 406 | /* calculate md4 hash of password */ |
| 407 | E_md4hash(ses->password, nt_hash); | 407 | E_md4hash(ses->password, nt_hash, nls_cp); |
| 408 | 408 | ||
| 409 | rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, | 409 | rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, |
| 410 | CIFS_NTHASH_SIZE); | 410 | CIFS_NTHASH_SIZE); |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ef4f631e4c01..6f4e243e0f62 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -395,8 +395,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, | |||
| 395 | extern int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, | 395 | extern int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, |
| 396 | struct TCP_Server_Info *server, | 396 | struct TCP_Server_Info *server, |
| 397 | __u32 expected_sequence_number); | 397 | __u32 expected_sequence_number); |
| 398 | extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); | 398 | extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *, |
| 399 | extern int setup_ntlm_response(struct cifs_ses *); | 399 | const struct nls_table *); |
| 400 | extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *); | ||
| 400 | extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); | 401 | extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); |
| 401 | extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); | 402 | extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); |
| 402 | extern void cifs_crypto_shash_release(struct TCP_Server_Info *); | 403 | extern void cifs_crypto_shash_release(struct TCP_Server_Info *); |
| @@ -448,7 +449,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, | |||
| 448 | const unsigned char *path, | 449 | const unsigned char *path, |
| 449 | struct cifs_sb_info *cifs_sb, int xid); | 450 | struct cifs_sb_info *cifs_sb, int xid); |
| 450 | extern int mdfour(unsigned char *, unsigned char *, int); | 451 | extern int mdfour(unsigned char *, unsigned char *, int); |
| 451 | extern int E_md4hash(const unsigned char *passwd, unsigned char *p16); | 452 | extern int E_md4hash(const unsigned char *passwd, unsigned char *p16, |
| 453 | const struct nls_table *codepage); | ||
| 452 | extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, | 454 | extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, |
| 453 | unsigned char *p24); | 455 | unsigned char *p24); |
| 454 | 456 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d545a95c30ed..c0458c543f17 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -3452,7 +3452,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
| 3452 | else | 3452 | else |
| 3453 | #endif /* CIFS_WEAK_PW_HASH */ | 3453 | #endif /* CIFS_WEAK_PW_HASH */ |
| 3454 | rc = SMBNTencrypt(tcon->password, ses->server->cryptkey, | 3454 | rc = SMBNTencrypt(tcon->password, ses->server->cryptkey, |
| 3455 | bcc_ptr); | 3455 | bcc_ptr, nls_codepage); |
| 3456 | 3456 | ||
| 3457 | bcc_ptr += CIFS_AUTH_RESP_SIZE; | 3457 | bcc_ptr += CIFS_AUTH_RESP_SIZE; |
| 3458 | if (ses->capabilities & CAP_UNICODE) { | 3458 | if (ses->capabilities & CAP_UNICODE) { |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index c7d80e24f24e..4ec3ee9d72cc 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -683,7 +683,7 @@ ssetup_ntlmssp_authenticate: | |||
| 683 | cpu_to_le16(CIFS_AUTH_RESP_SIZE); | 683 | cpu_to_le16(CIFS_AUTH_RESP_SIZE); |
| 684 | 684 | ||
| 685 | /* calculate ntlm response and session key */ | 685 | /* calculate ntlm response and session key */ |
| 686 | rc = setup_ntlm_response(ses); | 686 | rc = setup_ntlm_response(ses, nls_cp); |
| 687 | if (rc) { | 687 | if (rc) { |
| 688 | cERROR(1, "Error %d during NTLM authentication", rc); | 688 | cERROR(1, "Error %d during NTLM authentication", rc); |
| 689 | goto ssetup_exit; | 689 | goto ssetup_exit; |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index ac1221d969d6..7cacba12b8f1 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
| @@ -199,75 +199,36 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) | |||
| 199 | return rc; | 199 | return rc; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | /* Routines for Windows NT MD4 Hash functions. */ | ||
| 203 | static int | ||
| 204 | _my_wcslen(__u16 *str) | ||
| 205 | { | ||
| 206 | int len = 0; | ||
| 207 | while (*str++ != 0) | ||
| 208 | len++; | ||
| 209 | return len; | ||
| 210 | } | ||
| 211 | |||
| 212 | /* | ||
| 213 | * Convert a string into an NT UNICODE string. | ||
| 214 | * Note that regardless of processor type | ||
| 215 | * this must be in intel (little-endian) | ||
| 216 | * format. | ||
| 217 | */ | ||
| 218 | |||
| 219 | static int | ||
| 220 | _my_mbstowcs(__u16 *dst, const unsigned char *src, int len) | ||
| 221 | { /* BB not a very good conversion routine - change/fix */ | ||
| 222 | int i; | ||
| 223 | __u16 val; | ||
| 224 | |||
| 225 | for (i = 0; i < len; i++) { | ||
| 226 | val = *src; | ||
| 227 | SSVAL(dst, 0, val); | ||
| 228 | dst++; | ||
| 229 | src++; | ||
| 230 | if (val == 0) | ||
| 231 | break; | ||
| 232 | } | ||
| 233 | return i; | ||
| 234 | } | ||
| 235 | |||
| 236 | /* | 202 | /* |
| 237 | * Creates the MD4 Hash of the users password in NT UNICODE. | 203 | * Creates the MD4 Hash of the users password in NT UNICODE. |
| 238 | */ | 204 | */ |
| 239 | 205 | ||
| 240 | int | 206 | int |
| 241 | E_md4hash(const unsigned char *passwd, unsigned char *p16) | 207 | E_md4hash(const unsigned char *passwd, unsigned char *p16, |
| 208 | const struct nls_table *codepage) | ||
| 242 | { | 209 | { |
| 243 | int rc; | 210 | int rc; |
| 244 | int len; | 211 | int len; |
| 245 | __u16 wpwd[129]; | 212 | __u16 wpwd[129]; |
| 246 | 213 | ||
| 247 | /* Password cannot be longer than 128 characters */ | 214 | /* Password cannot be longer than 128 characters */ |
| 248 | if (passwd) { | 215 | if (passwd) /* Password must be converted to NT unicode */ |
| 249 | len = strlen((char *) passwd); | 216 | len = cifs_strtoUCS(wpwd, passwd, 128, codepage); |
| 250 | if (len > 128) | 217 | else { |
| 251 | len = 128; | ||
| 252 | |||
| 253 | /* Password must be converted to NT unicode */ | ||
| 254 | _my_mbstowcs(wpwd, passwd, len); | ||
| 255 | } else | ||
| 256 | len = 0; | 218 | len = 0; |
| 219 | *wpwd = 0; /* Ensure string is null terminated */ | ||
| 220 | } | ||
| 257 | 221 | ||
| 258 | wpwd[len] = 0; /* Ensure string is null terminated */ | 222 | rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); |
| 259 | /* Calculate length in bytes */ | 223 | memset(wpwd, 0, 129 * sizeof(__u16)); |
| 260 | len = _my_wcslen(wpwd) * sizeof(__u16); | ||
| 261 | |||
| 262 | rc = mdfour(p16, (unsigned char *) wpwd, len); | ||
| 263 | memset(wpwd, 0, 129 * 2); | ||
| 264 | 224 | ||
| 265 | return rc; | 225 | return rc; |
| 266 | } | 226 | } |
| 267 | 227 | ||
| 268 | /* Does the NT MD4 hash then des encryption. */ | 228 | /* Does the NT MD4 hash then des encryption. */ |
| 269 | int | 229 | int |
| 270 | SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) | 230 | SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, |
| 231 | const struct nls_table *codepage) | ||
| 271 | { | 232 | { |
| 272 | int rc; | 233 | int rc; |
| 273 | unsigned char p16[16], p21[21]; | 234 | unsigned char p16[16], p21[21]; |
| @@ -275,7 +236,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) | |||
| 275 | memset(p16, '\0', 16); | 236 | memset(p16, '\0', 16); |
| 276 | memset(p21, '\0', 21); | 237 | memset(p21, '\0', 21); |
| 277 | 238 | ||
| 278 | rc = E_md4hash(passwd, p16); | 239 | rc = E_md4hash(passwd, p16, codepage); |
| 279 | if (rc) { | 240 | if (rc) { |
| 280 | cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); | 241 | cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); |
| 281 | return rc; | 242 | return rc; |
