2424#include <linux/iov_iter.h>
2525#include <crypto/aead.h>
2626#include <crypto/arc4.h>
27+ #include <crypto/md5.h>
28+ #include <crypto/sha2.h>
2729
28- static size_t cifs_shash_step ( void * iter_base , size_t progress , size_t len ,
29- void * priv , void * priv2 )
30+ static int cifs_sig_update ( struct cifs_calc_sig_ctx * ctx ,
31+ const u8 * data , size_t len )
3032{
31- struct shash_desc * shash = priv ;
33+ if (ctx -> md5 ) {
34+ md5_update (ctx -> md5 , data , len );
35+ return 0 ;
36+ }
37+ if (ctx -> hmac ) {
38+ hmac_sha256_update (ctx -> hmac , data , len );
39+ return 0 ;
40+ }
41+ return crypto_shash_update (ctx -> shash , data , len );
42+ }
43+
44+ static int cifs_sig_final (struct cifs_calc_sig_ctx * ctx , u8 * out )
45+ {
46+ if (ctx -> md5 ) {
47+ md5_final (ctx -> md5 , out );
48+ return 0 ;
49+ }
50+ if (ctx -> hmac ) {
51+ hmac_sha256_final (ctx -> hmac , out );
52+ return 0 ;
53+ }
54+ return crypto_shash_final (ctx -> shash , out );
55+ }
56+
57+ static size_t cifs_sig_step (void * iter_base , size_t progress , size_t len ,
58+ void * priv , void * priv2 )
59+ {
60+ struct cifs_calc_sig_ctx * ctx = priv ;
3261 int ret , * pret = priv2 ;
3362
34- ret = crypto_shash_update ( shash , iter_base , len );
63+ ret = cifs_sig_update ( ctx , iter_base , len );
3564 if (ret < 0 ) {
3665 * pret = ret ;
3766 return len ;
@@ -42,21 +71,20 @@ static size_t cifs_shash_step(void *iter_base, size_t progress, size_t len,
4271/*
4372 * Pass the data from an iterator into a hash.
4473 */
45- static int cifs_shash_iter (const struct iov_iter * iter , size_t maxsize ,
46- struct shash_desc * shash )
74+ static int cifs_sig_iter (const struct iov_iter * iter , size_t maxsize ,
75+ struct cifs_calc_sig_ctx * ctx )
4776{
4877 struct iov_iter tmp_iter = * iter ;
4978 int err = - EIO ;
5079
51- if (iterate_and_advance_kernel (& tmp_iter , maxsize , shash , & err ,
52- cifs_shash_step ) != maxsize )
80+ if (iterate_and_advance_kernel (& tmp_iter , maxsize , ctx , & err ,
81+ cifs_sig_step ) != maxsize )
5382 return err ;
5483 return 0 ;
5584}
5685
57- int __cifs_calc_signature (struct smb_rqst * rqst ,
58- struct TCP_Server_Info * server , char * signature ,
59- struct shash_desc * shash )
86+ int __cifs_calc_signature (struct smb_rqst * rqst , struct TCP_Server_Info * server ,
87+ char * signature , struct cifs_calc_sig_ctx * ctx )
6088{
6189 int i ;
6290 ssize_t rc ;
@@ -82,20 +110,19 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
82110 return - EIO ;
83111 }
84112
85- rc = crypto_shash_update (shash ,
86- iov [i ].iov_base , iov [i ].iov_len );
113+ rc = cifs_sig_update (ctx , iov [i ].iov_base , iov [i ].iov_len );
87114 if (rc ) {
88115 cifs_dbg (VFS , "%s: Could not update with payload\n" ,
89116 __func__ );
90117 return rc ;
91118 }
92119 }
93120
94- rc = cifs_shash_iter (& rqst -> rq_iter , iov_iter_count (& rqst -> rq_iter ), shash );
121+ rc = cifs_sig_iter (& rqst -> rq_iter , iov_iter_count (& rqst -> rq_iter ), ctx );
95122 if (rc < 0 )
96123 return rc ;
97124
98- rc = crypto_shash_final ( shash , signature );
125+ rc = cifs_sig_final ( ctx , signature );
99126 if (rc )
100127 cifs_dbg (VFS , "%s: Could not generate hash\n" , __func__ );
101128
@@ -112,29 +139,22 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
112139static int cifs_calc_signature (struct smb_rqst * rqst ,
113140 struct TCP_Server_Info * server , char * signature )
114141{
115- int rc ;
142+ struct md5_ctx ctx ;
116143
117144 if (!rqst -> rq_iov || !signature || !server )
118145 return - EINVAL ;
119-
120- rc = cifs_alloc_hash ("md5" , & server -> secmech .md5 );
121- if (rc )
122- return -1 ;
123-
124- rc = crypto_shash_init (server -> secmech .md5 );
125- if (rc ) {
126- cifs_dbg (VFS , "%s: Could not init md5\n" , __func__ );
127- return rc ;
146+ if (fips_enabled ) {
147+ cifs_dbg (VFS ,
148+ "MD5 signature support is disabled due to FIPS\n" );
149+ return - EOPNOTSUPP ;
128150 }
129151
130- rc = crypto_shash_update (server -> secmech .md5 ,
131- server -> session_key .response , server -> session_key .len );
132- if (rc ) {
133- cifs_dbg (VFS , "%s: Could not update with response\n" , __func__ );
134- return rc ;
135- }
152+ md5_init (& ctx );
153+ md5_update (& ctx , server -> session_key .response , server -> session_key .len );
136154
137- return __cifs_calc_signature (rqst , server , signature , server -> secmech .md5 );
155+ return __cifs_calc_signature (
156+ rqst , server , signature ,
157+ & (struct cifs_calc_sig_ctx ){ .md5 = & ctx });
138158}
139159
140160/* must be called with server->srv_mutex held */
@@ -405,29 +425,19 @@ static __le64 find_timestamp(struct cifs_ses *ses)
405425}
406426
407427static int calc_ntlmv2_hash (struct cifs_ses * ses , char * ntlmv2_hash ,
408- const struct nls_table * nls_cp , struct shash_desc * hmacmd5 )
428+ const struct nls_table * nls_cp )
409429{
410- int rc = 0 ;
411430 int len ;
412431 char nt_hash [CIFS_NTHASH_SIZE ];
432+ struct hmac_md5_ctx hmac_ctx ;
413433 __le16 * user ;
414434 wchar_t * domain ;
415435 wchar_t * server ;
416436
417437 /* calculate md4 hash of password */
418438 E_md4hash (ses -> password , nt_hash , nls_cp );
419439
420- rc = crypto_shash_setkey (hmacmd5 -> tfm , nt_hash , CIFS_NTHASH_SIZE );
421- if (rc ) {
422- cifs_dbg (VFS , "%s: Could not set NT hash as a key, rc=%d\n" , __func__ , rc );
423- return rc ;
424- }
425-
426- rc = crypto_shash_init (hmacmd5 );
427- if (rc ) {
428- cifs_dbg (VFS , "%s: Could not init HMAC-MD5, rc=%d\n" , __func__ , rc );
429- return rc ;
430- }
440+ hmac_md5_init_usingrawkey (& hmac_ctx , nt_hash , CIFS_NTHASH_SIZE );
431441
432442 /* convert ses->user_name to unicode */
433443 len = ses -> user_name ? strlen (ses -> user_name ) : 0 ;
@@ -442,12 +452,8 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
442452 * (u16 * )user = 0 ;
443453 }
444454
445- rc = crypto_shash_update ( hmacmd5 , (char * )user , 2 * len );
455+ hmac_md5_update ( & hmac_ctx , (const u8 * )user , 2 * len );
446456 kfree (user );
447- if (rc ) {
448- cifs_dbg (VFS , "%s: Could not update with user, rc=%d\n" , __func__ , rc );
449- return rc ;
450- }
451457
452458 /* convert ses->domainName to unicode and uppercase */
453459 if (ses -> domainName ) {
@@ -459,12 +465,8 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
459465
460466 len = cifs_strtoUTF16 ((__le16 * )domain , ses -> domainName , len ,
461467 nls_cp );
462- rc = crypto_shash_update ( hmacmd5 , (char * )domain , 2 * len );
468+ hmac_md5_update ( & hmac_ctx , (const u8 * )domain , 2 * len );
463469 kfree (domain );
464- if (rc ) {
465- cifs_dbg (VFS , "%s: Could not update with domain, rc=%d\n" , __func__ , rc );
466- return rc ;
467- }
468470 } else {
469471 /* We use ses->ip_addr if no domain name available */
470472 len = strlen (ses -> ip_addr );
@@ -474,25 +476,16 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
474476 return - ENOMEM ;
475477
476478 len = cifs_strtoUTF16 ((__le16 * )server , ses -> ip_addr , len , nls_cp );
477- rc = crypto_shash_update ( hmacmd5 , (char * )server , 2 * len );
479+ hmac_md5_update ( & hmac_ctx , (const u8 * )server , 2 * len );
478480 kfree (server );
479- if (rc ) {
480- cifs_dbg (VFS , "%s: Could not update with server, rc=%d\n" , __func__ , rc );
481- return rc ;
482- }
483481 }
484482
485- rc = crypto_shash_final (hmacmd5 , ntlmv2_hash );
486- if (rc )
487- cifs_dbg (VFS , "%s: Could not generate MD5 hash, rc=%d\n" , __func__ , rc );
488-
489- return rc ;
483+ hmac_md5_final (& hmac_ctx , ntlmv2_hash );
484+ return 0 ;
490485}
491486
492- static int
493- CalcNTLMv2_response (const struct cifs_ses * ses , char * ntlmv2_hash , struct shash_desc * hmacmd5 )
487+ static void CalcNTLMv2_response (const struct cifs_ses * ses , char * ntlmv2_hash )
494488{
495- int rc ;
496489 struct ntlmv2_resp * ntlmv2 = (struct ntlmv2_resp * )
497490 (ses -> auth_key .response + CIFS_SESS_KEY_SIZE );
498491 unsigned int hash_len ;
@@ -501,35 +494,15 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash, struct shash_
501494 hash_len = ses -> auth_key .len - (CIFS_SESS_KEY_SIZE +
502495 offsetof(struct ntlmv2_resp , challenge .key [0 ]));
503496
504- rc = crypto_shash_setkey (hmacmd5 -> tfm , ntlmv2_hash , CIFS_HMAC_MD5_HASH_SIZE );
505- if (rc ) {
506- cifs_dbg (VFS , "%s: Could not set NTLMv2 hash as a key, rc=%d\n" , __func__ , rc );
507- return rc ;
508- }
509-
510- rc = crypto_shash_init (hmacmd5 );
511- if (rc ) {
512- cifs_dbg (VFS , "%s: Could not init HMAC-MD5, rc=%d\n" , __func__ , rc );
513- return rc ;
514- }
515-
516497 if (ses -> server -> negflavor == CIFS_NEGFLAVOR_EXTENDED )
517498 memcpy (ntlmv2 -> challenge .key , ses -> ntlmssp -> cryptkey , CIFS_SERVER_CHALLENGE_SIZE );
518499 else
519500 memcpy (ntlmv2 -> challenge .key , ses -> server -> cryptkey , CIFS_SERVER_CHALLENGE_SIZE );
520501
521- rc = crypto_shash_update (hmacmd5 , ntlmv2 -> challenge .key , hash_len );
522- if (rc ) {
523- cifs_dbg (VFS , "%s: Could not update with response, rc=%d\n" , __func__ , rc );
524- return rc ;
525- }
526-
527- /* Note that the MD5 digest over writes anon.challenge_key.key */
528- rc = crypto_shash_final (hmacmd5 , ntlmv2 -> ntlmv2_hash );
529- if (rc )
530- cifs_dbg (VFS , "%s: Could not generate MD5 hash, rc=%d\n" , __func__ , rc );
531-
532- return rc ;
502+ /* Note that the HMAC-MD5 value overwrites ntlmv2->challenge.key */
503+ hmac_md5_usingrawkey (ntlmv2_hash , CIFS_HMAC_MD5_HASH_SIZE ,
504+ ntlmv2 -> challenge .key , hash_len ,
505+ ntlmv2 -> ntlmv2_hash );
533506}
534507
535508/*
@@ -586,7 +559,6 @@ static int set_auth_key_response(struct cifs_ses *ses)
586559int
587560setup_ntlmv2_rsp (struct cifs_ses * ses , const struct nls_table * nls_cp )
588561{
589- struct shash_desc * hmacmd5 = NULL ;
590562 unsigned char * tiblob = NULL ; /* target info blob */
591563 struct ntlmv2_resp * ntlmv2 ;
592564 char ntlmv2_hash [16 ];
@@ -657,51 +629,29 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
657629 ntlmv2 -> client_chal = cc ;
658630 ntlmv2 -> reserved2 = 0 ;
659631
660- rc = cifs_alloc_hash ( "hmac(md5)" , & hmacmd5 );
661- if ( rc ) {
662- cifs_dbg ( VFS , "Could not allocate HMAC-MD5, rc=%d\n" , rc ) ;
632+ if ( fips_enabled ) {
633+ cifs_dbg ( VFS , "NTLMv2 support is disabled due to FIPS\n" );
634+ rc = - EOPNOTSUPP ;
663635 goto unlock ;
664636 }
665637
666638 /* calculate ntlmv2_hash */
667- rc = calc_ntlmv2_hash (ses , ntlmv2_hash , nls_cp , hmacmd5 );
639+ rc = calc_ntlmv2_hash (ses , ntlmv2_hash , nls_cp );
668640 if (rc ) {
669641 cifs_dbg (VFS , "Could not get NTLMv2 hash, rc=%d\n" , rc );
670642 goto unlock ;
671643 }
672644
673645 /* calculate first part of the client response (CR1) */
674- rc = CalcNTLMv2_response (ses , ntlmv2_hash , hmacmd5 );
675- if (rc ) {
676- cifs_dbg (VFS , "Could not calculate CR1, rc=%d\n" , rc );
677- goto unlock ;
678- }
646+ CalcNTLMv2_response (ses , ntlmv2_hash );
679647
680648 /* now calculate the session key for NTLMv2 */
681- rc = crypto_shash_setkey (hmacmd5 -> tfm , ntlmv2_hash , CIFS_HMAC_MD5_HASH_SIZE );
682- if (rc ) {
683- cifs_dbg (VFS , "%s: Could not set NTLMv2 hash as a key, rc=%d\n" , __func__ , rc );
684- goto unlock ;
685- }
686-
687- rc = crypto_shash_init (hmacmd5 );
688- if (rc ) {
689- cifs_dbg (VFS , "%s: Could not init HMAC-MD5, rc=%d\n" , __func__ , rc );
690- goto unlock ;
691- }
692-
693- rc = crypto_shash_update (hmacmd5 , ntlmv2 -> ntlmv2_hash , CIFS_HMAC_MD5_HASH_SIZE );
694- if (rc ) {
695- cifs_dbg (VFS , "%s: Could not update with response, rc=%d\n" , __func__ , rc );
696- goto unlock ;
697- }
698-
699- rc = crypto_shash_final (hmacmd5 , ses -> auth_key .response );
700- if (rc )
701- cifs_dbg (VFS , "%s: Could not generate MD5 hash, rc=%d\n" , __func__ , rc );
649+ hmac_md5_usingrawkey (ntlmv2_hash , CIFS_HMAC_MD5_HASH_SIZE ,
650+ ntlmv2 -> ntlmv2_hash , CIFS_HMAC_MD5_HASH_SIZE ,
651+ ses -> auth_key .response );
652+ rc = 0 ;
702653unlock :
703654 cifs_server_unlock (ses -> server );
704- cifs_free_hash (& hmacmd5 );
705655setup_ntlmv2_rsp_ret :
706656 kfree_sensitive (tiblob );
707657
743693cifs_crypto_secmech_release (struct TCP_Server_Info * server )
744694{
745695 cifs_free_hash (& server -> secmech .aes_cmac );
746- cifs_free_hash (& server -> secmech .hmacsha256 );
747- cifs_free_hash (& server -> secmech .md5 );
748- cifs_free_hash (& server -> secmech .sha512 );
749696
750697 if (server -> secmech .enc ) {
751698 crypto_free_aead (server -> secmech .enc );
0 commit comments