[CIFS] Fix ntlmv2 auth with ntlmssp

Make ntlmv2 as an authentication mechanism within ntlmssp
instead of ntlmv1.
Parse type 2 response in ntlmssp negotiation to pluck
AV pairs and use them to calculate ntlmv2 response token.
Also, assign domain name from the sever response in type 2
packet of ntlmssp and use that (netbios) domain name in
calculation of response.

Enable cifs/smb signing using rc4 and md5.

Changed name of the structure mac_key to session_key to reflect
the type of key it holds.

Use kernel crypto_shash_* APIs instead of the equivalent cifs functions.

Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steve French <sfrench@us.ibm.com>

+452 -172
+2
fs/cifs/Kconfig
··· 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)" 3 depends on INET 4 select NLS 5 help 6 This is the client VFS module for the Common Internet File System 7 (CIFS) protocol which is the successor to the Server Message Block
··· 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)" 3 depends on INET 4 select NLS 5 + select CRYPTO_MD5 6 + select CRYPTO_ARC4 7 help 8 This is the client VFS module for the Common Internet File System 9 (CIFS) protocol which is the successor to the Server Message Block
+3 -3
fs/cifs/asn1.c
··· 597 if (compare_oid(oid, oidlen, MSKRB5_OID, 598 MSKRB5_OID_LEN)) 599 server->sec_mskerberos = true; 600 - else if (compare_oid(oid, oidlen, KRB5U2U_OID, 601 KRB5U2U_OID_LEN)) 602 server->sec_kerberosu2u = true; 603 - else if (compare_oid(oid, oidlen, KRB5_OID, 604 KRB5_OID_LEN)) 605 server->sec_kerberos = true; 606 - else if (compare_oid(oid, oidlen, NTLMSSP_OID, 607 NTLMSSP_OID_LEN)) 608 server->sec_ntlmssp = true; 609
··· 597 if (compare_oid(oid, oidlen, MSKRB5_OID, 598 MSKRB5_OID_LEN)) 599 server->sec_mskerberos = true; 600 + if (compare_oid(oid, oidlen, KRB5U2U_OID, 601 KRB5U2U_OID_LEN)) 602 server->sec_kerberosu2u = true; 603 + if (compare_oid(oid, oidlen, KRB5_OID, 604 KRB5_OID_LEN)) 605 server->sec_kerberos = true; 606 + if (compare_oid(oid, oidlen, NTLMSSP_OID, 607 NTLMSSP_OID_LEN)) 608 server->sec_ntlmssp = true; 609
+294 -122
fs/cifs/cifsencrypt.c
··· 27 #include "md5.h" 28 #include "cifs_unicode.h" 29 #include "cifsproto.h" 30 #include <linux/ctype.h> 31 #include <linux/random.h> 32 ··· 43 unsigned char *p24); 44 45 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 46 - const struct mac_key *key, char *signature) 47 { 48 - struct MD5Context context; 49 50 - if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) 51 return -EINVAL; 52 53 - cifs_MD5_init(&context); 54 - cifs_MD5_update(&context, (char *)&key->data, key->len); 55 - cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 56 57 - cifs_MD5_final(signature, &context); 58 return 0; 59 } 60 61 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 62 __u32 *pexpected_response_sequence_number) ··· 102 server->sequence_number++; 103 spin_unlock(&GlobalMid_Lock); 104 105 - rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key, 106 - smb_signature); 107 if (rc) 108 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 109 else ··· 112 } 113 114 static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 115 - const struct mac_key *key, char *signature) 116 { 117 - struct MD5Context context; 118 int i; 119 120 - if ((iov == NULL) || (signature == NULL) || (key == NULL)) 121 return -EINVAL; 122 123 - cifs_MD5_init(&context); 124 - cifs_MD5_update(&context, (char *)&key->data, key->len); 125 for (i = 0; i < n_vec; i++) { 126 if (iov[i].iov_len == 0) 127 continue; ··· 154 if (i == 0) { 155 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 156 break; /* nothing to sign or corrupt header */ 157 - cifs_MD5_update(&context, iov[0].iov_base+4, 158 - iov[0].iov_len-4); 159 } else 160 - cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); 161 } 162 163 - cifs_MD5_final(signature, &context); 164 165 return 0; 166 } 167 - 168 169 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 170 __u32 *pexpected_response_sequence_number) ··· 188 server->sequence_number++; 189 spin_unlock(&GlobalMid_Lock); 190 191 - rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key, 192 - smb_signature); 193 if (rc) 194 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 195 else ··· 198 } 199 200 int cifs_verify_signature(struct smb_hdr *cifs_pdu, 201 - const struct mac_key *mac_key, 202 __u32 expected_sequence_number) 203 { 204 - unsigned int rc; 205 char server_response_sig[8]; 206 char what_we_think_sig_should_be[20]; 207 208 - if ((cifs_pdu == NULL) || (mac_key == NULL)) 209 return -EINVAL; 210 211 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) ··· 234 cpu_to_le32(expected_sequence_number); 235 cifs_pdu->Signature.Sequence.Reserved = 0; 236 237 - rc = cifs_calculate_signature(cifs_pdu, mac_key, 238 what_we_think_sig_should_be); 239 240 if (rc) ··· 251 } 252 253 /* We fill in key by putting in 40 byte array which was allocated by caller */ 254 - int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 255 const char *password) 256 { 257 char temp_key[16]; ··· 262 mdfour(key->data.ntlm, temp_key, 16); 263 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); 264 key->len = 40; 265 - return 0; 266 - } 267 - 268 - int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses, 269 - const struct nls_table *nls_info) 270 - { 271 - char temp_hash[16]; 272 - struct HMACMD5Context ctx; 273 - char *ucase_buf; 274 - __le16 *unicode_buf; 275 - unsigned int i, user_name_len, dom_name_len; 276 - 277 - if (ses == NULL) 278 - return -EINVAL; 279 - 280 - E_md4hash(ses->password, temp_hash); 281 - 282 - hmac_md5_init_limK_to_64(temp_hash, 16, &ctx); 283 - user_name_len = strlen(ses->userName); 284 - if (user_name_len > MAX_USERNAME_SIZE) 285 - return -EINVAL; 286 - if (ses->domainName == NULL) 287 - return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ 288 - dom_name_len = strlen(ses->domainName); 289 - if (dom_name_len > MAX_USERNAME_SIZE) 290 - return -EINVAL; 291 - 292 - ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); 293 - if (ucase_buf == NULL) 294 - return -ENOMEM; 295 - unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); 296 - if (unicode_buf == NULL) { 297 - kfree(ucase_buf); 298 - return -ENOMEM; 299 - } 300 - 301 - for (i = 0; i < user_name_len; i++) 302 - ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; 303 - ucase_buf[i] = 0; 304 - user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, 305 - MAX_USERNAME_SIZE*2, nls_info); 306 - unicode_buf[user_name_len] = 0; 307 - user_name_len++; 308 - 309 - for (i = 0; i < dom_name_len; i++) 310 - ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; 311 - ucase_buf[i] = 0; 312 - dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, 313 - MAX_USERNAME_SIZE*2, nls_info); 314 - 315 - unicode_buf[user_name_len + dom_name_len] = 0; 316 - hmac_md5_update((const unsigned char *) unicode_buf, 317 - (user_name_len+dom_name_len)*2, &ctx); 318 - 319 - hmac_md5_final(ses->server->ntlmv2_hash, &ctx); 320 - kfree(ucase_buf); 321 - kfree(unicode_buf); 322 return 0; 323 } 324 ··· 309 { 310 int rc = 0; 311 int len; 312 - char nt_hash[16]; 313 - struct HMACMD5Context *pctxt; 314 wchar_t *user; 315 wchar_t *domain; 316 - 317 - pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); 318 - 319 - if (pctxt == NULL) 320 - return -ENOMEM; 321 322 /* calculate md4 hash of password */ 323 E_md4hash(ses->password, nt_hash); 324 325 - /* convert Domainname to unicode and uppercase */ 326 - hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); 327 328 /* convert ses->userName to unicode and uppercase */ 329 len = strlen(ses->userName); ··· 340 goto calc_exit_2; 341 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 342 UniStrupr(user); 343 - hmac_md5_update((char *)user, 2*len, pctxt); 344 345 /* convert ses->domainName to unicode and uppercase */ 346 if (ses->domainName) { ··· 357 Maybe converting the domain name earlier makes sense */ 358 /* UniStrupr(domain); */ 359 360 - hmac_md5_update((char *)domain, 2*len, pctxt); 361 362 kfree(domain); 363 } 364 calc_exit_1: 365 kfree(user); 366 calc_exit_2: 367 /* BB FIXME what about bytes 24 through 40 of the signing key? 368 compare with the NTLM example */ 369 - hmac_md5_final(ses->server->ntlmv2_hash, pctxt); 370 371 - kfree(pctxt); 372 return rc; 373 } 374 375 - void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 376 - const struct nls_table *nls_cp) 377 { 378 int rc; 379 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 380 - struct HMACMD5Context context; 381 382 buf->blob_signature = cpu_to_le32(0x00000101); 383 buf->reserved = 0; 384 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 385 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 386 buf->reserved2 = 0; 387 - buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 388 - buf->names[0].length = 0; 389 - buf->names[1].type = 0; 390 - buf->names[1].length = 0; 391 392 /* calculate buf->ntlmv2_hash */ 393 rc = calc_ntlmv2_hash(ses, nls_cp); 394 - if (rc) 395 cERROR(1, "could not get v2 hash rc %d", rc); 396 - CalcNTLMv2_response(ses, resp_buf); 397 398 - /* now calculate the MAC key for NTLMv2 */ 399 - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 400 - hmac_md5_update(resp_buf, 16, &context); 401 - hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); 402 403 - memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, 404 - sizeof(struct ntlmv2_resp)); 405 - ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); 406 } 407 408 - void CalcNTLMv2_response(const struct cifsSesInfo *ses, 409 - char *v2_session_response) 410 { 411 - struct HMACMD5Context context; 412 - /* rest of v2 struct already generated */ 413 - memcpy(v2_session_response + 8, ses->server->cryptKey, 8); 414 - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 415 416 - hmac_md5_update(v2_session_response+8, 417 - sizeof(struct ntlmv2_resp) - 8, &context); 418 419 - hmac_md5_final(v2_session_response, &context); 420 - /* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 421 }
··· 27 #include "md5.h" 28 #include "cifs_unicode.h" 29 #include "cifsproto.h" 30 + #include "ntlmssp.h" 31 #include <linux/ctype.h> 32 #include <linux/random.h> 33 ··· 42 unsigned char *p24); 43 44 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45 + struct TCP_Server_Info *server, char *signature) 46 { 47 + int rc = 0; 48 + struct { 49 + struct shash_desc shash; 50 + char ctx[crypto_shash_descsize(server->ntlmssp.md5)]; 51 + } sdesc; 52 53 + if (cifs_pdu == NULL || server == NULL || signature == NULL) 54 return -EINVAL; 55 56 + sdesc.shash.tfm = server->ntlmssp.md5; 57 + sdesc.shash.flags = 0x0; 58 59 + rc = crypto_shash_init(&sdesc.shash); 60 + if (rc) { 61 + cERROR(1, "could not initialize master crypto API hmacmd5\n"); 62 + return rc; 63 + } 64 + 65 + if (server->secType == RawNTLMSSP) 66 + crypto_shash_update(&sdesc.shash, 67 + server->session_key.data.ntlmv2.key, 68 + CIFS_NTLMV2_SESSKEY_SIZE); 69 + else 70 + crypto_shash_update(&sdesc.shash, 71 + (char *)&server->session_key.data, 72 + server->session_key.len); 73 + 74 + crypto_shash_update(&sdesc.shash, 75 + cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 76 + 77 + rc = crypto_shash_final(&sdesc.shash, signature); 78 + 79 return 0; 80 } 81 + 82 83 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 84 __u32 *pexpected_response_sequence_number) ··· 78 server->sequence_number++; 79 spin_unlock(&GlobalMid_Lock); 80 81 + rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); 82 if (rc) 83 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 84 else ··· 89 } 90 91 static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 92 + struct TCP_Server_Info *server, char *signature) 93 { 94 int i; 95 + int rc = 0; 96 + struct { 97 + struct shash_desc shash; 98 + char ctx[crypto_shash_descsize(server->ntlmssp.md5)]; 99 + } sdesc; 100 101 + if (iov == NULL || server == NULL || signature == NULL) 102 return -EINVAL; 103 104 + sdesc.shash.tfm = server->ntlmssp.md5; 105 + sdesc.shash.flags = 0x0; 106 + 107 + rc = crypto_shash_init(&sdesc.shash); 108 + if (rc) { 109 + cERROR(1, "could not initialize master crypto API hmacmd5\n"); 110 + return rc; 111 + } 112 + 113 + if (server->secType == RawNTLMSSP) 114 + crypto_shash_update(&sdesc.shash, 115 + server->session_key.data.ntlmv2.key, 116 + CIFS_NTLMV2_SESSKEY_SIZE); 117 + else 118 + crypto_shash_update(&sdesc.shash, 119 + (char *)&server->session_key.data, 120 + server->session_key.len); 121 + 122 for (i = 0; i < n_vec; i++) { 123 if (iov[i].iov_len == 0) 124 continue; ··· 111 if (i == 0) { 112 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 113 break; /* nothing to sign or corrupt header */ 114 + crypto_shash_update(&sdesc.shash, 115 + iov[i].iov_base + 4, iov[i].iov_len - 4); 116 } else 117 + crypto_shash_update(&sdesc.shash, 118 + iov[i].iov_base, iov[i].iov_len); 119 } 120 121 + rc = crypto_shash_final(&sdesc.shash, signature); 122 123 return 0; 124 } 125 126 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 127 __u32 *pexpected_response_sequence_number) ··· 145 server->sequence_number++; 146 spin_unlock(&GlobalMid_Lock); 147 148 + rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); 149 if (rc) 150 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 151 else ··· 156 } 157 158 int cifs_verify_signature(struct smb_hdr *cifs_pdu, 159 + struct TCP_Server_Info *server, 160 __u32 expected_sequence_number) 161 { 162 + int rc; 163 char server_response_sig[8]; 164 char what_we_think_sig_should_be[20]; 165 166 + if (cifs_pdu == NULL || server == NULL) 167 return -EINVAL; 168 169 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) ··· 192 cpu_to_le32(expected_sequence_number); 193 cifs_pdu->Signature.Sequence.Reserved = 0; 194 195 + rc = cifs_calculate_signature(cifs_pdu, server, 196 what_we_think_sig_should_be); 197 198 if (rc) ··· 209 } 210 211 /* We fill in key by putting in 40 byte array which was allocated by caller */ 212 + int cifs_calculate_session_key(struct session_key *key, const char *rn, 213 const char *password) 214 { 215 char temp_key[16]; ··· 220 mdfour(key->data.ntlm, temp_key, 16); 221 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); 222 key->len = 40; 223 return 0; 224 } 225 ··· 324 { 325 int rc = 0; 326 int len; 327 + char nt_hash[CIFS_NTHASH_SIZE]; 328 wchar_t *user; 329 wchar_t *domain; 330 + wchar_t *server; 331 + struct { 332 + struct shash_desc shash; 333 + char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)]; 334 + } sdesc; 335 336 /* calculate md4 hash of password */ 337 E_md4hash(ses->password, nt_hash); 338 339 + sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5; 340 + sdesc.shash.flags = 0x0; 341 + 342 + crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, 343 + CIFS_NTHASH_SIZE); 344 + 345 + rc = crypto_shash_init(&sdesc.shash); 346 + if (rc) { 347 + cERROR(1, "could not initialize master crypto API hmacmd5\n"); 348 + return rc; 349 + } 350 351 /* convert ses->userName to unicode and uppercase */ 352 len = strlen(ses->userName); ··· 347 goto calc_exit_2; 348 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 349 UniStrupr(user); 350 + 351 + crypto_shash_update(&sdesc.shash, (char *)user, 2 * len); 352 353 /* convert ses->domainName to unicode and uppercase */ 354 if (ses->domainName) { ··· 363 Maybe converting the domain name earlier makes sense */ 364 /* UniStrupr(domain); */ 365 366 + crypto_shash_update(&sdesc.shash, (char *)domain, 2 * len); 367 368 kfree(domain); 369 + } else if (ses->serverName) { 370 + len = strlen(ses->serverName); 371 + 372 + server = kmalloc(2 + (len * 2), GFP_KERNEL); 373 + if (server == NULL) 374 + goto calc_exit_1; 375 + len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, 376 + nls_cp); 377 + /* the following line was removed since it didn't work well 378 + with lower cased domain name that passed as an option. 379 + Maybe converting the domain name earlier makes sense */ 380 + /* UniStrupr(domain); */ 381 + 382 + crypto_shash_update(&sdesc.shash, (char *)server, 2 * len); 383 + 384 + kfree(server); 385 } 386 calc_exit_1: 387 kfree(user); 388 calc_exit_2: 389 /* BB FIXME what about bytes 24 through 40 of the signing key? 390 compare with the NTLM example */ 391 + rc = crypto_shash_final(&sdesc.shash, ses->server->ntlmv2_hash); 392 393 return rc; 394 } 395 396 + static int 397 + find_domain_name(struct cifsSesInfo *ses) 398 + { 399 + int rc = 0; 400 + unsigned int attrsize; 401 + unsigned int type; 402 + unsigned char *blobptr; 403 + struct ntlmssp2_name *attrptr; 404 + 405 + if (ses->server->tiblob) { 406 + blobptr = ses->server->tiblob; 407 + attrptr = (struct ntlmssp2_name *) blobptr; 408 + 409 + while ((type = attrptr->type) != 0) { 410 + blobptr += 2; /* advance attr type */ 411 + attrsize = attrptr->length; 412 + blobptr += 2; /* advance attr size */ 413 + if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { 414 + if (!ses->domainName) { 415 + ses->domainName = 416 + kmalloc(attrptr->length + 1, 417 + GFP_KERNEL); 418 + if (!ses->domainName) 419 + return -ENOMEM; 420 + cifs_from_ucs2(ses->domainName, 421 + (__le16 *)blobptr, 422 + attrptr->length, 423 + attrptr->length, 424 + load_nls_default(), false); 425 + } 426 + } 427 + blobptr += attrsize; /* advance attr value */ 428 + attrptr = (struct ntlmssp2_name *) blobptr; 429 + } 430 + } else { 431 + ses->server->tilen = 2 * sizeof(struct ntlmssp2_name); 432 + ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL); 433 + if (!ses->server->tiblob) { 434 + ses->server->tilen = 0; 435 + cERROR(1, "Challenge target info allocation failure"); 436 + return -ENOMEM; 437 + } 438 + memset(ses->server->tiblob, 0x0, ses->server->tilen); 439 + attrptr = (struct ntlmssp2_name *) ses->server->tiblob; 440 + attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 441 + } 442 + 443 + return rc; 444 + } 445 + 446 + static int 447 + CalcNTLMv2_response(const struct TCP_Server_Info *server, 448 + char *v2_session_response) 449 { 450 int rc; 451 + struct { 452 + struct shash_desc shash; 453 + char ctx[crypto_shash_descsize(server->ntlmssp.hmacmd5)]; 454 + } sdesc; 455 + 456 + sdesc.shash.tfm = server->ntlmssp.hmacmd5; 457 + sdesc.shash.flags = 0x0; 458 + 459 + crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash, 460 + CIFS_HMAC_MD5_HASH_SIZE); 461 + 462 + rc = crypto_shash_init(&sdesc.shash); 463 + if (rc) { 464 + cERROR(1, "could not initialize master crypto API hmacmd5\n"); 465 + return rc; 466 + } 467 + 468 + memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 469 + server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); 470 + crypto_shash_update(&sdesc.shash, 471 + v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 472 + sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); 473 + 474 + if (server->tilen) 475 + crypto_shash_update(&sdesc.shash, 476 + server->tiblob, server->tilen); 477 + 478 + rc = crypto_shash_final(&sdesc.shash, v2_session_response); 479 + 480 + return rc; 481 + } 482 + 483 + int 484 + setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 485 + const struct nls_table *nls_cp) 486 + { 487 + int rc = 0; 488 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 489 + struct { 490 + struct shash_desc shash; 491 + char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)]; 492 + } sdesc; 493 494 buf->blob_signature = cpu_to_le32(0x00000101); 495 buf->reserved = 0; 496 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 497 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 498 buf->reserved2 = 0; 499 + 500 + if (!ses->domainName) { 501 + rc = find_domain_name(ses); 502 + if (rc) { 503 + cERROR(1, "could not get domain/server name rc %d", rc); 504 + return rc; 505 + } 506 + } 507 508 /* calculate buf->ntlmv2_hash */ 509 rc = calc_ntlmv2_hash(ses, nls_cp); 510 + if (rc) { 511 cERROR(1, "could not get v2 hash rc %d", rc); 512 + return rc; 513 + } 514 + rc = CalcNTLMv2_response(ses->server, resp_buf); 515 + if (rc) { 516 + cERROR(1, "could not get v2 hash rc %d", rc); 517 + return rc; 518 + } 519 520 + crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, 521 + ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 522 523 + sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5; 524 + sdesc.shash.flags = 0x0; 525 + 526 + rc = crypto_shash_init(&sdesc.shash); 527 + if (rc) { 528 + cERROR(1, "could not initialize master crypto API hmacmd5\n"); 529 + return rc; 530 + } 531 + 532 + crypto_shash_update(&sdesc.shash, resp_buf, CIFS_HMAC_MD5_HASH_SIZE); 533 + 534 + rc = crypto_shash_final(&sdesc.shash, 535 + ses->server->session_key.data.ntlmv2.key); 536 + 537 + memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, 538 + sizeof(struct ntlmv2_resp)); 539 + ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp); 540 + 541 + return rc; 542 } 543 544 + int 545 + calc_seckey(struct TCP_Server_Info *server) 546 { 547 + int rc; 548 + unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE]; 549 + struct crypto_blkcipher *tfm_arc4; 550 + struct scatterlist sgin, sgout; 551 + struct blkcipher_desc desc; 552 553 + get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE); 554 555 + tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 556 + 0, CRYPTO_ALG_ASYNC); 557 + if (!tfm_arc4 || IS_ERR(tfm_arc4)) { 558 + cERROR(1, "could not allocate " "master crypto API arc4\n"); 559 + return 1; 560 + } 561 + 562 + crypto_blkcipher_setkey(tfm_arc4, 563 + server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE); 564 + sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE); 565 + sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); 566 + rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE); 567 + 568 + if (!rc) 569 + memcpy(server->session_key.data.ntlmv2.key, 570 + sec_key, CIFS_NTLMV2_SESSKEY_SIZE); 571 + 572 + crypto_free_blkcipher(tfm_arc4); 573 + 574 + return 0; 575 + } 576 + 577 + void 578 + cifs_crypto_shash_release(struct TCP_Server_Info *server) 579 + { 580 + if (server->ntlmssp.md5) 581 + crypto_free_shash(server->ntlmssp.md5); 582 + 583 + if (server->ntlmssp.hmacmd5) 584 + crypto_free_shash(server->ntlmssp.hmacmd5); 585 + } 586 + 587 + int 588 + cifs_crypto_shash_allocate(struct TCP_Server_Info *server) 589 + { 590 + server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 591 + if (!server->ntlmssp.hmacmd5 || 592 + IS_ERR(server->ntlmssp.hmacmd5)) { 593 + cERROR(1, "could not allocate master crypto API hmacmd5\n"); 594 + return 1; 595 + } 596 + 597 + server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); 598 + if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { 599 + crypto_free_shash(server->ntlmssp.hmacmd5); 600 + cERROR(1, "could not allocate master crypto API md5\n"); 601 + return 1; 602 + } 603 + 604 + return 0; 605 }
+16 -2
fs/cifs/cifsglob.h
··· 25 #include <linux/workqueue.h> 26 #include "cifs_fs_sb.h" 27 #include "cifsacl.h" 28 /* 29 * The sizes of various internal tables and strings 30 */ ··· 100 /* Netbios frames protocol not supported at this time */ 101 }; 102 103 - struct mac_key { 104 unsigned int len; 105 union { 106 char ntlm[CIFS_SESS_KEY_SIZE + 16]; ··· 121 struct cifs_sid gsid; 122 struct cifs_ntace *ntaces; 123 struct cifs_ace *aces; 124 }; 125 126 /* ··· 193 /* 16th byte of RFC1001 workstation name is always null */ 194 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 195 __u32 sequence_number; /* needed for CIFS PDU signature */ 196 - struct mac_key mac_signing_key; 197 char ntlmv2_hash[16]; 198 unsigned long lstrp; /* when we got last response from this server */ 199 u16 dialect; /* dialect index that server chose */ 200 /* extended security flavors that server supports */ 201 bool sec_kerberos; /* supports plain Kerberos */ 202 bool sec_mskerberos; /* supports legacy MS Kerberos */ 203 bool sec_kerberosu2u; /* supports U2U Kerberos */
··· 25 #include <linux/workqueue.h> 26 #include "cifs_fs_sb.h" 27 #include "cifsacl.h" 28 + #include <crypto/internal/hash.h> 29 + #include <linux/scatterlist.h> 30 + 31 /* 32 * The sizes of various internal tables and strings 33 */ ··· 97 /* Netbios frames protocol not supported at this time */ 98 }; 99 100 + struct session_key { 101 unsigned int len; 102 union { 103 char ntlm[CIFS_SESS_KEY_SIZE + 16]; ··· 118 struct cifs_sid gsid; 119 struct cifs_ntace *ntaces; 120 struct cifs_ace *aces; 121 + }; 122 + 123 + struct ntlmssp_auth { 124 + __u32 client_flags; 125 + __u32 server_flags; 126 + unsigned char ciphertext[CIFS_CPHTXT_SIZE]; 127 + struct crypto_shash *hmacmd5; 128 + struct crypto_shash *md5; 129 }; 130 131 /* ··· 182 /* 16th byte of RFC1001 workstation name is always null */ 183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 184 __u32 sequence_number; /* needed for CIFS PDU signature */ 185 + struct session_key session_key; 186 char ntlmv2_hash[16]; 187 unsigned long lstrp; /* when we got last response from this server */ 188 u16 dialect; /* dialect index that server chose */ 189 /* extended security flavors that server supports */ 190 + unsigned int tilen; /* length of the target info blob */ 191 + unsigned char *tiblob; /* target info blob in challenge response */ 192 + struct ntlmssp_auth ntlmssp; /* various keys, ciphers, flags */ 193 bool sec_kerberos; /* supports plain Kerberos */ 194 bool sec_mskerberos; /* supports legacy MS Kerberos */ 195 bool sec_kerberosu2u; /* supports U2U Kerberos */
+6 -1
fs/cifs/cifspdu.h
··· 134 * Size of the session key (crypto key encrypted with the password 135 */ 136 #define CIFS_SESS_KEY_SIZE (24) 137 138 /* 139 * Maximum user name length ··· 669 __le64 time; 670 __u64 client_chal; /* random */ 671 __u32 reserved2; 672 - struct ntlmssp2_name names[2]; 673 /* array of name entries could follow ending in minimum 4 byte struct */ 674 } __attribute__((packed)); 675
··· 134 * Size of the session key (crypto key encrypted with the password 135 */ 136 #define CIFS_SESS_KEY_SIZE (24) 137 + #define CIFS_CLIENT_CHALLENGE_SIZE (8) 138 + #define CIFS_SERVER_CHALLENGE_SIZE (8) 139 + #define CIFS_HMAC_MD5_HASH_SIZE (16) 140 + #define CIFS_CPHTXT_SIZE (16) 141 + #define CIFS_NTLMV2_SESSKEY_SIZE (16) 142 + #define CIFS_NTHASH_SIZE (16) 143 144 /* 145 * Maximum user name length ··· 663 __le64 time; 664 __u64 client_chal; /* random */ 665 __u32 reserved2; 666 /* array of name entries could follow ending in minimum 4 byte struct */ 667 } __attribute__((packed)); 668
+6 -6
fs/cifs/cifsproto.h
··· 361 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 362 __u32 *); 363 extern int cifs_verify_signature(struct smb_hdr *, 364 - const struct mac_key *mac_key, 365 __u32 expected_sequence_number); 366 - extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 367 const char *pass); 368 - extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, 369 - const struct nls_table *); 370 - extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); 371 - extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 372 const struct nls_table *); 373 #ifdef CONFIG_CIFS_WEAK_PW_HASH 374 extern void calc_lanman_hash(const char *password, const char *cryptkey, 375 bool encrypt, char *lnm_session_key);
··· 361 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 362 __u32 *); 363 extern int cifs_verify_signature(struct smb_hdr *, 364 + struct TCP_Server_Info *server, 365 __u32 expected_sequence_number); 366 + extern int cifs_calculate_session_key(struct session_key *key, const char *rn, 367 const char *pass); 368 + extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 369 const struct nls_table *); 370 + extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); 371 + extern void cifs_crypto_shash_release(struct TCP_Server_Info *); 372 + extern int calc_seckey(struct TCP_Server_Info *); 373 #ifdef CONFIG_CIFS_WEAK_PW_HASH 374 extern void calc_lanman_hash(const char *password, const char *cryptkey, 375 bool encrypt, char *lnm_session_key);
+8 -5
fs/cifs/cifssmb.c
··· 604 else 605 rc = -EINVAL; 606 607 - if (server->sec_kerberos || server->sec_mskerberos) 608 - server->secType = Kerberos; 609 - else if (server->sec_ntlmssp) 610 - server->secType = RawNTLMSSP; 611 - else 612 rc = -EOPNOTSUPP; 613 } 614 } else
··· 604 else 605 rc = -EINVAL; 606 607 + if (server->secType == Kerberos) { 608 + if (!server->sec_kerberos && 609 + !server->sec_mskerberos) 610 + rc = -EOPNOTSUPP; 611 + } else if (server->secType == RawNTLMSSP) { 612 + if (!server->sec_ntlmssp) 613 + rc = -EOPNOTSUPP; 614 + } else 615 rc = -EOPNOTSUPP; 616 } 617 } else
+12 -1
fs/cifs/connect.c
··· 1707 CIFSSMBLogoff(xid, ses); 1708 _FreeXid(xid); 1709 } 1710 sesInfoFree(ses); 1711 cifs_put_tcp_session(server); 1712 } ··· 1787 ses->linux_uid = volume_info->linux_uid; 1788 ses->overrideSecFlg = volume_info->secFlg; 1789 1790 mutex_lock(&ses->session_mutex); 1791 rc = cifs_negotiate_protocol(xid, ses); 1792 if (!rc) 1793 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1794 mutex_unlock(&ses->session_mutex); 1795 - if (rc) 1796 goto get_ses_fail; 1797 1798 /* success, put it on the list */ 1799 write_lock(&cifs_tcp_ses_lock);
··· 1707 CIFSSMBLogoff(xid, ses); 1708 _FreeXid(xid); 1709 } 1710 + cifs_crypto_shash_release(server); 1711 sesInfoFree(ses); 1712 cifs_put_tcp_session(server); 1713 } ··· 1786 ses->linux_uid = volume_info->linux_uid; 1787 ses->overrideSecFlg = volume_info->secFlg; 1788 1789 + rc = cifs_crypto_shash_allocate(server); 1790 + if (rc) { 1791 + cERROR(1, "could not setup hash structures rc %d", rc); 1792 + goto get_ses_fail; 1793 + } 1794 + server->tilen = 0; 1795 + server->tiblob = NULL; 1796 + 1797 mutex_lock(&ses->session_mutex); 1798 rc = cifs_negotiate_protocol(xid, ses); 1799 if (!rc) 1800 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1801 mutex_unlock(&ses->session_mutex); 1802 + if (rc) { 1803 + cifs_crypto_shash_release(ses->server); 1804 goto get_ses_fail; 1805 + } 1806 1807 /* success, put it on the list */ 1808 write_lock(&cifs_tcp_ses_lock);
+13
fs/cifs/ntlmssp.h
··· 61 #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 62 #define NTLMSSP_NEGOTIATE_56 0x80000000 63 64 /* Although typedefs are not commonly used for structure definitions */ 65 /* in the Linux kernel, in this particular case they are useful */ 66 /* to more closely match the standards document for NTLMSSP from */
··· 61 #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 62 #define NTLMSSP_NEGOTIATE_56 0x80000000 63 64 + /* Define AV Pair Field IDs */ 65 + #define NTLMSSP_AV_EOL 0 66 + #define NTLMSSP_AV_NB_COMPUTER_NAME 1 67 + #define NTLMSSP_AV_NB_DOMAIN_NAME 2 68 + #define NTLMSSP_AV_DNS_COMPUTER_NAME 3 69 + #define NTLMSSP_AV_DNS_DOMAIN_NAME 4 70 + #define NTLMSSP_AV_DNS_TREE_NAME 5 71 + #define NTLMSSP_AV_FLAGS 6 72 + #define NTLMSSP_AV_TIMESTAMP 7 73 + #define NTLMSSP_AV_RESTRICTION 8 74 + #define NTLMSSP_AV_TARGET_NAME 9 75 + #define NTLMSSP_AV_CHANNEL_BINDINGS 10 76 + 77 /* Although typedefs are not commonly used for structure definitions */ 78 /* in the Linux kernel, in this particular case they are useful */ 79 /* to more closely match the standards document for NTLMSSP from */
+89 -29
fs/cifs/sess.c
··· 383 static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 384 struct cifsSesInfo *ses) 385 { 386 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 387 388 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { ··· 407 /* In particular we can examine sign flags */ 408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 409 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 410 411 return 0; 412 } ··· 466 struct cifsSesInfo *ses, 467 const struct nls_table *nls_cp, bool first) 468 { 469 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 470 __u32 flags; 471 unsigned char *tmp; 472 - char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 473 474 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 475 sec_blob->MessageType = NtLmAuthenticate; ··· 494 sec_blob->LmChallengeResponse.Length = 0; 495 sec_blob->LmChallengeResponse.MaximumLength = 0; 496 497 - /* calculate session key, BB what about adding similar ntlmv2 path? */ 498 - SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key); 499 - if (first) 500 - cifs_calculate_mac_key(&ses->server->mac_signing_key, 501 - ntlm_session_key, ses->password); 502 - 503 - memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE); 504 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 505 - sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE); 506 - sec_blob->NtChallengeResponse.MaximumLength = 507 - cpu_to_le16(CIFS_SESS_KEY_SIZE); 508 509 - tmp += CIFS_SESS_KEY_SIZE; 510 511 if (ses->domainName == NULL) { 512 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); ··· 524 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 525 MAX_USERNAME_SIZE, nls_cp); 526 len *= 2; /* unicode is 2 bytes each */ 527 - len += 2; /* trailing null */ 528 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 529 sec_blob->DomainName.Length = cpu_to_le16(len); 530 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); ··· 540 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 541 MAX_USERNAME_SIZE, nls_cp); 542 len *= 2; /* unicode is 2 bytes each */ 543 - len += 2; /* trailing null */ 544 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 545 sec_blob->UserName.Length = cpu_to_le16(len); 546 sec_blob->UserName.MaximumLength = cpu_to_le16(len); ··· 551 sec_blob->WorkstationName.MaximumLength = 0; 552 tmp += 2; 553 554 - sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 555 - sec_blob->SessionKey.Length = 0; 556 - sec_blob->SessionKey.MaximumLength = 0; 557 return tmp - pbuffer; 558 } 559 ··· 584 return; 585 } 586 587 - static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, 588 struct cifsSesInfo *ses, 589 const struct nls_table *nls, bool first_time) 590 { 591 int bloblen; 592 593 - bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls, 594 first_time); 595 - pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen); 596 597 return bloblen; 598 } ··· 617 struct key *spnego_key = NULL; 618 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 619 bool first_time; 620 621 if (ses == NULL) 622 return -EINVAL; ··· 728 729 if (first_time) /* should this be moved into common code 730 with similar ntlmv2 path? */ 731 - cifs_calculate_mac_key(&ses->server->mac_signing_key, 732 ntlm_session_key, ses->password); 733 /* copy session key */ 734 ··· 767 cpu_to_le16(sizeof(struct ntlmv2_resp)); 768 769 /* calculate session key */ 770 - setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 771 /* FIXME: calculate MAC key */ 772 memcpy(bcc_ptr, (char *)v2_sess_key, 773 sizeof(struct ntlmv2_resp)); 774 bcc_ptr += sizeof(struct ntlmv2_resp); 775 kfree(v2_sess_key); 776 if (ses->capabilities & CAP_UNICODE) { 777 if (iov[0].iov_len % 2) { 778 *bcc_ptr = 0; ··· 812 } 813 /* bail out if key is too long */ 814 if (msg->sesskey_len > 815 - sizeof(ses->server->mac_signing_key.data.krb5)) { 816 cERROR(1, "Kerberos signing key too long (%u bytes)", 817 msg->sesskey_len); 818 rc = -EOVERFLOW; 819 goto ssetup_exit; 820 } 821 if (first_time) { 822 - ses->server->mac_signing_key.len = msg->sesskey_len; 823 - memcpy(ses->server->mac_signing_key.data.krb5, 824 msg->data, msg->sesskey_len); 825 } 826 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; ··· 862 if (phase == NtLmNegotiate) { 863 setup_ntlmssp_neg_req(pSMB, ses); 864 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 865 } else if (phase == NtLmAuthenticate) { 866 int blob_len; 867 - blob_len = setup_ntlmssp_auth_req(pSMB, ses, 868 - nls_cp, 869 - first_time); 870 iov[1].iov_len = blob_len; 871 /* Make sure that we tell the server that we 872 are using the uid that it just gave us back 873 on the response (challenge) */ ··· 891 rc = -ENOSYS; 892 goto ssetup_exit; 893 } 894 - iov[1].iov_base = &pSMB->req.SecurityBlob[0]; 895 /* unicode strings must be word aligned */ 896 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 897 *bcc_ptr = 0;
··· 383 static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 384 struct cifsSesInfo *ses) 385 { 386 + unsigned int tioffset; /* challeng message target info area */ 387 + unsigned int tilen; /* challeng message target info area length */ 388 + 389 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 390 391 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { ··· 404 /* In particular we can examine sign flags */ 405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 406 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 407 + 408 + tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); 409 + tilen = cpu_to_le16(pblob->TargetInfoArray.Length); 410 + ses->server->tilen = tilen; 411 + if (tilen) { 412 + ses->server->tiblob = kmalloc(tilen, GFP_KERNEL); 413 + if (!ses->server->tiblob) { 414 + cERROR(1, "Challenge target info allocation failure"); 415 + return -ENOMEM; 416 + } 417 + memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen); 418 + } 419 420 return 0; 421 } ··· 451 struct cifsSesInfo *ses, 452 const struct nls_table *nls_cp, bool first) 453 { 454 + int rc; 455 + unsigned int size; 456 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 457 __u32 flags; 458 unsigned char *tmp; 459 + struct ntlmv2_resp ntlmv2_response = {}; 460 461 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 462 sec_blob->MessageType = NtLmAuthenticate; ··· 477 sec_blob->LmChallengeResponse.Length = 0; 478 sec_blob->LmChallengeResponse.MaximumLength = 0; 479 480 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 481 + rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); 482 + if (rc) { 483 + cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); 484 + goto setup_ntlmv2_ret; 485 + } 486 + size = sizeof(struct ntlmv2_resp); 487 + memcpy(tmp, (char *)&ntlmv2_response, size); 488 + tmp += size; 489 + if (ses->server->tilen > 0) { 490 + memcpy(tmp, ses->server->tiblob, ses->server->tilen); 491 + tmp += ses->server->tilen; 492 + } else 493 + ses->server->tilen = 0; 494 495 + sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + 496 + ses->server->tilen); 497 + sec_blob->NtChallengeResponse.MaximumLength = 498 + cpu_to_le16(size + ses->server->tilen); 499 500 if (ses->domainName == NULL) { 501 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); ··· 501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 502 MAX_USERNAME_SIZE, nls_cp); 503 len *= 2; /* unicode is 2 bytes each */ 504 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 505 sec_blob->DomainName.Length = cpu_to_le16(len); 506 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); ··· 518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 519 MAX_USERNAME_SIZE, nls_cp); 520 len *= 2; /* unicode is 2 bytes each */ 521 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 522 sec_blob->UserName.Length = cpu_to_le16(len); 523 sec_blob->UserName.MaximumLength = cpu_to_le16(len); ··· 530 sec_blob->WorkstationName.MaximumLength = 0; 531 tmp += 2; 532 533 + if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && 534 + !calc_seckey(ses->server)) { 535 + memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); 536 + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 537 + sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); 538 + sec_blob->SessionKey.MaximumLength = 539 + cpu_to_le16(CIFS_CPHTXT_SIZE); 540 + tmp += CIFS_CPHTXT_SIZE; 541 + } else { 542 + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 543 + sec_blob->SessionKey.Length = 0; 544 + sec_blob->SessionKey.MaximumLength = 0; 545 + } 546 + 547 + ses->server->sequence_number = 0; 548 + 549 + setup_ntlmv2_ret: 550 + if (ses->server->tilen > 0) 551 + kfree(ses->server->tiblob); 552 + 553 return tmp - pbuffer; 554 } 555 ··· 546 return; 547 } 548 549 + static int setup_ntlmssp_auth_req(char *ntlmsspblob, 550 struct cifsSesInfo *ses, 551 const struct nls_table *nls, bool first_time) 552 { 553 int bloblen; 554 555 + bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, 556 first_time); 557 558 return bloblen; 559 } ··· 580 struct key *spnego_key = NULL; 581 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 582 bool first_time; 583 + char *ntlmsspblob; 584 585 if (ses == NULL) 586 return -EINVAL; ··· 690 691 if (first_time) /* should this be moved into common code 692 with similar ntlmv2 path? */ 693 + cifs_calculate_session_key(&ses->server->session_key, 694 ntlm_session_key, ses->password); 695 /* copy session key */ 696 ··· 729 cpu_to_le16(sizeof(struct ntlmv2_resp)); 730 731 /* calculate session key */ 732 + rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 733 + if (rc) { 734 + kfree(v2_sess_key); 735 + goto ssetup_exit; 736 + } 737 /* FIXME: calculate MAC key */ 738 memcpy(bcc_ptr, (char *)v2_sess_key, 739 sizeof(struct ntlmv2_resp)); 740 bcc_ptr += sizeof(struct ntlmv2_resp); 741 kfree(v2_sess_key); 742 + if (ses->server->tilen > 0) { 743 + memcpy(bcc_ptr, ses->server->tiblob, 744 + ses->server->tilen); 745 + bcc_ptr += ses->server->tilen; 746 + } 747 if (ses->capabilities & CAP_UNICODE) { 748 if (iov[0].iov_len % 2) { 749 *bcc_ptr = 0; ··· 765 } 766 /* bail out if key is too long */ 767 if (msg->sesskey_len > 768 + sizeof(ses->server->session_key.data.krb5)) { 769 cERROR(1, "Kerberos signing key too long (%u bytes)", 770 msg->sesskey_len); 771 rc = -EOVERFLOW; 772 goto ssetup_exit; 773 } 774 if (first_time) { 775 + ses->server->session_key.len = msg->sesskey_len; 776 + memcpy(ses->server->session_key.data.krb5, 777 msg->data, msg->sesskey_len); 778 } 779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; ··· 815 if (phase == NtLmNegotiate) { 816 setup_ntlmssp_neg_req(pSMB, ses); 817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 818 + iov[1].iov_base = &pSMB->req.SecurityBlob[0]; 819 } else if (phase == NtLmAuthenticate) { 820 int blob_len; 821 + ntlmsspblob = kmalloc(5 * 822 + sizeof(struct _AUTHENTICATE_MESSAGE), 823 + GFP_KERNEL); 824 + if (!ntlmsspblob) { 825 + cERROR(1, "Can't allocate NTLMSSP"); 826 + rc = -ENOMEM; 827 + goto ssetup_exit; 828 + } 829 + 830 + blob_len = setup_ntlmssp_auth_req(ntlmsspblob, 831 + ses, 832 + nls_cp, 833 + first_time); 834 iov[1].iov_len = blob_len; 835 + iov[1].iov_base = ntlmsspblob; 836 + pSMB->req.SecurityBlobLength = 837 + cpu_to_le16(blob_len); 838 /* Make sure that we tell the server that we 839 are using the uid that it just gave us back 840 on the response (challenge) */ ··· 830 rc = -ENOSYS; 831 goto ssetup_exit; 832 } 833 /* unicode strings must be word aligned */ 834 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 835 *bcc_ptr = 0;
+3 -3
fs/cifs/transport.c
··· 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 544 SECMODE_SIGN_ENABLED))) { 545 rc = cifs_verify_signature(midQ->resp_buf, 546 - &ses->server->mac_signing_key, 547 midQ->sequence_number+1); 548 if (rc) { 549 cERROR(1, "Unexpected SMB signature"); ··· 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 732 SECMODE_SIGN_ENABLED))) { 733 rc = cifs_verify_signature(out_buf, 734 - &ses->server->mac_signing_key, 735 midQ->sequence_number+1); 736 if (rc) { 737 cERROR(1, "Unexpected SMB signature"); ··· 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 982 SECMODE_SIGN_ENABLED))) { 983 rc = cifs_verify_signature(out_buf, 984 - &ses->server->mac_signing_key, 985 midQ->sequence_number+1); 986 if (rc) { 987 cERROR(1, "Unexpected SMB signature");
··· 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 544 SECMODE_SIGN_ENABLED))) { 545 rc = cifs_verify_signature(midQ->resp_buf, 546 + ses->server, 547 midQ->sequence_number+1); 548 if (rc) { 549 cERROR(1, "Unexpected SMB signature"); ··· 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 732 SECMODE_SIGN_ENABLED))) { 733 rc = cifs_verify_signature(out_buf, 734 + ses->server, 735 midQ->sequence_number+1); 736 if (rc) { 737 cERROR(1, "Unexpected SMB signature"); ··· 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 982 SECMODE_SIGN_ENABLED))) { 983 rc = cifs_verify_signature(out_buf, 984 + ses->server, 985 midQ->sequence_number+1); 986 if (rc) { 987 cERROR(1, "Unexpected SMB signature");