Whamcloud - gitweb
LU-12275 sec: decryption for read path
[fs/lustre-release.git] / lustre / llite / crypto.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2019, 2020, Whamcloud.
24  */
25 /*
26  * This file is part of Lustre, http://www.lustre.org/
27  */
28
29 #include "llite_internal.h"
30
31 #ifdef HAVE_LUSTRE_CRYPTO
32
33 static int ll_get_context(struct inode *inode, void *ctx, size_t len)
34 {
35         struct dentry *dentry;
36         int rc;
37
38         if (hlist_empty(&inode->i_dentry))
39                 return -ENODATA;
40
41         hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
42                 break;
43         }
44
45         rc = ll_vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
46                              ctx, len);
47
48         /* used as encryption unit size */
49         if (S_ISREG(inode->i_mode))
50                 inode->i_blkbits = LUSTRE_ENCRYPTION_BLOCKBITS;
51         return rc;
52 }
53
54 static int ll_set_context(struct inode *inode, const void *ctx, size_t len,
55                           void *fs_data)
56 {
57         unsigned int ext_flags;
58         struct dentry *dentry;
59         struct md_op_data *op_data;
60         struct ptlrpc_request *req = NULL;
61         int rc;
62
63         if (inode == NULL)
64                 return 0;
65
66         ext_flags = ll_inode_to_ext_flags(inode->i_flags) | LUSTRE_ENCRYPT_FL;
67         dentry = (struct dentry *)fs_data;
68
69         /* Encrypting the root directory is not allowed */
70         if (inode->i_ino == inode->i_sb->s_root->d_inode->i_ino)
71                 return -EPERM;
72
73         op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
74                                      LUSTRE_OPC_ANY, NULL);
75         if (IS_ERR(op_data))
76                 return PTR_ERR(op_data);
77
78         op_data->op_attr_flags = LUSTRE_ENCRYPT_FL;
79         op_data->op_xvalid |= OP_XVALID_FLAGS;
80         rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL, 0, &req);
81         ll_finish_md_op_data(op_data);
82         ptlrpc_req_finished(req);
83         if (rc)
84                 return rc;
85
86         rc = ll_vfs_setxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
87                              ctx, len, XATTR_CREATE);
88         if (rc)
89                 return rc;
90
91         /* used as encryption unit size */
92         if (S_ISREG(inode->i_mode))
93                 inode->i_blkbits = LUSTRE_ENCRYPTION_BLOCKBITS;
94         ll_update_inode_flags(inode, ext_flags);
95         return 0;
96 }
97
98 inline bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi)
99 {
100         return unlikely(sbi->ll_flags & LL_SBI_TEST_DUMMY_ENCRYPTION);
101 }
102
103 static bool ll_dummy_context(struct inode *inode)
104 {
105         struct ll_sb_info *sbi = ll_i2sbi(inode);
106
107         return sbi ? ll_sbi_has_test_dummy_encryption(sbi) : false;
108 }
109
110 inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi)
111 {
112         return sbi->ll_flags & LL_SBI_ENCRYPT;
113 }
114
115 inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set)
116 {
117         if (set)
118                 sbi->ll_flags |= LL_SBI_ENCRYPT;
119         else
120                 sbi->ll_flags &=
121                         ~(LL_SBI_ENCRYPT | LL_SBI_TEST_DUMMY_ENCRYPTION);
122 }
123
124 static bool ll_empty_dir(struct inode *inode)
125 {
126         /* used by llcrypt_ioctl_set_policy(), because a policy can only be set
127          * on an empty dir.
128          */
129         /* Here we choose to return true, meaning we always call .set_context.
130          * Then we rely on server side, with mdd_fix_attr() that calls
131          * mdd_dir_is_empty() when setting encryption flag on directory.
132          */
133         return true;
134 }
135
136 const struct llcrypt_operations lustre_cryptops = {
137         .key_prefix             = "lustre:",
138         .get_context            = ll_get_context,
139         .set_context            = ll_set_context,
140         .dummy_context          = ll_dummy_context,
141         .empty_dir              = ll_empty_dir,
142         .max_namelen            = NAME_MAX,
143 };
144 #else /* !HAVE_LUSTRE_CRYPTO */
145 inline bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi)
146 {
147         return false;
148 }
149
150 inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi)
151 {
152         return false;
153 }
154
155 inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set)
156 {
157 }
158 #endif
159