Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
cifs: More crypto cleanup (try #2)
CIFS: Add strictcache mount option
CIFS: Implement cifs_strict_writev (try #4)
[CIFS] Replace cifs md5 hashing functions with kernel crypto APIs

+371 -704
+1 -1
fs/cifs/Makefile
··· 5 6 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ 8 - md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 9 readdir.o ioctl.o sess.o export.o 10 11 cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
··· 5 6 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ 8 + cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 9 readdir.o ioctl.o sess.o export.o 10 11 cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
+5
fs/cifs/README
··· 452 if oplock (caching token) is granted and held. Note that 453 direct allows write operations larger than page size 454 to be sent to the server. 455 acl Allow setfacl and getfacl to manage posix ACLs if server 456 supports them. (default) 457 noacl Do not allow setfacl and getfacl calls on this mount
··· 452 if oplock (caching token) is granted and held. Note that 453 direct allows write operations larger than page size 454 to be sent to the server. 455 + strictcache Use for switching on strict cache mode. In this mode the 456 + client read from the cache all the time it has Oplock Level II, 457 + otherwise - read from the server. All written data are stored 458 + in the cache, but if the client doesn't have Exclusive Oplock, 459 + it writes the data to the server. 460 acl Allow setfacl and getfacl to manage posix ACLs if server 461 supports them. (default) 462 noacl Do not allow setfacl and getfacl calls on this mount
+20 -13
fs/cifs/cifsencrypt.c
··· 24 #include "cifspdu.h" 25 #include "cifsglob.h" 26 #include "cifs_debug.h" 27 - #include "md5.h" 28 #include "cifs_unicode.h" 29 #include "cifsproto.h" 30 #include "ntlmssp.h" ··· 35 /* Note we only use the 1st eight bytes */ 36 /* Note that the smb header signature field on input contains the 37 sequence number before this function is called */ 38 - 39 - extern void mdfour(unsigned char *out, unsigned char *in, int n); 40 - extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 41 - extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8, 42 - unsigned char *p24); 43 44 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45 struct TCP_Server_Info *server, char *signature) ··· 228 /* first calculate 24 bytes ntlm response and then 16 byte session key */ 229 int setup_ntlm_response(struct cifsSesInfo *ses) 230 { 231 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; 232 char temp_key[CIFS_SESS_KEY_SIZE]; 233 ··· 242 } 243 ses->auth_key.len = temp_len; 244 245 - SMBNTencrypt(ses->password, ses->server->cryptkey, 246 ses->auth_key.response + CIFS_SESS_KEY_SIZE); 247 248 - E_md4hash(ses->password, temp_key); 249 - mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE); 250 251 - return 0; 252 } 253 254 #ifdef CONFIG_CIFS_WEAK_PW_HASH ··· 708 unsigned int size; 709 710 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 711 - if (!server->secmech.hmacmd5 || 712 - IS_ERR(server->secmech.hmacmd5)) { 713 cERROR(1, "could not allocate crypto hmacmd5\n"); 714 return PTR_ERR(server->secmech.hmacmd5); 715 } 716 717 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); 718 - if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) { 719 cERROR(1, "could not allocate crypto md5\n"); 720 rc = PTR_ERR(server->secmech.md5); 721 goto crypto_allocate_md5_fail;
··· 24 #include "cifspdu.h" 25 #include "cifsglob.h" 26 #include "cifs_debug.h" 27 #include "cifs_unicode.h" 28 #include "cifsproto.h" 29 #include "ntlmssp.h" ··· 36 /* Note we only use the 1st eight bytes */ 37 /* Note that the smb header signature field on input contains the 38 sequence number before this function is called */ 39 40 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 41 struct TCP_Server_Info *server, char *signature) ··· 234 /* first calculate 24 bytes ntlm response and then 16 byte session key */ 235 int setup_ntlm_response(struct cifsSesInfo *ses) 236 { 237 + int rc = 0; 238 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; 239 char temp_key[CIFS_SESS_KEY_SIZE]; 240 ··· 247 } 248 ses->auth_key.len = temp_len; 249 250 + rc = SMBNTencrypt(ses->password, ses->server->cryptkey, 251 ses->auth_key.response + CIFS_SESS_KEY_SIZE); 252 + if (rc) { 253 + cFYI(1, "%s Can't generate NTLM response, error: %d", 254 + __func__, rc); 255 + return rc; 256 + } 257 258 + rc = E_md4hash(ses->password, temp_key); 259 + if (rc) { 260 + cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); 261 + return rc; 262 + } 263 264 + rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE); 265 + if (rc) 266 + cFYI(1, "%s Can't generate NTLM session key, error: %d", 267 + __func__, rc); 268 + 269 + return rc; 270 } 271 272 #ifdef CONFIG_CIFS_WEAK_PW_HASH ··· 700 unsigned int size; 701 702 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 703 + if (IS_ERR(server->secmech.hmacmd5)) { 704 cERROR(1, "could not allocate crypto hmacmd5\n"); 705 return PTR_ERR(server->secmech.hmacmd5); 706 } 707 708 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); 709 + if (IS_ERR(server->secmech.md5)) { 710 cERROR(1, "could not allocate crypto md5\n"); 711 rc = PTR_ERR(server->secmech.md5); 712 goto crypto_allocate_md5_fail;
-33
fs/cifs/cifsencrypt.h
··· 1 - /* 2 - * fs/cifs/cifsencrypt.h 3 - * 4 - * Copyright (c) International Business Machines Corp., 2005 5 - * Author(s): Steve French (sfrench@us.ibm.com) 6 - * 7 - * Externs for misc. small encryption routines 8 - * so we do not have to put them in cifsproto.h 9 - * 10 - * This library is free software; you can redistribute it and/or modify 11 - * it under the terms of the GNU Lesser General Public License as published 12 - * by the Free Software Foundation; either version 2.1 of the License, or 13 - * (at your option) any later version. 14 - * 15 - * This library is distributed in the hope that it will be useful, 16 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 18 - * the GNU Lesser General Public License for more details. 19 - * 20 - * You should have received a copy of the GNU Lesser General Public License 21 - * along with this library; if not, write to the Free Software 22 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 - */ 24 - 25 - /* md4.c */ 26 - extern void mdfour(unsigned char *out, unsigned char *in, int n); 27 - /* smbdes.c */ 28 - extern void E_P16(unsigned char *p14, unsigned char *p16); 29 - extern void E_P24(unsigned char *p21, const unsigned char *c8, 30 - unsigned char *p24); 31 - 32 - 33 -
···
+11 -4
fs/cifs/cifsfs.c
··· 600 { 601 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; 602 ssize_t written; 603 604 written = generic_file_aio_write(iocb, iov, nr_segs, pos); 605 - if (!CIFS_I(inode)->clientCanCacheAll) 606 - filemap_fdatawrite(inode->i_mapping); 607 return written; 608 } 609 ··· 744 .read = do_sync_read, 745 .write = do_sync_write, 746 .aio_read = cifs_strict_readv, 747 - .aio_write = cifs_file_aio_write, 748 .open = cifs_open, 749 .release = cifs_close, 750 .lock = cifs_lock, ··· 800 .read = do_sync_read, 801 .write = do_sync_write, 802 .aio_read = cifs_strict_readv, 803 - .aio_write = cifs_file_aio_write, 804 .open = cifs_open, 805 .release = cifs_close, 806 .fsync = cifs_strict_fsync,
··· 600 { 601 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; 602 ssize_t written; 603 + int rc; 604 605 written = generic_file_aio_write(iocb, iov, nr_segs, pos); 606 + 607 + if (CIFS_I(inode)->clientCanCacheAll) 608 + return written; 609 + 610 + rc = filemap_fdatawrite(inode->i_mapping); 611 + if (rc) 612 + cFYI(1, "cifs_file_aio_write: %d rc on %p inode", rc, inode); 613 + 614 return written; 615 } 616 ··· 737 .read = do_sync_read, 738 .write = do_sync_write, 739 .aio_read = cifs_strict_readv, 740 + .aio_write = cifs_strict_writev, 741 .open = cifs_open, 742 .release = cifs_close, 743 .lock = cifs_lock, ··· 793 .read = do_sync_read, 794 .write = do_sync_write, 795 .aio_read = cifs_strict_readv, 796 + .aio_write = cifs_strict_writev, 797 .open = cifs_open, 798 .release = cifs_close, 799 .fsync = cifs_strict_fsync,
+3 -1
fs/cifs/cifsfs.h
··· 85 extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov, 86 unsigned long nr_segs, loff_t pos); 87 extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, 88 - size_t write_size, loff_t *poffset); 89 extern int cifs_lock(struct file *, int, struct file_lock *); 90 extern int cifs_fsync(struct file *, int); 91 extern int cifs_strict_fsync(struct file *, int);
··· 85 extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov, 86 unsigned long nr_segs, loff_t pos); 87 extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, 88 + size_t write_size, loff_t *poffset); 89 + extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, 90 + unsigned long nr_segs, loff_t pos); 91 extern int cifs_lock(struct file *, int, struct file_lock *); 92 extern int cifs_fsync(struct file *, int); 93 extern int cifs_strict_fsync(struct file *, int);
+10 -1
fs/cifs/cifsproto.h
··· 85 extern bool is_valid_oplock_break(struct smb_hdr *smb, 86 struct TCP_Server_Info *); 87 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); 88 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); 89 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 90 extern unsigned int smbCalcSize(struct smb_hdr *ptr); ··· 375 extern int cifs_verify_signature(struct smb_hdr *, 376 struct TCP_Server_Info *server, 377 __u32 expected_sequence_number); 378 - extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); 379 extern int setup_ntlm_response(struct cifsSesInfo *); 380 extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); 381 extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); ··· 425 extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, 426 const unsigned char *path, 427 struct cifs_sb_info *cifs_sb, int xid); 428 #endif /* _CIFSPROTO_H */
··· 85 extern bool is_valid_oplock_break(struct smb_hdr *smb, 86 struct TCP_Server_Info *); 87 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); 88 + extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 89 + unsigned int bytes_written); 90 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); 91 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 92 extern unsigned int smbCalcSize(struct smb_hdr *ptr); ··· 373 extern int cifs_verify_signature(struct smb_hdr *, 374 struct TCP_Server_Info *server, 375 __u32 expected_sequence_number); 376 + extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); 377 extern int setup_ntlm_response(struct cifsSesInfo *); 378 extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); 379 extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); ··· 423 extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, 424 const unsigned char *path, 425 struct cifs_sb_info *cifs_sb, int xid); 426 + extern int mdfour(unsigned char *, unsigned char *, int); 427 + extern int E_md4hash(const unsigned char *passwd, unsigned char *p16); 428 + extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8, 429 + unsigned char *p24); 430 + extern void E_P16(unsigned char *p14, unsigned char *p16); 431 + extern void E_P24(unsigned char *p21, const unsigned char *c8, 432 + unsigned char *p24); 433 #endif /* _CIFSPROTO_H */
+7 -4
fs/cifs/connect.c
··· 55 /* SMB echo "timeout" -- FIXME: tunable? */ 56 #define SMB_ECHO_INTERVAL (60 * HZ) 57 58 - extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 59 - unsigned char *p24); 60 - 61 extern mempool_t *cifs_req_poolp; 62 63 struct smb_vol { ··· 84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ 85 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 86 bool direct_io:1; 87 bool remap:1; /* set to remap seven reserved chars in filenames */ 88 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 89 bool no_linux_ext:1; ··· 1342 vol->direct_io = 1; 1343 } else if (strnicmp(data, "forcedirectio", 13) == 0) { 1344 vol->direct_io = 1; 1345 } else if (strnicmp(data, "noac", 4) == 0) { 1346 printk(KERN_WARNING "CIFS: Mount option noac not " 1347 "supported. Instead set " ··· 2584 if (pvolume_info->multiuser) 2585 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | 2586 CIFS_MOUNT_NO_PERM); 2587 if (pvolume_info->direct_io) { 2588 cFYI(1, "mounting share using direct i/o"); 2589 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; ··· 2987 bcc_ptr); 2988 else 2989 #endif /* CIFS_WEAK_PW_HASH */ 2990 - SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr); 2991 2992 bcc_ptr += CIFS_AUTH_RESP_SIZE; 2993 if (ses->capabilities & CAP_UNICODE) {
··· 55 /* SMB echo "timeout" -- FIXME: tunable? */ 56 #define SMB_ECHO_INTERVAL (60 * HZ) 57 58 extern mempool_t *cifs_req_poolp; 59 60 struct smb_vol { ··· 87 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ 88 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 89 bool direct_io:1; 90 + bool strict_io:1; /* strict cache behavior */ 91 bool remap:1; /* set to remap seven reserved chars in filenames */ 92 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 93 bool no_linux_ext:1; ··· 1344 vol->direct_io = 1; 1345 } else if (strnicmp(data, "forcedirectio", 13) == 0) { 1346 vol->direct_io = 1; 1347 + } else if (strnicmp(data, "strictcache", 11) == 0) { 1348 + vol->strict_io = 1; 1349 } else if (strnicmp(data, "noac", 4) == 0) { 1350 printk(KERN_WARNING "CIFS: Mount option noac not " 1351 "supported. Instead set " ··· 2584 if (pvolume_info->multiuser) 2585 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | 2586 CIFS_MOUNT_NO_PERM); 2587 + if (pvolume_info->strict_io) 2588 + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO; 2589 if (pvolume_info->direct_io) { 2590 cFYI(1, "mounting share using direct i/o"); 2591 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; ··· 2985 bcc_ptr); 2986 else 2987 #endif /* CIFS_WEAK_PW_HASH */ 2988 + rc = SMBNTencrypt(tcon->password, ses->server->cryptkey, 2989 + bcc_ptr); 2990 2991 bcc_ptr += CIFS_AUTH_RESP_SIZE; 2992 if (ses->capabilities & CAP_UNICODE) {
+201 -1
fs/cifs/file.c
··· 848 } 849 850 /* update the file size (if needed) after a write */ 851 - static void 852 cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 853 unsigned int bytes_written) 854 { ··· 1617 cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc); 1618 1619 return rc; 1620 } 1621 1622 static ssize_t
··· 848 } 849 850 /* update the file size (if needed) after a write */ 851 + void 852 cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 853 unsigned int bytes_written) 854 { ··· 1617 cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc); 1618 1619 return rc; 1620 + } 1621 + 1622 + static int 1623 + cifs_write_allocate_pages(struct page **pages, unsigned long num_pages) 1624 + { 1625 + int rc = 0; 1626 + unsigned long i; 1627 + 1628 + for (i = 0; i < num_pages; i++) { 1629 + pages[i] = alloc_page(__GFP_HIGHMEM); 1630 + if (!pages[i]) { 1631 + /* 1632 + * save number of pages we have already allocated and 1633 + * return with ENOMEM error 1634 + */ 1635 + num_pages = i; 1636 + rc = -ENOMEM; 1637 + goto error; 1638 + } 1639 + } 1640 + 1641 + return rc; 1642 + 1643 + error: 1644 + for (i = 0; i < num_pages; i++) 1645 + put_page(pages[i]); 1646 + return rc; 1647 + } 1648 + 1649 + static inline 1650 + size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len) 1651 + { 1652 + size_t num_pages; 1653 + size_t clen; 1654 + 1655 + clen = min_t(const size_t, len, wsize); 1656 + num_pages = clen / PAGE_CACHE_SIZE; 1657 + if (clen % PAGE_CACHE_SIZE) 1658 + num_pages++; 1659 + 1660 + if (cur_len) 1661 + *cur_len = clen; 1662 + 1663 + return num_pages; 1664 + } 1665 + 1666 + static ssize_t 1667 + cifs_iovec_write(struct file *file, const struct iovec *iov, 1668 + unsigned long nr_segs, loff_t *poffset) 1669 + { 1670 + size_t total_written = 0, written = 0; 1671 + unsigned long num_pages, npages; 1672 + size_t copied, len, cur_len, i; 1673 + struct kvec *to_send; 1674 + struct page **pages; 1675 + struct iov_iter it; 1676 + struct inode *inode; 1677 + struct cifsFileInfo *open_file; 1678 + struct cifsTconInfo *pTcon; 1679 + struct cifs_sb_info *cifs_sb; 1680 + int xid, rc; 1681 + 1682 + len = iov_length(iov, nr_segs); 1683 + if (!len) 1684 + return 0; 1685 + 1686 + rc = generic_write_checks(file, poffset, &len, 0); 1687 + if (rc) 1688 + return rc; 1689 + 1690 + cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1691 + num_pages = get_numpages(cifs_sb->wsize, len, &cur_len); 1692 + 1693 + pages = kmalloc(sizeof(struct pages *)*num_pages, GFP_KERNEL); 1694 + if (!pages) 1695 + return -ENOMEM; 1696 + 1697 + to_send = kmalloc(sizeof(struct kvec)*(num_pages + 1), GFP_KERNEL); 1698 + if (!to_send) { 1699 + kfree(pages); 1700 + return -ENOMEM; 1701 + } 1702 + 1703 + rc = cifs_write_allocate_pages(pages, num_pages); 1704 + if (rc) { 1705 + kfree(pages); 1706 + kfree(to_send); 1707 + return rc; 1708 + } 1709 + 1710 + xid = GetXid(); 1711 + open_file = file->private_data; 1712 + pTcon = tlink_tcon(open_file->tlink); 1713 + inode = file->f_path.dentry->d_inode; 1714 + 1715 + iov_iter_init(&it, iov, nr_segs, len, 0); 1716 + npages = num_pages; 1717 + 1718 + do { 1719 + size_t save_len = cur_len; 1720 + for (i = 0; i < npages; i++) { 1721 + copied = min_t(const size_t, cur_len, PAGE_CACHE_SIZE); 1722 + copied = iov_iter_copy_from_user(pages[i], &it, 0, 1723 + copied); 1724 + cur_len -= copied; 1725 + iov_iter_advance(&it, copied); 1726 + to_send[i+1].iov_base = kmap(pages[i]); 1727 + to_send[i+1].iov_len = copied; 1728 + } 1729 + 1730 + cur_len = save_len - cur_len; 1731 + 1732 + do { 1733 + if (open_file->invalidHandle) { 1734 + rc = cifs_reopen_file(open_file, false); 1735 + if (rc != 0) 1736 + break; 1737 + } 1738 + rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, 1739 + cur_len, *poffset, &written, 1740 + to_send, npages, 0); 1741 + } while (rc == -EAGAIN); 1742 + 1743 + for (i = 0; i < npages; i++) 1744 + kunmap(pages[i]); 1745 + 1746 + if (written) { 1747 + len -= written; 1748 + total_written += written; 1749 + cifs_update_eof(CIFS_I(inode), *poffset, written); 1750 + *poffset += written; 1751 + } else if (rc < 0) { 1752 + if (!total_written) 1753 + total_written = rc; 1754 + break; 1755 + } 1756 + 1757 + /* get length and number of kvecs of the next write */ 1758 + npages = get_numpages(cifs_sb->wsize, len, &cur_len); 1759 + } while (len > 0); 1760 + 1761 + if (total_written > 0) { 1762 + spin_lock(&inode->i_lock); 1763 + if (*poffset > inode->i_size) 1764 + i_size_write(inode, *poffset); 1765 + spin_unlock(&inode->i_lock); 1766 + } 1767 + 1768 + cifs_stats_bytes_written(pTcon, total_written); 1769 + mark_inode_dirty_sync(inode); 1770 + 1771 + for (i = 0; i < num_pages; i++) 1772 + put_page(pages[i]); 1773 + kfree(to_send); 1774 + kfree(pages); 1775 + FreeXid(xid); 1776 + return total_written; 1777 + } 1778 + 1779 + static ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, 1780 + unsigned long nr_segs, loff_t pos) 1781 + { 1782 + ssize_t written; 1783 + struct inode *inode; 1784 + 1785 + inode = iocb->ki_filp->f_path.dentry->d_inode; 1786 + 1787 + /* 1788 + * BB - optimize the way when signing is disabled. We can drop this 1789 + * extra memory-to-memory copying and use iovec buffers for constructing 1790 + * write request. 1791 + */ 1792 + 1793 + written = cifs_iovec_write(iocb->ki_filp, iov, nr_segs, &pos); 1794 + if (written > 0) { 1795 + CIFS_I(inode)->invalid_mapping = true; 1796 + iocb->ki_pos = pos; 1797 + } 1798 + 1799 + return written; 1800 + } 1801 + 1802 + ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, 1803 + unsigned long nr_segs, loff_t pos) 1804 + { 1805 + struct inode *inode; 1806 + 1807 + inode = iocb->ki_filp->f_path.dentry->d_inode; 1808 + 1809 + if (CIFS_I(inode)->clientCanCacheAll) 1810 + return generic_file_aio_write(iocb, iov, nr_segs, pos); 1811 + 1812 + /* 1813 + * In strict cache mode we need to write the data to the server exactly 1814 + * from the pos to pos+len-1 rather than flush all affected pages 1815 + * because it may cause a error with mandatory locks on these pages but 1816 + * not on the region from pos to ppos+len-1. 1817 + */ 1818 + 1819 + return cifs_user_writev(iocb, iov, nr_segs, pos); 1820 } 1821 1822 static ssize_t
+49 -9
fs/cifs/link.c
··· 28 #include "cifsproto.h" 29 #include "cifs_debug.h" 30 #include "cifs_fs_sb.h" 31 - #include "md5.h" 32 33 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) 34 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) ··· 46 md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15] 47 48 static int 49 CIFSParseMFSymlink(const u8 *buf, 50 unsigned int buf_len, 51 unsigned int *_link_len, ··· 93 unsigned int link_len; 94 const char *md5_str1; 95 const char *link_str; 96 - struct MD5Context md5_ctx; 97 u8 md5_hash[16]; 98 char md5_str2[34]; 99 ··· 106 if (rc != 1) 107 return -EINVAL; 108 109 - cifs_MD5_init(&md5_ctx); 110 - cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len); 111 - cifs_MD5_final(md5_hash, &md5_ctx); 112 113 snprintf(md5_str2, sizeof(md5_str2), 114 CIFS_MF_SYMLINK_MD5_FORMAT, ··· 132 static int 133 CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) 134 { 135 unsigned int link_len; 136 unsigned int ofs; 137 - struct MD5Context md5_ctx; 138 u8 md5_hash[16]; 139 140 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) ··· 145 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 146 return -ENAMETOOLONG; 147 148 - cifs_MD5_init(&md5_ctx); 149 - cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len); 150 - cifs_MD5_final(md5_hash, &md5_ctx); 151 152 snprintf(buf, buf_len, 153 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
··· 28 #include "cifsproto.h" 29 #include "cifs_debug.h" 30 #include "cifs_fs_sb.h" 31 32 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) 33 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) ··· 47 md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15] 48 49 static int 50 + symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) 51 + { 52 + int rc; 53 + unsigned int size; 54 + struct crypto_shash *md5; 55 + struct sdesc *sdescmd5; 56 + 57 + md5 = crypto_alloc_shash("md5", 0, 0); 58 + if (IS_ERR(md5)) { 59 + cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); 60 + return PTR_ERR(md5); 61 + } 62 + size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); 63 + sdescmd5 = kmalloc(size, GFP_KERNEL); 64 + if (!sdescmd5) { 65 + rc = -ENOMEM; 66 + cERROR(1, "%s: Memory allocation failure\n", __func__); 67 + goto symlink_hash_err; 68 + } 69 + sdescmd5->shash.tfm = md5; 70 + sdescmd5->shash.flags = 0x0; 71 + 72 + rc = crypto_shash_init(&sdescmd5->shash); 73 + if (rc) { 74 + cERROR(1, "%s: Could not init md5 shash\n", __func__); 75 + goto symlink_hash_err; 76 + } 77 + crypto_shash_update(&sdescmd5->shash, link_str, link_len); 78 + rc = crypto_shash_final(&sdescmd5->shash, md5_hash); 79 + 80 + symlink_hash_err: 81 + crypto_free_shash(md5); 82 + kfree(sdescmd5); 83 + 84 + return rc; 85 + } 86 + 87 + static int 88 CIFSParseMFSymlink(const u8 *buf, 89 unsigned int buf_len, 90 unsigned int *_link_len, ··· 56 unsigned int link_len; 57 const char *md5_str1; 58 const char *link_str; 59 u8 md5_hash[16]; 60 char md5_str2[34]; 61 ··· 70 if (rc != 1) 71 return -EINVAL; 72 73 + rc = symlink_hash(link_len, link_str, md5_hash); 74 + if (rc) { 75 + cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc); 76 + return rc; 77 + } 78 79 snprintf(md5_str2, sizeof(md5_str2), 80 CIFS_MF_SYMLINK_MD5_FORMAT, ··· 94 static int 95 CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) 96 { 97 + int rc; 98 unsigned int link_len; 99 unsigned int ofs; 100 u8 md5_hash[16]; 101 102 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) ··· 107 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 108 return -ENAMETOOLONG; 109 110 + rc = symlink_hash(link_len, link_str, md5_hash); 111 + if (rc) { 112 + cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc); 113 + return rc; 114 + } 115 116 snprintf(buf, buf_len, 117 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
-205
fs/cifs/md4.c
··· 1 - /* 2 - Unix SMB/Netbios implementation. 3 - Version 1.9. 4 - a implementation of MD4 designed for use in the SMB authentication protocol 5 - Copyright (C) Andrew Tridgell 1997-1998. 6 - Modified by Steve French (sfrench@us.ibm.com) 2002-2003 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2 of the License, or 11 - (at your option) any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; if not, write to the Free Software 20 - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 - */ 22 - #include <linux/module.h> 23 - #include <linux/fs.h> 24 - #include "cifsencrypt.h" 25 - 26 - /* NOTE: This code makes no attempt to be fast! */ 27 - 28 - static __u32 29 - F(__u32 X, __u32 Y, __u32 Z) 30 - { 31 - return (X & Y) | ((~X) & Z); 32 - } 33 - 34 - static __u32 35 - G(__u32 X, __u32 Y, __u32 Z) 36 - { 37 - return (X & Y) | (X & Z) | (Y & Z); 38 - } 39 - 40 - static __u32 41 - H(__u32 X, __u32 Y, __u32 Z) 42 - { 43 - return X ^ Y ^ Z; 44 - } 45 - 46 - static __u32 47 - lshift(__u32 x, int s) 48 - { 49 - x &= 0xFFFFFFFF; 50 - return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); 51 - } 52 - 53 - #define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s) 54 - #define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s) 55 - #define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s) 56 - 57 - /* this applies md4 to 64 byte chunks */ 58 - static void 59 - mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D) 60 - { 61 - int j; 62 - __u32 AA, BB, CC, DD; 63 - __u32 X[16]; 64 - 65 - 66 - for (j = 0; j < 16; j++) 67 - X[j] = M[j]; 68 - 69 - AA = *A; 70 - BB = *B; 71 - CC = *C; 72 - DD = *D; 73 - 74 - ROUND1(A, B, C, D, 0, 3); 75 - ROUND1(D, A, B, C, 1, 7); 76 - ROUND1(C, D, A, B, 2, 11); 77 - ROUND1(B, C, D, A, 3, 19); 78 - ROUND1(A, B, C, D, 4, 3); 79 - ROUND1(D, A, B, C, 5, 7); 80 - ROUND1(C, D, A, B, 6, 11); 81 - ROUND1(B, C, D, A, 7, 19); 82 - ROUND1(A, B, C, D, 8, 3); 83 - ROUND1(D, A, B, C, 9, 7); 84 - ROUND1(C, D, A, B, 10, 11); 85 - ROUND1(B, C, D, A, 11, 19); 86 - ROUND1(A, B, C, D, 12, 3); 87 - ROUND1(D, A, B, C, 13, 7); 88 - ROUND1(C, D, A, B, 14, 11); 89 - ROUND1(B, C, D, A, 15, 19); 90 - 91 - ROUND2(A, B, C, D, 0, 3); 92 - ROUND2(D, A, B, C, 4, 5); 93 - ROUND2(C, D, A, B, 8, 9); 94 - ROUND2(B, C, D, A, 12, 13); 95 - ROUND2(A, B, C, D, 1, 3); 96 - ROUND2(D, A, B, C, 5, 5); 97 - ROUND2(C, D, A, B, 9, 9); 98 - ROUND2(B, C, D, A, 13, 13); 99 - ROUND2(A, B, C, D, 2, 3); 100 - ROUND2(D, A, B, C, 6, 5); 101 - ROUND2(C, D, A, B, 10, 9); 102 - ROUND2(B, C, D, A, 14, 13); 103 - ROUND2(A, B, C, D, 3, 3); 104 - ROUND2(D, A, B, C, 7, 5); 105 - ROUND2(C, D, A, B, 11, 9); 106 - ROUND2(B, C, D, A, 15, 13); 107 - 108 - ROUND3(A, B, C, D, 0, 3); 109 - ROUND3(D, A, B, C, 8, 9); 110 - ROUND3(C, D, A, B, 4, 11); 111 - ROUND3(B, C, D, A, 12, 15); 112 - ROUND3(A, B, C, D, 2, 3); 113 - ROUND3(D, A, B, C, 10, 9); 114 - ROUND3(C, D, A, B, 6, 11); 115 - ROUND3(B, C, D, A, 14, 15); 116 - ROUND3(A, B, C, D, 1, 3); 117 - ROUND3(D, A, B, C, 9, 9); 118 - ROUND3(C, D, A, B, 5, 11); 119 - ROUND3(B, C, D, A, 13, 15); 120 - ROUND3(A, B, C, D, 3, 3); 121 - ROUND3(D, A, B, C, 11, 9); 122 - ROUND3(C, D, A, B, 7, 11); 123 - ROUND3(B, C, D, A, 15, 15); 124 - 125 - *A += AA; 126 - *B += BB; 127 - *C += CC; 128 - *D += DD; 129 - 130 - *A &= 0xFFFFFFFF; 131 - *B &= 0xFFFFFFFF; 132 - *C &= 0xFFFFFFFF; 133 - *D &= 0xFFFFFFFF; 134 - 135 - for (j = 0; j < 16; j++) 136 - X[j] = 0; 137 - } 138 - 139 - static void 140 - copy64(__u32 *M, unsigned char *in) 141 - { 142 - int i; 143 - 144 - for (i = 0; i < 16; i++) 145 - M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | 146 - (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0); 147 - } 148 - 149 - static void 150 - copy4(unsigned char *out, __u32 x) 151 - { 152 - out[0] = x & 0xFF; 153 - out[1] = (x >> 8) & 0xFF; 154 - out[2] = (x >> 16) & 0xFF; 155 - out[3] = (x >> 24) & 0xFF; 156 - } 157 - 158 - /* produce a md4 message digest from data of length n bytes */ 159 - void 160 - mdfour(unsigned char *out, unsigned char *in, int n) 161 - { 162 - unsigned char buf[128]; 163 - __u32 M[16]; 164 - __u32 b = n * 8; 165 - int i; 166 - __u32 A = 0x67452301; 167 - __u32 B = 0xefcdab89; 168 - __u32 C = 0x98badcfe; 169 - __u32 D = 0x10325476; 170 - 171 - while (n > 64) { 172 - copy64(M, in); 173 - mdfour64(M, &A, &B, &C, &D); 174 - in += 64; 175 - n -= 64; 176 - } 177 - 178 - for (i = 0; i < 128; i++) 179 - buf[i] = 0; 180 - memcpy(buf, in, n); 181 - buf[n] = 0x80; 182 - 183 - if (n <= 55) { 184 - copy4(buf + 56, b); 185 - copy64(M, buf); 186 - mdfour64(M, &A, &B, &C, &D); 187 - } else { 188 - copy4(buf + 120, b); 189 - copy64(M, buf); 190 - mdfour64(M, &A, &B, &C, &D); 191 - copy64(M, buf + 64); 192 - mdfour64(M, &A, &B, &C, &D); 193 - } 194 - 195 - for (i = 0; i < 128; i++) 196 - buf[i] = 0; 197 - copy64(M, buf); 198 - 199 - copy4(out, A); 200 - copy4(out + 4, B); 201 - copy4(out + 8, C); 202 - copy4(out + 12, D); 203 - 204 - A = B = C = D = 0; 205 - }
···
-366
fs/cifs/md5.c
··· 1 - /* 2 - * This code implements the MD5 message-digest algorithm. 3 - * The algorithm is due to Ron Rivest. This code was 4 - * written by Colin Plumb in 1993, no copyright is claimed. 5 - * This code is in the public domain; do with it what you wish. 6 - * 7 - * Equivalent code is available from RSA Data Security, Inc. 8 - * This code has been tested against that, and is equivalent, 9 - * except that you don't need to include two pages of legalese 10 - * with every copy. 11 - * 12 - * To compute the message digest of a chunk of bytes, declare an 13 - * MD5Context structure, pass it to cifs_MD5_init, call cifs_MD5_update as 14 - * needed on buffers full of bytes, and then call cifs_MD5_final, which 15 - * will fill a supplied 16-byte array with the digest. 16 - */ 17 - 18 - /* This code slightly modified to fit into Samba by 19 - abartlet@samba.org Jun 2001 20 - and to fit the cifs vfs by 21 - Steve French sfrench@us.ibm.com */ 22 - 23 - #include <linux/string.h> 24 - #include "md5.h" 25 - 26 - static void MD5Transform(__u32 buf[4], __u32 const in[16]); 27 - 28 - /* 29 - * Note: this code is harmless on little-endian machines. 30 - */ 31 - static void 32 - byteReverse(unsigned char *buf, unsigned longs) 33 - { 34 - __u32 t; 35 - do { 36 - t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 37 - ((unsigned) buf[1] << 8 | buf[0]); 38 - *(__u32 *) buf = t; 39 - buf += 4; 40 - } while (--longs); 41 - } 42 - 43 - /* 44 - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 45 - * initialization constants. 46 - */ 47 - void 48 - cifs_MD5_init(struct MD5Context *ctx) 49 - { 50 - ctx->buf[0] = 0x67452301; 51 - ctx->buf[1] = 0xefcdab89; 52 - ctx->buf[2] = 0x98badcfe; 53 - ctx->buf[3] = 0x10325476; 54 - 55 - ctx->bits[0] = 0; 56 - ctx->bits[1] = 0; 57 - } 58 - 59 - /* 60 - * Update context to reflect the concatenation of another buffer full 61 - * of bytes. 62 - */ 63 - void 64 - cifs_MD5_update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) 65 - { 66 - register __u32 t; 67 - 68 - /* Update bitcount */ 69 - 70 - t = ctx->bits[0]; 71 - if ((ctx->bits[0] = t + ((__u32) len << 3)) < t) 72 - ctx->bits[1]++; /* Carry from low to high */ 73 - ctx->bits[1] += len >> 29; 74 - 75 - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 76 - 77 - /* Handle any leading odd-sized chunks */ 78 - 79 - if (t) { 80 - unsigned char *p = (unsigned char *) ctx->in + t; 81 - 82 - t = 64 - t; 83 - if (len < t) { 84 - memmove(p, buf, len); 85 - return; 86 - } 87 - memmove(p, buf, t); 88 - byteReverse(ctx->in, 16); 89 - MD5Transform(ctx->buf, (__u32 *) ctx->in); 90 - buf += t; 91 - len -= t; 92 - } 93 - /* Process data in 64-byte chunks */ 94 - 95 - while (len >= 64) { 96 - memmove(ctx->in, buf, 64); 97 - byteReverse(ctx->in, 16); 98 - MD5Transform(ctx->buf, (__u32 *) ctx->in); 99 - buf += 64; 100 - len -= 64; 101 - } 102 - 103 - /* Handle any remaining bytes of data. */ 104 - 105 - memmove(ctx->in, buf, len); 106 - } 107 - 108 - /* 109 - * Final wrapup - pad to 64-byte boundary with the bit pattern 110 - * 1 0* (64-bit count of bits processed, MSB-first) 111 - */ 112 - void 113 - cifs_MD5_final(unsigned char digest[16], struct MD5Context *ctx) 114 - { 115 - unsigned int count; 116 - unsigned char *p; 117 - 118 - /* Compute number of bytes mod 64 */ 119 - count = (ctx->bits[0] >> 3) & 0x3F; 120 - 121 - /* Set the first char of padding to 0x80. This is safe since there is 122 - always at least one byte free */ 123 - p = ctx->in + count; 124 - *p++ = 0x80; 125 - 126 - /* Bytes of padding needed to make 64 bytes */ 127 - count = 64 - 1 - count; 128 - 129 - /* Pad out to 56 mod 64 */ 130 - if (count < 8) { 131 - /* Two lots of padding: Pad the first block to 64 bytes */ 132 - memset(p, 0, count); 133 - byteReverse(ctx->in, 16); 134 - MD5Transform(ctx->buf, (__u32 *) ctx->in); 135 - 136 - /* Now fill the next block with 56 bytes */ 137 - memset(ctx->in, 0, 56); 138 - } else { 139 - /* Pad block to 56 bytes */ 140 - memset(p, 0, count - 8); 141 - } 142 - byteReverse(ctx->in, 14); 143 - 144 - /* Append length in bits and transform */ 145 - ((__u32 *) ctx->in)[14] = ctx->bits[0]; 146 - ((__u32 *) ctx->in)[15] = ctx->bits[1]; 147 - 148 - MD5Transform(ctx->buf, (__u32 *) ctx->in); 149 - byteReverse((unsigned char *) ctx->buf, 4); 150 - memmove(digest, ctx->buf, 16); 151 - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ 152 - } 153 - 154 - /* The four core functions - F1 is optimized somewhat */ 155 - 156 - /* #define F1(x, y, z) (x & y | ~x & z) */ 157 - #define F1(x, y, z) (z ^ (x & (y ^ z))) 158 - #define F2(x, y, z) F1(z, x, y) 159 - #define F3(x, y, z) (x ^ y ^ z) 160 - #define F4(x, y, z) (y ^ (x | ~z)) 161 - 162 - /* This is the central step in the MD5 algorithm. */ 163 - #define MD5STEP(f, w, x, y, z, data, s) \ 164 - (w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x) 165 - 166 - /* 167 - * The core of the MD5 algorithm, this alters an existing MD5 hash to 168 - * reflect the addition of 16 longwords of new data. cifs_MD5_update blocks 169 - * the data and converts bytes into longwords for this routine. 170 - */ 171 - static void 172 - MD5Transform(__u32 buf[4], __u32 const in[16]) 173 - { 174 - register __u32 a, b, c, d; 175 - 176 - a = buf[0]; 177 - b = buf[1]; 178 - c = buf[2]; 179 - d = buf[3]; 180 - 181 - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 182 - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 183 - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 184 - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 185 - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 186 - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 187 - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 188 - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 189 - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 190 - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 191 - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 192 - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 193 - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 194 - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 195 - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 196 - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 197 - 198 - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 199 - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 200 - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 201 - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 202 - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 203 - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 204 - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 205 - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 206 - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 207 - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 208 - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 209 - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 210 - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 211 - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 212 - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 213 - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 214 - 215 - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 216 - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 217 - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 218 - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 219 - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 220 - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 221 - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 222 - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 223 - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 224 - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 225 - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 226 - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 227 - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 228 - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 229 - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 230 - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 231 - 232 - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 233 - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 234 - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 235 - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 236 - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 237 - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 238 - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 239 - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 240 - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 241 - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 242 - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 243 - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 244 - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 245 - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 246 - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 247 - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 248 - 249 - buf[0] += a; 250 - buf[1] += b; 251 - buf[2] += c; 252 - buf[3] += d; 253 - } 254 - 255 - #if 0 /* currently unused */ 256 - /*********************************************************************** 257 - the rfc 2104 version of hmac_md5 initialisation. 258 - ***********************************************************************/ 259 - static void 260 - hmac_md5_init_rfc2104(unsigned char *key, int key_len, 261 - struct HMACMD5Context *ctx) 262 - { 263 - int i; 264 - 265 - /* if key is longer than 64 bytes reset it to key=MD5(key) */ 266 - if (key_len > 64) { 267 - unsigned char tk[16]; 268 - struct MD5Context tctx; 269 - 270 - cifs_MD5_init(&tctx); 271 - cifs_MD5_update(&tctx, key, key_len); 272 - cifs_MD5_final(tk, &tctx); 273 - 274 - key = tk; 275 - key_len = 16; 276 - } 277 - 278 - /* start out by storing key in pads */ 279 - memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); 280 - memset(ctx->k_opad, 0, sizeof(ctx->k_opad)); 281 - memcpy(ctx->k_ipad, key, key_len); 282 - memcpy(ctx->k_opad, key, key_len); 283 - 284 - /* XOR key with ipad and opad values */ 285 - for (i = 0; i < 64; i++) { 286 - ctx->k_ipad[i] ^= 0x36; 287 - ctx->k_opad[i] ^= 0x5c; 288 - } 289 - 290 - cifs_MD5_init(&ctx->ctx); 291 - cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64); 292 - } 293 - #endif 294 - 295 - /*********************************************************************** 296 - the microsoft version of hmac_md5 initialisation. 297 - ***********************************************************************/ 298 - void 299 - hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, 300 - struct HMACMD5Context *ctx) 301 - { 302 - int i; 303 - 304 - /* if key is longer than 64 bytes truncate it */ 305 - if (key_len > 64) 306 - key_len = 64; 307 - 308 - /* start out by storing key in pads */ 309 - memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); 310 - memset(ctx->k_opad, 0, sizeof(ctx->k_opad)); 311 - memcpy(ctx->k_ipad, key, key_len); 312 - memcpy(ctx->k_opad, key, key_len); 313 - 314 - /* XOR key with ipad and opad values */ 315 - for (i = 0; i < 64; i++) { 316 - ctx->k_ipad[i] ^= 0x36; 317 - ctx->k_opad[i] ^= 0x5c; 318 - } 319 - 320 - cifs_MD5_init(&ctx->ctx); 321 - cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64); 322 - } 323 - 324 - /*********************************************************************** 325 - update hmac_md5 "inner" buffer 326 - ***********************************************************************/ 327 - void 328 - hmac_md5_update(const unsigned char *text, int text_len, 329 - struct HMACMD5Context *ctx) 330 - { 331 - cifs_MD5_update(&ctx->ctx, text, text_len); /* then text of datagram */ 332 - } 333 - 334 - /*********************************************************************** 335 - finish off hmac_md5 "inner" buffer and generate outer one. 336 - ***********************************************************************/ 337 - void 338 - hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx) 339 - { 340 - struct MD5Context ctx_o; 341 - 342 - cifs_MD5_final(digest, &ctx->ctx); 343 - 344 - cifs_MD5_init(&ctx_o); 345 - cifs_MD5_update(&ctx_o, ctx->k_opad, 64); 346 - cifs_MD5_update(&ctx_o, digest, 16); 347 - cifs_MD5_final(digest, &ctx_o); 348 - } 349 - 350 - /*********************************************************** 351 - single function to calculate an HMAC MD5 digest from data. 352 - use the microsoft hmacmd5 init method because the key is 16 bytes. 353 - ************************************************************/ 354 - #if 0 /* currently unused */ 355 - static void 356 - hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 357 - unsigned char *digest) 358 - { 359 - struct HMACMD5Context ctx; 360 - hmac_md5_init_limK_to_64(key, 16, &ctx); 361 - if (data_len != 0) 362 - hmac_md5_update(data, data_len, &ctx); 363 - 364 - hmac_md5_final(digest, &ctx); 365 - } 366 - #endif
···
-38
fs/cifs/md5.h
··· 1 - #ifndef MD5_H 2 - #define MD5_H 3 - #ifndef HEADER_MD5_H 4 - /* Try to avoid clashes with OpenSSL */ 5 - #define HEADER_MD5_H 6 - #endif 7 - 8 - struct MD5Context { 9 - __u32 buf[4]; 10 - __u32 bits[2]; 11 - unsigned char in[64]; 12 - }; 13 - #endif /* !MD5_H */ 14 - 15 - #ifndef _HMAC_MD5_H 16 - struct HMACMD5Context { 17 - struct MD5Context ctx; 18 - unsigned char k_ipad[65]; 19 - unsigned char k_opad[65]; 20 - }; 21 - #endif /* _HMAC_MD5_H */ 22 - 23 - void cifs_MD5_init(struct MD5Context *context); 24 - void cifs_MD5_update(struct MD5Context *context, unsigned char const *buf, 25 - unsigned len); 26 - void cifs_MD5_final(unsigned char digest[16], struct MD5Context *context); 27 - 28 - /* The following definitions come from lib/hmacmd5.c */ 29 - 30 - /* void hmac_md5_init_rfc2104(unsigned char *key, int key_len, 31 - struct HMACMD5Context *ctx);*/ 32 - void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, 33 - struct HMACMD5Context *ctx); 34 - void hmac_md5_update(const unsigned char *text, int text_len, 35 - struct HMACMD5Context *ctx); 36 - void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); 37 - /* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 38 - unsigned char *digest);*/
···
-1
fs/cifs/smbdes.c
··· 45 up with a different answer to the one above) 46 */ 47 #include <linux/slab.h> 48 - #include "cifsencrypt.h" 49 #define uchar unsigned char 50 51 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
··· 45 up with a different answer to the one above) 46 */ 47 #include <linux/slab.h> 48 #define uchar unsigned char 49 50 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
+64 -27
fs/cifs/smbencrypt.c
··· 32 #include "cifs_unicode.h" 33 #include "cifspdu.h" 34 #include "cifsglob.h" 35 - #include "md5.h" 36 #include "cifs_debug.h" 37 - #include "cifsencrypt.h" 38 39 #ifndef false 40 #define false 0 ··· 47 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) 48 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) 49 50 - /*The following definitions come from libsmb/smbencrypt.c */ 51 52 - void SMBencrypt(unsigned char *passwd, const unsigned char *c8, 53 - unsigned char *p24); 54 - void E_md4hash(const unsigned char *passwd, unsigned char *p16); 55 - static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, 56 - unsigned char p24[24]); 57 - void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 58 59 /* 60 This implements the X/Open SMB password encryption ··· 160 * Creates the MD4 Hash of the users password in NT UNICODE. 161 */ 162 163 - void 164 E_md4hash(const unsigned char *passwd, unsigned char *p16) 165 { 166 int len; 167 __u16 wpwd[129]; 168 ··· 182 /* Calculate length in bytes */ 183 len = _my_wcslen(wpwd) * sizeof(__u16); 184 185 - mdfour(p16, (unsigned char *) wpwd, len); 186 memset(wpwd, 0, 129 * 2); 187 } 188 189 #if 0 /* currently unused */ ··· 257 } 258 #endif 259 260 - /* Does the des encryption from the NT or LM MD4 hash. */ 261 - static void 262 - SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, 263 - unsigned char p24[24]) 264 - { 265 - unsigned char p21[21]; 266 - 267 - memset(p21, '\0', 21); 268 - 269 - memcpy(p21, passwd, 16); 270 - E_P24(p21, c8, p24); 271 - } 272 - 273 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 274 #if 0 /* currently unused */ 275 static void ··· 274 #endif 275 276 /* Does the NT MD4 hash then des encryption. */ 277 - 278 - void 279 SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) 280 { 281 unsigned char p21[21]; 282 283 memset(p21, '\0', 21); 284 285 - E_md4hash(passwd, p21); 286 SMBOWFencrypt(p21, c8, p24); 287 } 288 289
··· 32 #include "cifs_unicode.h" 33 #include "cifspdu.h" 34 #include "cifsglob.h" 35 #include "cifs_debug.h" 36 + #include "cifsproto.h" 37 38 #ifndef false 39 #define false 0 ··· 48 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) 49 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) 50 51 + /* produce a md4 message digest from data of length n bytes */ 52 + int 53 + mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) 54 + { 55 + int rc; 56 + unsigned int size; 57 + struct crypto_shash *md4; 58 + struct sdesc *sdescmd4; 59 60 + md4 = crypto_alloc_shash("md4", 0, 0); 61 + if (IS_ERR(md4)) { 62 + cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); 63 + return PTR_ERR(md4); 64 + } 65 + size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); 66 + sdescmd4 = kmalloc(size, GFP_KERNEL); 67 + if (!sdescmd4) { 68 + rc = -ENOMEM; 69 + cERROR(1, "%s: Memory allocation failure\n", __func__); 70 + goto mdfour_err; 71 + } 72 + sdescmd4->shash.tfm = md4; 73 + sdescmd4->shash.flags = 0x0; 74 + 75 + rc = crypto_shash_init(&sdescmd4->shash); 76 + if (rc) { 77 + cERROR(1, "%s: Could not init md4 shash\n", __func__); 78 + goto mdfour_err; 79 + } 80 + crypto_shash_update(&sdescmd4->shash, link_str, link_len); 81 + rc = crypto_shash_final(&sdescmd4->shash, md4_hash); 82 + 83 + mdfour_err: 84 + crypto_free_shash(md4); 85 + kfree(sdescmd4); 86 + 87 + return rc; 88 + } 89 + 90 + /* Does the des encryption from the NT or LM MD4 hash. */ 91 + static void 92 + SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, 93 + unsigned char p24[24]) 94 + { 95 + unsigned char p21[21]; 96 + 97 + memset(p21, '\0', 21); 98 + 99 + memcpy(p21, passwd, 16); 100 + E_P24(p21, c8, p24); 101 + } 102 103 /* 104 This implements the X/Open SMB password encryption ··· 118 * Creates the MD4 Hash of the users password in NT UNICODE. 119 */ 120 121 + int 122 E_md4hash(const unsigned char *passwd, unsigned char *p16) 123 { 124 + int rc; 125 int len; 126 __u16 wpwd[129]; 127 ··· 139 /* Calculate length in bytes */ 140 len = _my_wcslen(wpwd) * sizeof(__u16); 141 142 + rc = mdfour(p16, (unsigned char *) wpwd, len); 143 memset(wpwd, 0, 129 * 2); 144 + 145 + return rc; 146 } 147 148 #if 0 /* currently unused */ ··· 212 } 213 #endif 214 215 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 216 #if 0 /* currently unused */ 217 static void ··· 242 #endif 243 244 /* Does the NT MD4 hash then des encryption. */ 245 + int 246 SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) 247 { 248 + int rc; 249 unsigned char p21[21]; 250 251 memset(p21, '\0', 21); 252 253 + rc = E_md4hash(passwd, p21); 254 + if (rc) { 255 + cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); 256 + return rc; 257 + } 258 SMBOWFencrypt(p21, c8, p24); 259 + return rc; 260 } 261 262