Skip to content

Commit 1f3d547

Browse files
ematsumiyasmfrench
authored andcommitted
cifs: secmech: use shash_desc directly, remove sdesc
The struct sdesc is just a wrapper around shash_desc, with exact same memory layout. Replace the hashing TFMs with shash_desc as it's what's passed to the crypto API anyway. Also remove the crypto_shash pointers as they can be accessed via shash_desc->tfm (and are actually only used in the setkey calls). Adapt cifs_{alloc,free}_hash functions to this change. Signed-off-by: Enzo Matsumiya <[email protected]> Reviewed-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 8698baa commit 1f3d547

File tree

7 files changed

+98
-166
lines changed

7 files changed

+98
-166
lines changed

fs/cifs/cifsencrypt.c

Lines changed: 26 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -103,26 +103,24 @@ static int cifs_calc_signature(struct smb_rqst *rqst,
103103
if (!rqst->rq_iov || !signature || !server)
104104
return -EINVAL;
105105

106-
rc = cifs_alloc_hash("md5", &server->secmech.md5,
107-
&server->secmech.sdescmd5);
106+
rc = cifs_alloc_hash("md5", &server->secmech.md5);
108107
if (rc)
109108
return -1;
110109

111-
rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
110+
rc = crypto_shash_init(server->secmech.md5);
112111
if (rc) {
113112
cifs_dbg(VFS, "%s: Could not init md5\n", __func__);
114113
return rc;
115114
}
116115

117-
rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
116+
rc = crypto_shash_update(server->secmech.md5,
118117
server->session_key.response, server->session_key.len);
119118
if (rc) {
120119
cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
121120
return rc;
122121
}
123122

124-
return __cifs_calc_signature(rqst, server, signature,
125-
&server->secmech.sdescmd5->shash);
123+
return __cifs_calc_signature(rqst, server, signature, server->secmech.md5);
126124
}
127125

128126
/* must be called with server->srv_mutex held */
@@ -412,22 +410,22 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
412410
wchar_t *domain;
413411
wchar_t *server;
414412

415-
if (!ses->server->secmech.sdeschmacmd5) {
413+
if (!ses->server->secmech.hmacmd5) {
416414
cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
417415
return -1;
418416
}
419417

420418
/* calculate md4 hash of password */
421419
E_md4hash(ses->password, nt_hash, nls_cp);
422420

423-
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
421+
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, nt_hash,
424422
CIFS_NTHASH_SIZE);
425423
if (rc) {
426424
cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__);
427425
return rc;
428426
}
429427

430-
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
428+
rc = crypto_shash_init(ses->server->secmech.hmacmd5);
431429
if (rc) {
432430
cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
433431
return rc;
@@ -448,7 +446,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
448446
memset(user, '\0', 2);
449447
}
450448

451-
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
449+
rc = crypto_shash_update(ses->server->secmech.hmacmd5,
452450
(char *)user, 2 * len);
453451
kfree(user);
454452
if (rc) {
@@ -468,7 +466,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
468466
len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
469467
nls_cp);
470468
rc =
471-
crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
469+
crypto_shash_update(ses->server->secmech.hmacmd5,
472470
(char *)domain, 2 * len);
473471
kfree(domain);
474472
if (rc) {
@@ -488,7 +486,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
488486
len = cifs_strtoUTF16((__le16 *)server, ses->ip_addr, len,
489487
nls_cp);
490488
rc =
491-
crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
489+
crypto_shash_update(ses->server->secmech.hmacmd5,
492490
(char *)server, 2 * len);
493491
kfree(server);
494492
if (rc) {
@@ -498,7 +496,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
498496
}
499497
}
500498

501-
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
499+
rc = crypto_shash_final(ses->server->secmech.hmacmd5,
502500
ntlmv2_hash);
503501
if (rc)
504502
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
@@ -518,20 +516,20 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
518516
hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE +
519517
offsetof(struct ntlmv2_resp, challenge.key[0]));
520518

