.. | .. |
---|
33 | 33 | #include <linux/ctype.h> |
---|
34 | 34 | #include <linux/random.h> |
---|
35 | 35 | #include <linux/highmem.h> |
---|
36 | | -#include <crypto/skcipher.h> |
---|
| 36 | +#include <linux/fips.h> |
---|
| 37 | +#include <crypto/arc4.h> |
---|
37 | 38 | #include <crypto/aead.h> |
---|
38 | 39 | |
---|
39 | 40 | int __cifs_calc_signature(struct smb_rqst *rqst, |
---|
.. | .. |
---|
224 | 225 | if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { |
---|
225 | 226 | struct smb_com_lock_req *pSMB = |
---|
226 | 227 | (struct smb_com_lock_req *)cifs_pdu; |
---|
227 | | - if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE) |
---|
| 228 | + if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE) |
---|
228 | 229 | return 0; |
---|
229 | 230 | } |
---|
230 | 231 | |
---|
.. | .. |
---|
304 | 305 | int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, |
---|
305 | 306 | char *lnm_session_key) |
---|
306 | 307 | { |
---|
307 | | - int i; |
---|
| 308 | + int i, len; |
---|
308 | 309 | int rc; |
---|
309 | 310 | char password_with_pad[CIFS_ENCPWD_SIZE] = {0}; |
---|
310 | 311 | |
---|
311 | | - if (password) |
---|
312 | | - strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE); |
---|
| 312 | + if (password) { |
---|
| 313 | + for (len = 0; len < CIFS_ENCPWD_SIZE; len++) |
---|
| 314 | + if (!password[len]) |
---|
| 315 | + break; |
---|
| 316 | + |
---|
| 317 | + memcpy(password_with_pad, password, len); |
---|
| 318 | + } |
---|
313 | 319 | |
---|
314 | 320 | if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) { |
---|
315 | 321 | memcpy(lnm_session_key, password_with_pad, |
---|
.. | .. |
---|
514 | 520 | |
---|
515 | 521 | rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); |
---|
516 | 522 | if (rc) { |
---|
517 | | - cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__); |
---|
| 523 | + cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); |
---|
518 | 524 | return rc; |
---|
519 | 525 | } |
---|
520 | 526 | |
---|
.. | .. |
---|
618 | 624 | |
---|
619 | 625 | rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); |
---|
620 | 626 | if (rc) { |
---|
621 | | - cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__); |
---|
| 627 | + cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); |
---|
622 | 628 | return rc; |
---|
623 | 629 | } |
---|
624 | 630 | |
---|
.. | .. |
---|
717 | 723 | /* calculate ntlmv2_hash */ |
---|
718 | 724 | rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); |
---|
719 | 725 | if (rc) { |
---|
720 | | - cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc); |
---|
| 726 | + cifs_dbg(VFS, "Could not get v2 hash rc %d\n", rc); |
---|
721 | 727 | goto unlock; |
---|
722 | 728 | } |
---|
723 | 729 | |
---|
.. | .. |
---|
767 | 773 | int |
---|
768 | 774 | calc_seckey(struct cifs_ses *ses) |
---|
769 | 775 | { |
---|
770 | | - int rc; |
---|
771 | | - struct crypto_skcipher *tfm_arc4; |
---|
772 | | - struct scatterlist sgin, sgout; |
---|
773 | | - struct skcipher_request *req; |
---|
774 | | - unsigned char *sec_key; |
---|
| 776 | + unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */ |
---|
| 777 | + struct arc4_ctx *ctx_arc4; |
---|
775 | 778 | |
---|
776 | | - sec_key = kmalloc(CIFS_SESS_KEY_SIZE, GFP_KERNEL); |
---|
777 | | - if (sec_key == NULL) |
---|
778 | | - return -ENOMEM; |
---|
| 779 | + if (fips_enabled) |
---|
| 780 | + return -ENODEV; |
---|
779 | 781 | |
---|
780 | 782 | get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); |
---|
781 | 783 | |
---|
782 | | - tfm_arc4 = crypto_alloc_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); |
---|
783 | | - if (IS_ERR(tfm_arc4)) { |
---|
784 | | - rc = PTR_ERR(tfm_arc4); |
---|
785 | | - cifs_dbg(VFS, "could not allocate crypto API arc4\n"); |
---|
786 | | - goto out; |
---|
| 784 | + ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); |
---|
| 785 | + if (!ctx_arc4) { |
---|
| 786 | + cifs_dbg(VFS, "Could not allocate arc4 context\n"); |
---|
| 787 | + return -ENOMEM; |
---|
787 | 788 | } |
---|
788 | 789 | |
---|
789 | | - rc = crypto_skcipher_setkey(tfm_arc4, ses->auth_key.response, |
---|
790 | | - CIFS_SESS_KEY_SIZE); |
---|
791 | | - if (rc) { |
---|
792 | | - cifs_dbg(VFS, "%s: Could not set response as a key\n", |
---|
793 | | - __func__); |
---|
794 | | - goto out_free_cipher; |
---|
795 | | - } |
---|
796 | | - |
---|
797 | | - req = skcipher_request_alloc(tfm_arc4, GFP_KERNEL); |
---|
798 | | - if (!req) { |
---|
799 | | - rc = -ENOMEM; |
---|
800 | | - cifs_dbg(VFS, "could not allocate crypto API arc4 request\n"); |
---|
801 | | - goto out_free_cipher; |
---|
802 | | - } |
---|
803 | | - |
---|
804 | | - sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE); |
---|
805 | | - sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); |
---|
806 | | - |
---|
807 | | - skcipher_request_set_callback(req, 0, NULL, NULL); |
---|
808 | | - skcipher_request_set_crypt(req, &sgin, &sgout, CIFS_CPHTXT_SIZE, NULL); |
---|
809 | | - |
---|
810 | | - rc = crypto_skcipher_encrypt(req); |
---|
811 | | - skcipher_request_free(req); |
---|
812 | | - if (rc) { |
---|
813 | | - cifs_dbg(VFS, "could not encrypt session key rc: %d\n", rc); |
---|
814 | | - goto out_free_cipher; |
---|
815 | | - } |
---|
| 790 | + arc4_setkey(ctx_arc4, ses->auth_key.response, CIFS_SESS_KEY_SIZE); |
---|
| 791 | + arc4_crypt(ctx_arc4, ses->ntlmssp->ciphertext, sec_key, |
---|
| 792 | + CIFS_CPHTXT_SIZE); |
---|
816 | 793 | |
---|
817 | 794 | /* make secondary_key/nonce as session key */ |
---|
818 | 795 | memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE); |
---|
819 | 796 | /* and make len as that of session key only */ |
---|
820 | 797 | ses->auth_key.len = CIFS_SESS_KEY_SIZE; |
---|
821 | 798 | |
---|
822 | | -out_free_cipher: |
---|
823 | | - crypto_free_skcipher(tfm_arc4); |
---|
824 | | -out: |
---|
825 | | - kfree(sec_key); |
---|
826 | | - return rc; |
---|
| 799 | + memzero_explicit(sec_key, CIFS_SESS_KEY_SIZE); |
---|
| 800 | + kfree_sensitive(ctx_arc4); |
---|
| 801 | + return 0; |
---|
827 | 802 | } |
---|
828 | 803 | |
---|
829 | 804 | void |
---|