| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /** |
|---|
| 2 | 3 | * eCryptfs: Linux filesystem encryption layer |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Copyright (C) 2004-2007 International Business Machines Corp. |
|---|
| 7 | 8 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
|---|
| 8 | 9 | * Michael C. Thompson <mcthomps@us.ibm.com> |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or |
|---|
| 11 | | - * modify it under the terms of the GNU General Public License as |
|---|
| 12 | | - * published by the Free Software Foundation; either version 2 of the |
|---|
| 13 | | - * License, or (at your option) any later version. |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 16 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 18 | | - * General Public License for more details. |
|---|
| 19 | | - * |
|---|
| 20 | | - * You should have received a copy of the GNU General Public License |
|---|
| 21 | | - * along with this program; if not, write to the Free Software |
|---|
| 22 | | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
|---|
| 23 | | - * 02111-1307, USA. |
|---|
| 24 | 10 | */ |
|---|
| 25 | 11 | |
|---|
| 26 | 12 | #include <crypto/hash.h> |
|---|
| .. | .. |
|---|
| 37 | 23 | #include <linux/slab.h> |
|---|
| 38 | 24 | #include <asm/unaligned.h> |
|---|
| 39 | 25 | #include <linux/kernel.h> |
|---|
| 26 | +#include <linux/xattr.h> |
|---|
| 40 | 27 | #include "ecryptfs_kernel.h" |
|---|
| 41 | 28 | |
|---|
| 42 | 29 | #define DECRYPT 0 |
|---|
| .. | .. |
|---|
| 61 | 48 | } |
|---|
| 62 | 49 | } |
|---|
| 63 | 50 | |
|---|
| 64 | | -static int ecryptfs_hash_digest(struct crypto_shash *tfm, |
|---|
| 65 | | - char *src, int len, char *dst) |
|---|
| 66 | | -{ |
|---|
| 67 | | - SHASH_DESC_ON_STACK(desc, tfm); |
|---|
| 68 | | - int err; |
|---|
| 69 | | - |
|---|
| 70 | | - desc->tfm = tfm; |
|---|
| 71 | | - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
|---|
| 72 | | - err = crypto_shash_digest(desc, src, len, dst); |
|---|
| 73 | | - shash_desc_zero(desc); |
|---|
| 74 | | - return err; |
|---|
| 75 | | -} |
|---|
| 76 | | - |
|---|
| 77 | 51 | /** |
|---|
| 78 | 52 | * ecryptfs_calculate_md5 - calculates the md5 of @src |
|---|
| 79 | 53 | * @dst: Pointer to 16 bytes of allocated memory |
|---|
| .. | .. |
|---|
| 88 | 62 | struct ecryptfs_crypt_stat *crypt_stat, |
|---|
| 89 | 63 | char *src, int len) |
|---|
| 90 | 64 | { |
|---|
| 91 | | - struct crypto_shash *tfm; |
|---|
| 92 | | - int rc = 0; |
|---|
| 65 | + int rc = crypto_shash_tfm_digest(crypt_stat->hash_tfm, src, len, dst); |
|---|
| 93 | 66 | |
|---|
| 94 | | - tfm = crypt_stat->hash_tfm; |
|---|
| 95 | | - rc = ecryptfs_hash_digest(tfm, src, len, dst); |
|---|
| 96 | 67 | if (rc) { |
|---|
| 97 | 68 | printk(KERN_ERR |
|---|
| 98 | 69 | "%s: Error computing crypto hash; rc = [%d]\n", |
|---|
| .. | .. |
|---|
| 610 | 581 | full_alg_name); |
|---|
| 611 | 582 | goto out_free; |
|---|
| 612 | 583 | } |
|---|
| 613 | | - crypto_skcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
|---|
| 584 | + crypto_skcipher_set_flags(crypt_stat->tfm, |
|---|
| 585 | + CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); |
|---|
| 614 | 586 | rc = 0; |
|---|
| 615 | 587 | out_free: |
|---|
| 616 | 588 | kfree(full_alg_name); |
|---|
| .. | .. |
|---|
| 874 | 846 | * @crypt_stat: The cryptographic context |
|---|
| 875 | 847 | * @page_virt: Source data to be parsed |
|---|
| 876 | 848 | * @bytes_read: Updated with the number of bytes read |
|---|
| 877 | | - * |
|---|
| 878 | | - * Returns zero on success; non-zero if the flag set is invalid |
|---|
| 879 | 849 | */ |
|---|
| 880 | | -static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat, |
|---|
| 850 | +static void ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat, |
|---|
| 881 | 851 | char *page_virt, int *bytes_read) |
|---|
| 882 | 852 | { |
|---|
| 883 | | - int rc = 0; |
|---|
| 884 | 853 | int i; |
|---|
| 885 | 854 | u32 flags; |
|---|
| 886 | 855 | |
|---|
| .. | .. |
|---|
| 893 | 862 | /* Version is in top 8 bits of the 32-bit flag vector */ |
|---|
| 894 | 863 | crypt_stat->file_version = ((flags >> 24) & 0xFF); |
|---|
| 895 | 864 | (*bytes_read) = 4; |
|---|
| 896 | | - return rc; |
|---|
| 897 | 865 | } |
|---|
| 898 | 866 | |
|---|
| 899 | 867 | /** |
|---|
| .. | .. |
|---|
| 1131 | 1099 | char *page_virt, size_t size) |
|---|
| 1132 | 1100 | { |
|---|
| 1133 | 1101 | int rc; |
|---|
| 1102 | + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
|---|
| 1103 | + struct inode *lower_inode = d_inode(lower_dentry); |
|---|
| 1134 | 1104 | |
|---|
| 1135 | | - rc = ecryptfs_setxattr(ecryptfs_dentry, ecryptfs_inode, |
|---|
| 1136 | | - ECRYPTFS_XATTR_NAME, page_virt, size, 0); |
|---|
| 1105 | + if (!(lower_inode->i_opflags & IOP_XATTR)) { |
|---|
| 1106 | + rc = -EOPNOTSUPP; |
|---|
| 1107 | + goto out; |
|---|
| 1108 | + } |
|---|
| 1109 | + |
|---|
| 1110 | + inode_lock(lower_inode); |
|---|
| 1111 | + rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, |
|---|
| 1112 | + page_virt, size, 0); |
|---|
| 1113 | + if (!rc && ecryptfs_inode) |
|---|
| 1114 | + fsstack_copy_attr_all(ecryptfs_inode, lower_inode); |
|---|
| 1115 | + inode_unlock(lower_inode); |
|---|
| 1116 | +out: |
|---|
| 1137 | 1117 | return rc; |
|---|
| 1138 | 1118 | } |
|---|
| 1139 | 1119 | |
|---|
| .. | .. |
|---|
| 1307 | 1287 | if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) |
|---|
| 1308 | 1288 | ecryptfs_i_size_init(page_virt, d_inode(ecryptfs_dentry)); |
|---|
| 1309 | 1289 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
|---|
| 1310 | | - rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset), |
|---|
| 1311 | | - &bytes_read); |
|---|
| 1312 | | - if (rc) { |
|---|
| 1313 | | - ecryptfs_printk(KERN_WARNING, "Error processing flags\n"); |
|---|
| 1314 | | - goto out; |
|---|
| 1315 | | - } |
|---|
| 1290 | + ecryptfs_process_flags(crypt_stat, (page_virt + offset), &bytes_read); |
|---|
| 1316 | 1291 | if (crypt_stat->file_version > ECRYPTFS_SUPPORTED_FILE_VERSION) { |
|---|
| 1317 | 1292 | ecryptfs_printk(KERN_WARNING, "File version is [%d]; only " |
|---|
| 1318 | 1293 | "file version [%d] is supported by this " |
|---|
| .. | .. |
|---|
| 1594 | 1569 | "[%s]; rc = [%d]\n", full_alg_name, rc); |
|---|
| 1595 | 1570 | goto out; |
|---|
| 1596 | 1571 | } |
|---|
| 1597 | | - crypto_skcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
|---|
| 1572 | + crypto_skcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); |
|---|
| 1598 | 1573 | if (*key_size == 0) |
|---|
| 1599 | | - *key_size = crypto_skcipher_default_keysize(*key_tfm); |
|---|
| 1574 | + *key_size = crypto_skcipher_max_keysize(*key_tfm); |
|---|
| 1600 | 1575 | get_random_bytes(dummy_key, *key_size); |
|---|
| 1601 | 1576 | rc = crypto_skcipher_setkey(*key_tfm, dummy_key, *key_size); |
|---|
| 1602 | 1577 | if (rc) { |
|---|