aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsencrypt.c193
-rw-r--r--fs/cifs/cifsglob.h7
2 files changed, 128 insertions, 72 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index eef78c24e0cc..709f2296bdb4 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -45,39 +45,38 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
46 struct TCP_Server_Info *server, char *signature) 46 struct TCP_Server_Info *server, char *signature)
47{ 47{
48 int rc = 0; 48 int rc;
49 struct {
50 struct shash_desc shash;
51 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
52 } sdesc;
53 49
54 if (cifs_pdu == NULL || server == NULL || signature == NULL) 50 if (cifs_pdu == NULL || server == NULL || signature == NULL)
55 return -EINVAL; 51 return -EINVAL;
56 52
57 sdesc.shash.tfm = server->ntlmssp.md5; 53 if (!server->ntlmssp.sdescmd5) {
58 sdesc.shash.flags = 0x0; 54 cERROR(1,
55 "cifs_calculate_signature: can't generate signature\n");
56 return -1;
57 }
59 58
60 rc = crypto_shash_init(&sdesc.shash); 59 rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash);
61 if (rc) { 60 if (rc) {
62 cERROR(1, "could not initialize master crypto API hmacmd5\n"); 61 cERROR(1, "cifs_calculate_signature: oould not init md5\n");
63 return rc; 62 return rc;
64 } 63 }
65 64
66 if (server->secType == RawNTLMSSP) 65 if (server->secType == RawNTLMSSP)
67 crypto_shash_update(&sdesc.shash, 66 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
68 server->session_key.data.ntlmv2.key, 67 server->session_key.data.ntlmv2.key,
69 CIFS_NTLMV2_SESSKEY_SIZE); 68 CIFS_NTLMV2_SESSKEY_SIZE);
70 else 69 else
71 crypto_shash_update(&sdesc.shash, 70 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
72 (char *)&server->session_key.data, 71 (char *)&server->session_key.data,
73 server->session_key.len); 72 server->session_key.len);
74 73
75 crypto_shash_update(&sdesc.shash, 74 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
76 cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 75 cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
77 76
78 rc = crypto_shash_final(&sdesc.shash, signature); 77 rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature);
79 78
80 return 0; 79 return rc;
81} 80}
82 81
83 82
@@ -115,30 +114,28 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
115 struct TCP_Server_Info *server, char *signature) 114 struct TCP_Server_Info *server, char *signature)
116{ 115{
117 int i; 116 int i;
118 int rc = 0; 117 int rc;
119 struct {
120 struct shash_desc shash;
121 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
122 } sdesc;
123 118
124 if (iov == NULL || server == NULL || signature == NULL) 119 if (iov == NULL || server == NULL || signature == NULL)
125 return -EINVAL; 120 return -EINVAL;
126 121
127 sdesc.shash.tfm = server->ntlmssp.md5; 122 if (!server->ntlmssp.sdescmd5) {
128 sdesc.shash.flags = 0x0; 123 cERROR(1, "cifs_calc_signature2: can't generate signature\n");
124 return -1;
125 }
129 126
130 rc = crypto_shash_init(&sdesc.shash); 127 rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash);
131 if (rc) { 128 if (rc) {
132 cERROR(1, "could not initialize master crypto API hmacmd5\n"); 129 cERROR(1, "cifs_calc_signature2: oould not init md5\n");
133 return rc; 130 return rc;
134 } 131 }
135 132
136 if (server->secType == RawNTLMSSP) 133 if (server->secType == RawNTLMSSP)
137 crypto_shash_update(&sdesc.shash, 134 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
138 server->session_key.data.ntlmv2.key, 135 server->session_key.data.ntlmv2.key,
139 CIFS_NTLMV2_SESSKEY_SIZE); 136 CIFS_NTLMV2_SESSKEY_SIZE);
140 else 137 else
141 crypto_shash_update(&sdesc.shash, 138 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
142 (char *)&server->session_key.data, 139 (char *)&server->session_key.data,
143 server->session_key.len); 140 server->session_key.len);
144 141
@@ -146,7 +143,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
146 if (iov[i].iov_len == 0) 143 if (iov[i].iov_len == 0)
147 continue; 144 continue;
148 if (iov[i].iov_base == NULL) { 145 if (iov[i].iov_base == NULL) {
149 cERROR(1, "null iovec entry"); 146 cERROR(1, "cifs_calc_signature2: null iovec entry");
150 return -EIO; 147 return -EIO;
151 } 148 }
152 /* The first entry includes a length field (which does not get 149 /* The first entry includes a length field (which does not get
@@ -154,16 +151,16 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
154 if (i == 0) { 151 if (i == 0) {
155 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 152 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
156 break; /* nothing to sign or corrupt header */ 153 break; /* nothing to sign or corrupt header */
157 crypto_shash_update(&sdesc.shash, 154 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
158 iov[i].iov_base + 4, iov[i].iov_len - 4); 155 iov[i].iov_base + 4, iov[i].iov_len - 4);
159 } else 156 } else
160 crypto_shash_update(&sdesc.shash, 157 crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
161 iov[i].iov_base, iov[i].iov_len); 158 iov[i].iov_base, iov[i].iov_len);
162 } 159 }
163 160
164 rc = crypto_shash_final(&sdesc.shash, signature); 161 rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature);
165 162
166 return 0; 163 return rc;
167} 164}
168 165
169int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 166int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
@@ -313,43 +310,48 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
313 wchar_t *user; 310 wchar_t *user;
314 wchar_t *domain; 311 wchar_t *domain;
315 wchar_t *server; 312 wchar_t *server;
316 struct { 313
317 struct shash_desc shash; 314 if (!ses->server->ntlmssp.sdeschmacmd5) {
318 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)]; 315 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
319 } sdesc; 316 return -1;
317 }
320 318
321 /* calculate md4 hash of password */ 319 /* calculate md4 hash of password */
322 E_md4hash(ses->password, nt_hash); 320 E_md4hash(ses->password, nt_hash);
323 321
324 sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
325 sdesc.shash.flags = 0x0;
326
327 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, 322 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash,
328 CIFS_NTHASH_SIZE); 323 CIFS_NTHASH_SIZE);
329 324
330 rc = crypto_shash_init(&sdesc.shash); 325 rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash);
331 if (rc) { 326 if (rc) {
332 cERROR(1, "could not initialize master crypto API hmacmd5\n"); 327 cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
333 return rc; 328 return rc;
334 } 329 }
335 330
336 /* convert ses->userName to unicode and uppercase */ 331 /* convert ses->userName to unicode and uppercase */
337 len = strlen(ses->userName); 332 len = strlen(ses->userName);
338 user = kmalloc(2 + (len * 2), GFP_KERNEL); 333 user = kmalloc(2 + (len * 2), GFP_KERNEL);
339 if (user == NULL) 334 if (user == NULL) {
335 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
336 rc = -ENOMEM;
340 goto calc_exit_2; 337 goto calc_exit_2;
338 }
341 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 339 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
342 UniStrupr(user); 340 UniStrupr(user);
343 341
344 crypto_shash_update(&sdesc.shash, (char *)user, 2 * len); 342 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
343 (char *)user, 2 * len);
345 344
346 /* convert ses->domainName to unicode and uppercase */ 345 /* convert ses->domainName to unicode and uppercase */
347 if (ses->domainName) { 346 if (ses->domainName) {
348 len = strlen(ses->domainName); 347 len = strlen(ses->domainName);
349 348
350 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 349 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
351 if (domain == NULL) 350 if (domain == NULL) {
351 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
352 rc = -ENOMEM;
352 goto calc_exit_1; 353 goto calc_exit_1;
354 }
353 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 355 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
354 nls_cp); 356 nls_cp);
355 /* the following line was removed since it didn't work well 357 /* the following line was removed since it didn't work well
@@ -357,15 +359,19 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
357 Maybe converting the domain name earlier makes sense */ 359 Maybe converting the domain name earlier makes sense */
358 /* UniStrupr(domain); */ 360 /* UniStrupr(domain); */
359 361
360 crypto_shash_update(&sdesc.shash, (char *)domain, 2 * len); 362 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
363 (char *)domain, 2 * len);
361 364
362 kfree(domain); 365 kfree(domain);
363 } else if (ses->serverName) { 366 } else if (ses->serverName) {
364 len = strlen(ses->serverName); 367 len = strlen(ses->serverName);
365 368
366 server = kmalloc(2 + (len * 2), GFP_KERNEL); 369 server = kmalloc(2 + (len * 2), GFP_KERNEL);
367 if (server == NULL) 370 if (server == NULL) {
371 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
372 rc = -ENOMEM;
368 goto calc_exit_1; 373 goto calc_exit_1;
374 }
369 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, 375 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
370 nls_cp); 376 nls_cp);
371 /* the following line was removed since it didn't work well 377 /* the following line was removed since it didn't work well
@@ -373,16 +379,20 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
373 Maybe converting the domain name earlier makes sense */ 379 Maybe converting the domain name earlier makes sense */
374 /* UniStrupr(domain); */ 380 /* UniStrupr(domain); */
375 381
376 crypto_shash_update(&sdesc.shash, (char *)server, 2 * len); 382 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
383 (char *)server, 2 * len);
377 384
378 kfree(server); 385 kfree(server);
379 } 386 }
387
388 rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash,
389 ses->server->ntlmv2_hash);
390
380calc_exit_1: 391calc_exit_1:
381 kfree(user); 392 kfree(user);
382calc_exit_2: 393calc_exit_2:
383 /* BB FIXME what about bytes 24 through 40 of the signing key? 394 /* BB FIXME what about bytes 24 through 40 of the signing key?
384 compare with the NTLM example */ 395 compare with the NTLM example */
385 rc = crypto_shash_final(&sdesc.shash, ses->server->ntlmv2_hash);
386 396
387 return rc; 397 return rc;
388} 398}
@@ -442,34 +452,33 @@ CalcNTLMv2_response(const struct TCP_Server_Info *server,
442 char *v2_session_response) 452 char *v2_session_response)
443{ 453{
444 int rc; 454 int rc;
445 struct {
446 struct shash_desc shash;
447 char ctx[crypto_shash_descsize(server->ntlmssp.hmacmd5)];
448 } sdesc;
449 455
450 sdesc.shash.tfm = server->ntlmssp.hmacmd5; 456 if (!server->ntlmssp.sdeschmacmd5) {
451 sdesc.shash.flags = 0x0; 457 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
458 return -1;
459 }
452 460
453 crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash, 461 crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash,
454 CIFS_HMAC_MD5_HASH_SIZE); 462 CIFS_HMAC_MD5_HASH_SIZE);
455 463
456 rc = crypto_shash_init(&sdesc.shash); 464 rc = crypto_shash_init(&server->ntlmssp.sdeschmacmd5->shash);
457 if (rc) { 465 if (rc) {
458 cERROR(1, "could not initialize master crypto API hmacmd5\n"); 466 cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
459 return rc; 467 return rc;
460 } 468 }
461 469
462 memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 470 memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
463 server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); 471 server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE);
464 crypto_shash_update(&sdesc.shash, 472 crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash,
465 v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 473 v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
466 sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); 474 sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE);
467 475
468 if (server->tilen) 476 if (server->tilen)
469 crypto_shash_update(&sdesc.shash, 477 crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash,
470 server->tiblob, server->tilen); 478 server->tiblob, server->tilen);
471 479
472 rc = crypto_shash_final(&sdesc.shash, v2_session_response); 480 rc = crypto_shash_final(&server->ntlmssp.sdeschmacmd5->shash,
481 v2_session_response);
473 482
474 return rc; 483 return rc;
475} 484}
@@ -480,10 +489,6 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
480{ 489{
481 int rc = 0; 490 int rc = 0;
482 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 491 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
483 struct {
484 struct shash_desc shash;
485 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
486 } sdesc;
487 492
488 buf->blob_signature = cpu_to_le32(0x00000101); 493 buf->blob_signature = cpu_to_le32(0x00000101);
489 buf->reserved = 0; 494 buf->reserved = 0;
@@ -511,21 +516,24 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
511 return rc; 516 return rc;
512 } 517 }
513 518
519 if (!ses->server->ntlmssp.sdeschmacmd5) {
520 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
521 return -1;
522 }
523
514 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, 524 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5,
515 ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 525 ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
516 526
517 sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5; 527 rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash);
518 sdesc.shash.flags = 0x0;
519
520 rc = crypto_shash_init(&sdesc.shash);
521 if (rc) { 528 if (rc) {
522 cERROR(1, "could not initialize master crypto API hmacmd5\n"); 529 cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n");
523 return rc; 530 return rc;
524 } 531 }
525 532
526 crypto_shash_update(&sdesc.shash, resp_buf, CIFS_HMAC_MD5_HASH_SIZE); 533 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
534 resp_buf, CIFS_HMAC_MD5_HASH_SIZE);
527 535
528 rc = crypto_shash_final(&sdesc.shash, 536 rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash,
529 ses->server->session_key.data.ntlmv2.key); 537 ses->server->session_key.data.ntlmv2.key);
530 538
531 memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, 539 memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf,
@@ -578,24 +586,65 @@ cifs_crypto_shash_release(struct TCP_Server_Info *server)
578 586
579 if (server->ntlmssp.hmacmd5) 587 if (server->ntlmssp.hmacmd5)
580 crypto_free_shash(server->ntlmssp.hmacmd5); 588 crypto_free_shash(server->ntlmssp.hmacmd5);
589
590 kfree(server->ntlmssp.sdeschmacmd5);
591
592 kfree(server->ntlmssp.sdescmd5);
581} 593}
582 594
583int 595int
584cifs_crypto_shash_allocate(struct TCP_Server_Info *server) 596cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
585{ 597{
598 int rc;
599 unsigned int size;
600
586 server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 601 server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
587 if (!server->ntlmssp.hmacmd5 || 602 if (!server->ntlmssp.hmacmd5 ||
588 IS_ERR(server->ntlmssp.hmacmd5)) { 603 IS_ERR(server->ntlmssp.hmacmd5)) {
589 cERROR(1, "could not allocate master crypto API hmacmd5\n"); 604 cERROR(1, "could not allocate crypto hmacmd5\n");
590 return 1; 605 return 1;
591 } 606 }
592 607
593 server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); 608 server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0);
594 if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { 609 if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) {
595 crypto_free_shash(server->ntlmssp.hmacmd5); 610 cERROR(1, "could not allocate crypto md5\n");
596 cERROR(1, "could not allocate master crypto API md5\n"); 611 rc = 1;
597 return 1; 612 goto cifs_crypto_shash_allocate_ret1;
598 } 613 }
599 614
615 size = sizeof(struct shash_desc) +
616 crypto_shash_descsize(server->ntlmssp.hmacmd5);
617 server->ntlmssp.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
618 if (!server->ntlmssp.sdeschmacmd5) {
619 cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
620 rc = -ENOMEM;
621 goto cifs_crypto_shash_allocate_ret2;
622 }
623 server->ntlmssp.sdeschmacmd5->shash.tfm = server->ntlmssp.hmacmd5;
624 server->ntlmssp.sdeschmacmd5->shash.flags = 0x0;
625
626
627 size = sizeof(struct shash_desc) +
628 crypto_shash_descsize(server->ntlmssp.md5);
629 server->ntlmssp.sdescmd5 = kmalloc(size, GFP_KERNEL);
630 if (!server->ntlmssp.sdescmd5) {
631 cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
632 rc = -ENOMEM;
633 goto cifs_crypto_shash_allocate_ret3;
634 }
635 server->ntlmssp.sdescmd5->shash.tfm = server->ntlmssp.md5;
636 server->ntlmssp.sdescmd5->shash.flags = 0x0;
637
600 return 0; 638 return 0;
639
640cifs_crypto_shash_allocate_ret3:
641 kfree(server->ntlmssp.sdeschmacmd5);
642
643cifs_crypto_shash_allocate_ret2:
644 crypto_free_shash(server->ntlmssp.md5);
645
646cifs_crypto_shash_allocate_ret1:
647 crypto_free_shash(server->ntlmssp.hmacmd5);
648
649 return rc;
601} 650}
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 49563e0c1725..c9d0cfc086eb 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -123,12 +123,19 @@ struct cifs_cred {
123 struct cifs_ace *aces; 123 struct cifs_ace *aces;
124}; 124};
125 125
126struct sdesc {
127 struct shash_desc shash;
128 char ctx[];
129};
130
126struct ntlmssp_auth { 131struct ntlmssp_auth {
127 __u32 client_flags; 132 __u32 client_flags;
128 __u32 server_flags; 133 __u32 server_flags;
129 unsigned char ciphertext[CIFS_CPHTXT_SIZE]; 134 unsigned char ciphertext[CIFS_CPHTXT_SIZE];
130 struct crypto_shash *hmacmd5; 135 struct crypto_shash *hmacmd5;
131 struct crypto_shash *md5; 136 struct crypto_shash *md5;
137 struct sdesc *sdeschmacmd5;
138 struct sdesc *sdescmd5;
132}; 139};
133 140
134/* 141/*