521-
if (!ses->server->secmech.sdeschmacmd5) {
519+
if (!ses->server->secmech.hmacmd5) {
522520
cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
523521
return -1;
524522
}
525523

526-
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
524+
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm,
527525
ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
528526
if (rc) {
529527
cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
530528
__func__);
531529
return rc;
532530
}
533531

534-
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
532+
rc = crypto_shash_init(ses->server->secmech.hmacmd5);
535533
if (rc) {
536534
cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
537535
return rc;
@@ -543,15 +541,15 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
543541
else
544542
memcpy(ntlmv2->challenge.key,
545543
ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
546-
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
544+
rc = crypto_shash_update(ses->server->secmech.hmacmd5,
547545
ntlmv2->challenge.key, hash_len);
548546
if (rc) {
549547
cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
550548
return rc;
551549
}
552550

553551
/* Note that the MD5 digest over writes anon.challenge_key.key */
554-
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
552+
rc = crypto_shash_final(ses->server->secmech.hmacmd5,
555553
ntlmv2->ntlmv2_hash);
556554
if (rc)
557555
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
@@ -627,9 +625,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
627625

628626
cifs_server_lock(ses->server);
629627

630-
rc = cifs_alloc_hash("hmac(md5)",
631-
&ses->server->secmech.hmacmd5,
632-
&ses->server->secmech.sdeschmacmd5);
628+
rc = cifs_alloc_hash("hmac(md5)", &ses->server->secmech.hmacmd5);
633629
if (rc) {
634630
goto unlock;
635631
}
@@ -649,29 +645,29 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
649645
}
650646

651647
/* now calculate the session key for NTLMv2 */
652-
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
648+
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm,
653649
ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
654650
if (rc) {
655651
cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
656652
__func__);
657653
goto unlock;
658654
}
659655

660-
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
656+
rc = crypto_shash_init(ses->server->secmech.hmacmd5);
661657
if (rc) {
662658
cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
663659
goto unlock;
664660
}
665661

666-
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
662+
rc = crypto_shash_update(ses->server->secmech.hmacmd5,
667663
ntlmv2->ntlmv2_hash,
668664
CIFS_HMAC_MD5_HASH_SIZE);
669665
if (rc) {
670666
cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
671667
goto unlock;
672668
}
673669

674-
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
670+
rc = crypto_shash_final(ses->server->secmech.hmacmd5,
675671
ses->auth_key.response);
676672
if (rc)
677673
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
@@ -718,30 +714,11 @@ calc_seckey(struct cifs_ses *ses)
718714
void
719715
cifs_crypto_secmech_release(struct TCP_Server_Info *server)
720716
{
721-
if (server->secmech.cmacaes) {
722-
crypto_free_shash(server->secmech.cmacaes);
723-
server->secmech.cmacaes = NULL;
724-
}
725-
726-
if (server->secmech.hmacsha256) {
727-
crypto_free_shash(server->secmech.hmacsha256);
728-
server->secmech.hmacsha256 = NULL;
729-
}
730-
731-
if (server->secmech.md5) {
732-
crypto_free_shash(server->secmech.md5);
733-
server->secmech.md5 = NULL;
734-
}
735-
736-
if (server->secmech.sha512) {
737-
crypto_free_shash(server->secmech.sha512);
738-
server->secmech.sha512 = NULL;
739-
}
740-
741-
if (server->secmech.hmacmd5) {
742-
crypto_free_shash(server->secmech.hmacmd5);
743-
server->secmech.hmacmd5 = NULL;
744-
}
717+
cifs_free_hash(&server->secmech.aes_cmac);
718+
cifs_free_hash(&server->secmech.hmacsha256);
719+
cifs_free_hash(&server->secmech.md5);
720+
cifs_free_hash(&server->secmech.sha512);
721+
cifs_free_hash(&server->secmech.hmacmd5);
745722

746723
if (server->secmech.enc) {
747724
crypto_free_aead(server->secmech.enc);
@@ -752,15 +729,4 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
752729
crypto_free_aead(server->secmech.dec);
753730
server->secmech.dec = NULL;
754731
}
755-
756-
kfree_sensitive(server->secmech.sdesccmacaes);
757-
server->secmech.sdesccmacaes = NULL;
758-
kfree_sensitive(server->secmech.sdeschmacsha256);
759-
server->secmech.sdeschmacsha256 = NULL;
760-
kfree_sensitive(server->secmech.sdeschmacmd5);
761-
server->secmech.sdeschmacmd5 = NULL;
762-
kfree_sensitive(server->secmech.sdescmd5);
763-
server->secmech.sdescmd5 = NULL;
764-
kfree_sensitive(server->secmech.sdescsha512);
765-
server->secmech.sdescsha512 = NULL;
766732
}

