| .. | .. |
|---|
| 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 |
|---|