fs/cifs/cifsglob.h

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,26 +153,16 @@ struct session_key {
153153
char *response;
154154
};
155155

156-
/* crypto security descriptor definition */
157-
struct sdesc {
158-
struct shash_desc shash;
159-
char ctx[];
160-
};
161-
162156
/* crypto hashing related structure/fields, not specific to a sec mech */
163157
struct cifs_secmech {
164-
struct crypto_shash *hmacmd5; /* hmac-md5 hash function */
165-
struct crypto_shash *md5; /* md5 hash function */
166-
struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */
167-
struct crypto_shash *cmacaes; /* block-cipher based MAC function */
168-
struct crypto_shash *sha512; /* sha512 hash function */
169-
struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */
170-
struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */
171-
struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */
172-
struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */
173-
struct sdesc *sdescsha512; /* ctxt to generate smb3.11 signing key */
174-
struct crypto_aead *enc; /* smb3 AEAD encryption TFM (AES-CCM and AES-GCM) */
175-
struct crypto_aead *dec; /* smb3 AEAD decryption TFM (AES-CCM and AES-GCM) */
158+
struct shash_desc *hmacmd5; /* hmacmd5 hash function, for NTLMv2/CR1 hashes */
159+
struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */
160+
struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */
161+
struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */
162+
struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */
163+
164+
struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
165+
struct crypto_aead *dec; /* smb3 decryption AEAD TFM (AES-CCM and AES-GCM) */
176166
};
177167

178168
/* per smb session structure/fields */

fs/cifs/cifsproto.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,8 @@ struct cifs_aio_ctx *cifs_aio_ctx_alloc(void);
598598
void cifs_aio_ctx_release(struct kref *refcount);
599599
int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw);
600600

601-
int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
602-
struct sdesc **sdesc);
603-
void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
601+
int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
602+
void cifs_free_hash(struct shash_desc **sdesc);
604603

605604
extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
606605
unsigned int *len, unsigned int *offset);

fs/cifs/link.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,28 @@ static int
3838
symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
3939
{
4040
int rc;
41-
struct crypto_shash *md5 = NULL;
42-
struct sdesc *sdescmd5 = NULL;
41+
struct shash_desc *md5 = NULL;
4342

44-
rc = cifs_alloc_hash("md5", &md5, &sdescmd5);
43+
rc = cifs_alloc_hash("md5", &md5);
4544
if (rc)
4645
goto symlink_hash_err;
4746

48-
rc = crypto_shash_init(&sdescmd5->shash);
47+
rc = crypto_shash_init(md5);
4948
if (rc) {
5049
cifs_dbg(VFS, "%s: Could not init md5 shash\n", __func__);
5150
goto symlink_hash_err;
5251
}
53-
rc = crypto_shash_update(&sdescmd5->shash, link_str, link_len);
52+
rc = crypto_shash_update(md5, link_str, link_len);
5453
if (rc) {
5554
cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__);
5655
goto symlink_hash_err;
5756
}
58-
rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
57+
rc = crypto_shash_final(md5, md5_hash);
5958
if (rc)
6059
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
6160

6261
symlink_hash_err:
63-
cifs_free_hash(&md5, &sdescmd5);
62+
cifs_free_hash(&md5);
6463
return rc;
6564
}
6665

fs/cifs/misc.c

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,59 +1071,58 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
10711071
/**
10721072
* cifs_alloc_hash - allocate hash and hash context together
10731073
* @name: The name of the crypto hash algo
1074-
* @shash: Where to put the pointer to the hash algo
1075-
* @sdesc: Where to put the pointer to the hash descriptor
1074+
* @sdesc: SHASH descriptor where to put the pointer to the hash TFM
10761075
*
10771076
* The caller has to make sure @sdesc is initialized to either NULL or
1078-
* a valid context. Both can be freed via cifs_free_hash().
1077+
* a valid context. It can be freed via cifs_free_hash().
10791078
*/
10801079
int
1081-
cifs_alloc_hash(const char *name,
1082-
struct crypto_shash **shash, struct sdesc **sdesc)
1080+
cifs_alloc_hash(const char *name, struct shash_desc **sdesc)
10831081
{
10841082
int rc = 0;
1085-
size_t size;
1083+
struct crypto_shash *alg = NULL;
10861084

1087-
if (*sdesc != NULL)
1085+
if (*sdesc)
10881086
return 0;
10891087

1090-
*shash = crypto_alloc_shash(name, 0, 0);
1091-
if (IS_ERR(*shash)) {
1092-
cifs_dbg(VFS, "Could not allocate crypto %s\n", name);
1093-
rc = PTR_ERR(*shash);
1094-
*shash = NULL;
1088+
alg = crypto_alloc_shash(name, 0, 0);
1089+
if (IS_ERR(alg)) {
1090+
cifs_dbg(VFS, "Could not allocate shash TFM '%s'\n", name);
1091+
rc = PTR_ERR(alg);
10951092
*sdesc = NULL;
10961093
return rc;
10971094
}
10981095

1099-
size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash);
1100-
*sdesc = kmalloc(size, GFP_KERNEL);
1096+
*sdesc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(alg), GFP_KERNEL);
11011097
if (*sdesc == NULL) {
1102-
cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name);
1103-
crypto_free_shash(*shash);
1104-
*shash = NULL;
1098+
cifs_dbg(VFS, "no memory left to allocate shash TFM '%s'\n", name);
1099+
crypto_free_shash(alg);
11051100
return -ENOMEM;
11061101
}
11071102

1108-
(*sdesc)->shash.tfm = *shash;
1103+
(*sdesc)->tfm = alg;
11091104
return 0;
11101105
}
11111106

11121107
/**
11131108
* cifs_free_hash - free hash and hash context together
1114-
* @shash: Where to find the pointer to the hash algo
1115-
* @sdesc: Where to find the pointer to the hash descriptor
1109+
* @sdesc: Where to find the pointer to the hash TFM
11161110
*
1117-
* Freeing a NULL hash or context is safe.
1111+
* Freeing a NULL descriptor is safe.
11181112
*/
11191113
void
1120-
cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
1114+
cifs_free_hash(struct shash_desc **sdesc)
11211115
{
1116+
if (unlikely(!sdesc) || !*sdesc)
1117+
return;
1118+
1119+
if ((*sdesc)->tfm) {
1120+
crypto_free_shash((*sdesc)->tfm);
1121+
(*sdesc)->tfm = NULL;
1122+
}
1123+
11221124
kfree_sensitive(*sdesc);
11231125
*sdesc = NULL;
1124-
if (*shash)
1125-
crypto_free_shash(*shash);
1126-
*shash = NULL;
11271126
}
11281127

11291128
/**

0 commit comments

Comments
 (0)