Commit d55140ce3a7b36241171bd78c75a5ee85de20439
Exists in
master
and in
4 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6: Ecryptfs: Add mount option to check uid of device being mounted = expect uid eCryptfs: Fix payload_len unitialized variable warning eCryptfs: fix compile error eCryptfs: Return error when lower file pointer is NULL
Showing 4 changed files Inline Diff
fs/ecryptfs/Kconfig
1 | config ECRYPT_FS | 1 | config ECRYPT_FS |
2 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" | 2 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" |
3 | depends on EXPERIMENTAL && KEYS && CRYPTO | 3 | depends on EXPERIMENTAL && KEYS && CRYPTO && (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n) |
4 | select CRYPTO_ECB | 4 | select CRYPTO_ECB |
5 | select CRYPTO_CBC | 5 | select CRYPTO_CBC |
6 | select CRYPTO_MD5 | 6 | select CRYPTO_MD5 |
7 | help | 7 | help |
8 | Encrypted filesystem that operates on the VFS layer. See | 8 | Encrypted filesystem that operates on the VFS layer. See |
9 | <file:Documentation/filesystems/ecryptfs.txt> to learn more about | 9 | <file:Documentation/filesystems/ecryptfs.txt> to learn more about |
10 | eCryptfs. Userspace components are required and can be | 10 | eCryptfs. Userspace components are required and can be |
11 | obtained from <http://ecryptfs.sf.net>. | 11 | obtained from <http://ecryptfs.sf.net>. |
12 | 12 | ||
13 | To compile this file system support as a module, choose M here: the | 13 | To compile this file system support as a module, choose M here: the |
14 | module will be called ecryptfs. | 14 | module will be called ecryptfs. |
15 | 15 |
fs/ecryptfs/keystore.c
1 | /** | 1 | /** |
2 | * eCryptfs: Linux filesystem encryption layer | 2 | * eCryptfs: Linux filesystem encryption layer |
3 | * In-kernel key management code. Includes functions to parse and | 3 | * In-kernel key management code. Includes functions to parse and |
4 | * write authentication token-related packets with the underlying | 4 | * write authentication token-related packets with the underlying |
5 | * file. | 5 | * file. |
6 | * | 6 | * |
7 | * Copyright (C) 2004-2006 International Business Machines Corp. | 7 | * Copyright (C) 2004-2006 International Business Machines Corp. |
8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | 8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> |
9 | * Michael C. Thompson <mcthomps@us.ibm.com> | 9 | * Michael C. Thompson <mcthomps@us.ibm.com> |
10 | * Trevor S. Highland <trevor.highland@gmail.com> | 10 | * Trevor S. Highland <trevor.highland@gmail.com> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
14 | * published by the Free Software Foundation; either version 2 of the | 14 | * published by the Free Software Foundation; either version 2 of the |
15 | * License, or (at your option) any later version. | 15 | * License, or (at your option) any later version. |
16 | * | 16 | * |
17 | * This program is distributed in the hope that it will be useful, but | 17 | * This program is distributed in the hope that it will be useful, but |
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 | * General Public License for more details. | 20 | * General Public License for more details. |
21 | * | 21 | * |
22 | * You should have received a copy of the GNU General Public License | 22 | * You should have received a copy of the GNU General Public License |
23 | * along with this program; if not, write to the Free Software | 23 | * along with this program; if not, write to the Free Software |
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | 24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
25 | * 02111-1307, USA. | 25 | * 02111-1307, USA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
31 | #include <linux/key.h> | 31 | #include <linux/key.h> |
32 | #include <linux/random.h> | 32 | #include <linux/random.h> |
33 | #include <linux/crypto.h> | 33 | #include <linux/crypto.h> |
34 | #include <linux/scatterlist.h> | 34 | #include <linux/scatterlist.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include "ecryptfs_kernel.h" | 36 | #include "ecryptfs_kernel.h" |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * request_key returned an error instead of a valid key address; | 39 | * request_key returned an error instead of a valid key address; |
40 | * determine the type of error, make appropriate log entries, and | 40 | * determine the type of error, make appropriate log entries, and |
41 | * return an error code. | 41 | * return an error code. |
42 | */ | 42 | */ |
43 | static int process_request_key_err(long err_code) | 43 | static int process_request_key_err(long err_code) |
44 | { | 44 | { |
45 | int rc = 0; | 45 | int rc = 0; |
46 | 46 | ||
47 | switch (err_code) { | 47 | switch (err_code) { |
48 | case -ENOKEY: | 48 | case -ENOKEY: |
49 | ecryptfs_printk(KERN_WARNING, "No key\n"); | 49 | ecryptfs_printk(KERN_WARNING, "No key\n"); |
50 | rc = -ENOENT; | 50 | rc = -ENOENT; |
51 | break; | 51 | break; |
52 | case -EKEYEXPIRED: | 52 | case -EKEYEXPIRED: |
53 | ecryptfs_printk(KERN_WARNING, "Key expired\n"); | 53 | ecryptfs_printk(KERN_WARNING, "Key expired\n"); |
54 | rc = -ETIME; | 54 | rc = -ETIME; |
55 | break; | 55 | break; |
56 | case -EKEYREVOKED: | 56 | case -EKEYREVOKED: |
57 | ecryptfs_printk(KERN_WARNING, "Key revoked\n"); | 57 | ecryptfs_printk(KERN_WARNING, "Key revoked\n"); |
58 | rc = -EINVAL; | 58 | rc = -EINVAL; |
59 | break; | 59 | break; |
60 | default: | 60 | default: |
61 | ecryptfs_printk(KERN_WARNING, "Unknown error code: " | 61 | ecryptfs_printk(KERN_WARNING, "Unknown error code: " |
62 | "[0x%.16lx]\n", err_code); | 62 | "[0x%.16lx]\n", err_code); |
63 | rc = -EINVAL; | 63 | rc = -EINVAL; |
64 | } | 64 | } |
65 | return rc; | 65 | return rc; |
66 | } | 66 | } |
67 | 67 | ||
68 | static int process_find_global_auth_tok_for_sig_err(int err_code) | 68 | static int process_find_global_auth_tok_for_sig_err(int err_code) |
69 | { | 69 | { |
70 | int rc = err_code; | 70 | int rc = err_code; |
71 | 71 | ||
72 | switch (err_code) { | 72 | switch (err_code) { |
73 | case -ENOENT: | 73 | case -ENOENT: |
74 | ecryptfs_printk(KERN_WARNING, "Missing auth tok\n"); | 74 | ecryptfs_printk(KERN_WARNING, "Missing auth tok\n"); |
75 | break; | 75 | break; |
76 | case -EINVAL: | 76 | case -EINVAL: |
77 | ecryptfs_printk(KERN_WARNING, "Invalid auth tok\n"); | 77 | ecryptfs_printk(KERN_WARNING, "Invalid auth tok\n"); |
78 | break; | 78 | break; |
79 | default: | 79 | default: |
80 | rc = process_request_key_err(err_code); | 80 | rc = process_request_key_err(err_code); |
81 | break; | 81 | break; |
82 | } | 82 | } |
83 | return rc; | 83 | return rc; |
84 | } | 84 | } |
85 | 85 | ||
86 | /** | 86 | /** |
87 | * ecryptfs_parse_packet_length | 87 | * ecryptfs_parse_packet_length |
88 | * @data: Pointer to memory containing length at offset | 88 | * @data: Pointer to memory containing length at offset |
89 | * @size: This function writes the decoded size to this memory | 89 | * @size: This function writes the decoded size to this memory |
90 | * address; zero on error | 90 | * address; zero on error |
91 | * @length_size: The number of bytes occupied by the encoded length | 91 | * @length_size: The number of bytes occupied by the encoded length |
92 | * | 92 | * |
93 | * Returns zero on success; non-zero on error | 93 | * Returns zero on success; non-zero on error |
94 | */ | 94 | */ |
95 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, | 95 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, |
96 | size_t *length_size) | 96 | size_t *length_size) |
97 | { | 97 | { |
98 | int rc = 0; | 98 | int rc = 0; |
99 | 99 | ||
100 | (*length_size) = 0; | 100 | (*length_size) = 0; |
101 | (*size) = 0; | 101 | (*size) = 0; |
102 | if (data[0] < 192) { | 102 | if (data[0] < 192) { |
103 | /* One-byte length */ | 103 | /* One-byte length */ |
104 | (*size) = (unsigned char)data[0]; | 104 | (*size) = (unsigned char)data[0]; |
105 | (*length_size) = 1; | 105 | (*length_size) = 1; |
106 | } else if (data[0] < 224) { | 106 | } else if (data[0] < 224) { |
107 | /* Two-byte length */ | 107 | /* Two-byte length */ |
108 | (*size) = (((unsigned char)(data[0]) - 192) * 256); | 108 | (*size) = (((unsigned char)(data[0]) - 192) * 256); |
109 | (*size) += ((unsigned char)(data[1]) + 192); | 109 | (*size) += ((unsigned char)(data[1]) + 192); |
110 | (*length_size) = 2; | 110 | (*length_size) = 2; |
111 | } else if (data[0] == 255) { | 111 | } else if (data[0] == 255) { |
112 | /* Five-byte length; we're not supposed to see this */ | 112 | /* Five-byte length; we're not supposed to see this */ |
113 | ecryptfs_printk(KERN_ERR, "Five-byte packet length not " | 113 | ecryptfs_printk(KERN_ERR, "Five-byte packet length not " |
114 | "supported\n"); | 114 | "supported\n"); |
115 | rc = -EINVAL; | 115 | rc = -EINVAL; |
116 | goto out; | 116 | goto out; |
117 | } else { | 117 | } else { |
118 | ecryptfs_printk(KERN_ERR, "Error parsing packet length\n"); | 118 | ecryptfs_printk(KERN_ERR, "Error parsing packet length\n"); |
119 | rc = -EINVAL; | 119 | rc = -EINVAL; |
120 | goto out; | 120 | goto out; |
121 | } | 121 | } |
122 | out: | 122 | out: |
123 | return rc; | 123 | return rc; |
124 | } | 124 | } |
125 | 125 | ||
126 | /** | 126 | /** |
127 | * ecryptfs_write_packet_length | 127 | * ecryptfs_write_packet_length |
128 | * @dest: The byte array target into which to write the length. Must | 128 | * @dest: The byte array target into which to write the length. Must |
129 | * have at least 5 bytes allocated. | 129 | * have at least 5 bytes allocated. |
130 | * @size: The length to write. | 130 | * @size: The length to write. |
131 | * @packet_size_length: The number of bytes used to encode the packet | 131 | * @packet_size_length: The number of bytes used to encode the packet |
132 | * length is written to this address. | 132 | * length is written to this address. |
133 | * | 133 | * |
134 | * Returns zero on success; non-zero on error. | 134 | * Returns zero on success; non-zero on error. |
135 | */ | 135 | */ |
136 | int ecryptfs_write_packet_length(char *dest, size_t size, | 136 | int ecryptfs_write_packet_length(char *dest, size_t size, |
137 | size_t *packet_size_length) | 137 | size_t *packet_size_length) |
138 | { | 138 | { |
139 | int rc = 0; | 139 | int rc = 0; |
140 | 140 | ||
141 | if (size < 192) { | 141 | if (size < 192) { |
142 | dest[0] = size; | 142 | dest[0] = size; |
143 | (*packet_size_length) = 1; | 143 | (*packet_size_length) = 1; |
144 | } else if (size < 65536) { | 144 | } else if (size < 65536) { |
145 | dest[0] = (((size - 192) / 256) + 192); | 145 | dest[0] = (((size - 192) / 256) + 192); |
146 | dest[1] = ((size - 192) % 256); | 146 | dest[1] = ((size - 192) % 256); |
147 | (*packet_size_length) = 2; | 147 | (*packet_size_length) = 2; |
148 | } else { | 148 | } else { |
149 | rc = -EINVAL; | 149 | rc = -EINVAL; |
150 | ecryptfs_printk(KERN_WARNING, | 150 | ecryptfs_printk(KERN_WARNING, |
151 | "Unsupported packet size: [%zd]\n", size); | 151 | "Unsupported packet size: [%zd]\n", size); |
152 | } | 152 | } |
153 | return rc; | 153 | return rc; |
154 | } | 154 | } |
155 | 155 | ||
156 | static int | 156 | static int |
157 | write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, | 157 | write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, |
158 | char **packet, size_t *packet_len) | 158 | char **packet, size_t *packet_len) |
159 | { | 159 | { |
160 | size_t i = 0; | 160 | size_t i = 0; |
161 | size_t data_len; | 161 | size_t data_len; |
162 | size_t packet_size_len; | 162 | size_t packet_size_len; |
163 | char *message; | 163 | char *message; |
164 | int rc; | 164 | int rc; |
165 | 165 | ||
166 | /* | 166 | /* |
167 | * ***** TAG 64 Packet Format ***** | 167 | * ***** TAG 64 Packet Format ***** |
168 | * | Content Type | 1 byte | | 168 | * | Content Type | 1 byte | |
169 | * | Key Identifier Size | 1 or 2 bytes | | 169 | * | Key Identifier Size | 1 or 2 bytes | |
170 | * | Key Identifier | arbitrary | | 170 | * | Key Identifier | arbitrary | |
171 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | 171 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | |
172 | * | Encrypted File Encryption Key | arbitrary | | 172 | * | Encrypted File Encryption Key | arbitrary | |
173 | */ | 173 | */ |
174 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX | 174 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX |
175 | + session_key->encrypted_key_size); | 175 | + session_key->encrypted_key_size); |
176 | *packet = kmalloc(data_len, GFP_KERNEL); | 176 | *packet = kmalloc(data_len, GFP_KERNEL); |
177 | message = *packet; | 177 | message = *packet; |
178 | if (!message) { | 178 | if (!message) { |
179 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 179 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); |
180 | rc = -ENOMEM; | 180 | rc = -ENOMEM; |
181 | goto out; | 181 | goto out; |
182 | } | 182 | } |
183 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; | 183 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; |
184 | rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | 184 | rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, |
185 | &packet_size_len); | 185 | &packet_size_len); |
186 | if (rc) { | 186 | if (rc) { |
187 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | 187 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " |
188 | "header; cannot generate packet length\n"); | 188 | "header; cannot generate packet length\n"); |
189 | goto out; | 189 | goto out; |
190 | } | 190 | } |
191 | i += packet_size_len; | 191 | i += packet_size_len; |
192 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | 192 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); |
193 | i += ECRYPTFS_SIG_SIZE_HEX; | 193 | i += ECRYPTFS_SIG_SIZE_HEX; |
194 | rc = ecryptfs_write_packet_length(&message[i], | 194 | rc = ecryptfs_write_packet_length(&message[i], |
195 | session_key->encrypted_key_size, | 195 | session_key->encrypted_key_size, |
196 | &packet_size_len); | 196 | &packet_size_len); |
197 | if (rc) { | 197 | if (rc) { |
198 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | 198 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " |
199 | "header; cannot generate packet length\n"); | 199 | "header; cannot generate packet length\n"); |
200 | goto out; | 200 | goto out; |
201 | } | 201 | } |
202 | i += packet_size_len; | 202 | i += packet_size_len; |
203 | memcpy(&message[i], session_key->encrypted_key, | 203 | memcpy(&message[i], session_key->encrypted_key, |
204 | session_key->encrypted_key_size); | 204 | session_key->encrypted_key_size); |
205 | i += session_key->encrypted_key_size; | 205 | i += session_key->encrypted_key_size; |
206 | *packet_len = i; | 206 | *packet_len = i; |
207 | out: | 207 | out: |
208 | return rc; | 208 | return rc; |
209 | } | 209 | } |
210 | 210 | ||
211 | static int | 211 | static int |
212 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code, | 212 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code, |
213 | struct ecryptfs_message *msg) | 213 | struct ecryptfs_message *msg) |
214 | { | 214 | { |
215 | size_t i = 0; | 215 | size_t i = 0; |
216 | char *data; | 216 | char *data; |
217 | size_t data_len; | 217 | size_t data_len; |
218 | size_t m_size; | 218 | size_t m_size; |
219 | size_t message_len; | 219 | size_t message_len; |
220 | u16 checksum = 0; | 220 | u16 checksum = 0; |
221 | u16 expected_checksum = 0; | 221 | u16 expected_checksum = 0; |
222 | int rc; | 222 | int rc; |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * ***** TAG 65 Packet Format ***** | 225 | * ***** TAG 65 Packet Format ***** |
226 | * | Content Type | 1 byte | | 226 | * | Content Type | 1 byte | |
227 | * | Status Indicator | 1 byte | | 227 | * | Status Indicator | 1 byte | |
228 | * | File Encryption Key Size | 1 or 2 bytes | | 228 | * | File Encryption Key Size | 1 or 2 bytes | |
229 | * | File Encryption Key | arbitrary | | 229 | * | File Encryption Key | arbitrary | |
230 | */ | 230 | */ |
231 | message_len = msg->data_len; | 231 | message_len = msg->data_len; |
232 | data = msg->data; | 232 | data = msg->data; |
233 | if (message_len < 4) { | 233 | if (message_len < 4) { |
234 | rc = -EIO; | 234 | rc = -EIO; |
235 | goto out; | 235 | goto out; |
236 | } | 236 | } |
237 | if (data[i++] != ECRYPTFS_TAG_65_PACKET_TYPE) { | 237 | if (data[i++] != ECRYPTFS_TAG_65_PACKET_TYPE) { |
238 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_65\n"); | 238 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_65\n"); |
239 | rc = -EIO; | 239 | rc = -EIO; |
240 | goto out; | 240 | goto out; |
241 | } | 241 | } |
242 | if (data[i++]) { | 242 | if (data[i++]) { |
243 | ecryptfs_printk(KERN_ERR, "Status indicator has non-zero value " | 243 | ecryptfs_printk(KERN_ERR, "Status indicator has non-zero value " |
244 | "[%d]\n", data[i-1]); | 244 | "[%d]\n", data[i-1]); |
245 | rc = -EIO; | 245 | rc = -EIO; |
246 | goto out; | 246 | goto out; |
247 | } | 247 | } |
248 | rc = ecryptfs_parse_packet_length(&data[i], &m_size, &data_len); | 248 | rc = ecryptfs_parse_packet_length(&data[i], &m_size, &data_len); |
249 | if (rc) { | 249 | if (rc) { |
250 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | 250 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " |
251 | "rc = [%d]\n", rc); | 251 | "rc = [%d]\n", rc); |
252 | goto out; | 252 | goto out; |
253 | } | 253 | } |
254 | i += data_len; | 254 | i += data_len; |
255 | if (message_len < (i + m_size)) { | 255 | if (message_len < (i + m_size)) { |
256 | ecryptfs_printk(KERN_ERR, "The message received from ecryptfsd " | 256 | ecryptfs_printk(KERN_ERR, "The message received from ecryptfsd " |
257 | "is shorter than expected\n"); | 257 | "is shorter than expected\n"); |
258 | rc = -EIO; | 258 | rc = -EIO; |
259 | goto out; | 259 | goto out; |
260 | } | 260 | } |
261 | if (m_size < 3) { | 261 | if (m_size < 3) { |
262 | ecryptfs_printk(KERN_ERR, | 262 | ecryptfs_printk(KERN_ERR, |
263 | "The decrypted key is not long enough to " | 263 | "The decrypted key is not long enough to " |
264 | "include a cipher code and checksum\n"); | 264 | "include a cipher code and checksum\n"); |
265 | rc = -EIO; | 265 | rc = -EIO; |
266 | goto out; | 266 | goto out; |
267 | } | 267 | } |
268 | *cipher_code = data[i++]; | 268 | *cipher_code = data[i++]; |
269 | /* The decrypted key includes 1 byte cipher code and 2 byte checksum */ | 269 | /* The decrypted key includes 1 byte cipher code and 2 byte checksum */ |
270 | session_key->decrypted_key_size = m_size - 3; | 270 | session_key->decrypted_key_size = m_size - 3; |
271 | if (session_key->decrypted_key_size > ECRYPTFS_MAX_KEY_BYTES) { | 271 | if (session_key->decrypted_key_size > ECRYPTFS_MAX_KEY_BYTES) { |
272 | ecryptfs_printk(KERN_ERR, "key_size [%d] larger than " | 272 | ecryptfs_printk(KERN_ERR, "key_size [%d] larger than " |
273 | "the maximum key size [%d]\n", | 273 | "the maximum key size [%d]\n", |
274 | session_key->decrypted_key_size, | 274 | session_key->decrypted_key_size, |
275 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | 275 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); |
276 | rc = -EIO; | 276 | rc = -EIO; |
277 | goto out; | 277 | goto out; |
278 | } | 278 | } |
279 | memcpy(session_key->decrypted_key, &data[i], | 279 | memcpy(session_key->decrypted_key, &data[i], |
280 | session_key->decrypted_key_size); | 280 | session_key->decrypted_key_size); |
281 | i += session_key->decrypted_key_size; | 281 | i += session_key->decrypted_key_size; |
282 | expected_checksum += (unsigned char)(data[i++]) << 8; | 282 | expected_checksum += (unsigned char)(data[i++]) << 8; |
283 | expected_checksum += (unsigned char)(data[i++]); | 283 | expected_checksum += (unsigned char)(data[i++]); |
284 | for (i = 0; i < session_key->decrypted_key_size; i++) | 284 | for (i = 0; i < session_key->decrypted_key_size; i++) |
285 | checksum += session_key->decrypted_key[i]; | 285 | checksum += session_key->decrypted_key[i]; |
286 | if (expected_checksum != checksum) { | 286 | if (expected_checksum != checksum) { |
287 | ecryptfs_printk(KERN_ERR, "Invalid checksum for file " | 287 | ecryptfs_printk(KERN_ERR, "Invalid checksum for file " |
288 | "encryption key; expected [%x]; calculated " | 288 | "encryption key; expected [%x]; calculated " |
289 | "[%x]\n", expected_checksum, checksum); | 289 | "[%x]\n", expected_checksum, checksum); |
290 | rc = -EIO; | 290 | rc = -EIO; |
291 | } | 291 | } |
292 | out: | 292 | out: |
293 | return rc; | 293 | return rc; |
294 | } | 294 | } |
295 | 295 | ||
296 | 296 | ||
297 | static int | 297 | static int |
298 | write_tag_66_packet(char *signature, u8 cipher_code, | 298 | write_tag_66_packet(char *signature, u8 cipher_code, |
299 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, | 299 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, |
300 | size_t *packet_len) | 300 | size_t *packet_len) |
301 | { | 301 | { |
302 | size_t i = 0; | 302 | size_t i = 0; |
303 | size_t j; | 303 | size_t j; |
304 | size_t data_len; | 304 | size_t data_len; |
305 | size_t checksum = 0; | 305 | size_t checksum = 0; |
306 | size_t packet_size_len; | 306 | size_t packet_size_len; |
307 | char *message; | 307 | char *message; |
308 | int rc; | 308 | int rc; |
309 | 309 | ||
310 | /* | 310 | /* |
311 | * ***** TAG 66 Packet Format ***** | 311 | * ***** TAG 66 Packet Format ***** |
312 | * | Content Type | 1 byte | | 312 | * | Content Type | 1 byte | |
313 | * | Key Identifier Size | 1 or 2 bytes | | 313 | * | Key Identifier Size | 1 or 2 bytes | |
314 | * | Key Identifier | arbitrary | | 314 | * | Key Identifier | arbitrary | |
315 | * | File Encryption Key Size | 1 or 2 bytes | | 315 | * | File Encryption Key Size | 1 or 2 bytes | |
316 | * | File Encryption Key | arbitrary | | 316 | * | File Encryption Key | arbitrary | |
317 | */ | 317 | */ |
318 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size); | 318 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size); |
319 | *packet = kmalloc(data_len, GFP_KERNEL); | 319 | *packet = kmalloc(data_len, GFP_KERNEL); |
320 | message = *packet; | 320 | message = *packet; |
321 | if (!message) { | 321 | if (!message) { |
322 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 322 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); |
323 | rc = -ENOMEM; | 323 | rc = -ENOMEM; |
324 | goto out; | 324 | goto out; |
325 | } | 325 | } |
326 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; | 326 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; |
327 | rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | 327 | rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, |
328 | &packet_size_len); | 328 | &packet_size_len); |
329 | if (rc) { | 329 | if (rc) { |
330 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | 330 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " |
331 | "header; cannot generate packet length\n"); | 331 | "header; cannot generate packet length\n"); |
332 | goto out; | 332 | goto out; |
333 | } | 333 | } |
334 | i += packet_size_len; | 334 | i += packet_size_len; |
335 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | 335 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); |
336 | i += ECRYPTFS_SIG_SIZE_HEX; | 336 | i += ECRYPTFS_SIG_SIZE_HEX; |
337 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ | 337 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ |
338 | rc = ecryptfs_write_packet_length(&message[i], crypt_stat->key_size + 3, | 338 | rc = ecryptfs_write_packet_length(&message[i], crypt_stat->key_size + 3, |
339 | &packet_size_len); | 339 | &packet_size_len); |
340 | if (rc) { | 340 | if (rc) { |
341 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | 341 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " |
342 | "header; cannot generate packet length\n"); | 342 | "header; cannot generate packet length\n"); |
343 | goto out; | 343 | goto out; |
344 | } | 344 | } |
345 | i += packet_size_len; | 345 | i += packet_size_len; |
346 | message[i++] = cipher_code; | 346 | message[i++] = cipher_code; |
347 | memcpy(&message[i], crypt_stat->key, crypt_stat->key_size); | 347 | memcpy(&message[i], crypt_stat->key, crypt_stat->key_size); |
348 | i += crypt_stat->key_size; | 348 | i += crypt_stat->key_size; |
349 | for (j = 0; j < crypt_stat->key_size; j++) | 349 | for (j = 0; j < crypt_stat->key_size; j++) |
350 | checksum += crypt_stat->key[j]; | 350 | checksum += crypt_stat->key[j]; |
351 | message[i++] = (checksum / 256) % 256; | 351 | message[i++] = (checksum / 256) % 256; |
352 | message[i++] = (checksum % 256); | 352 | message[i++] = (checksum % 256); |
353 | *packet_len = i; | 353 | *packet_len = i; |
354 | out: | 354 | out: |
355 | return rc; | 355 | return rc; |
356 | } | 356 | } |
357 | 357 | ||
358 | static int | 358 | static int |
359 | parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | 359 | parse_tag_67_packet(struct ecryptfs_key_record *key_rec, |
360 | struct ecryptfs_message *msg) | 360 | struct ecryptfs_message *msg) |
361 | { | 361 | { |
362 | size_t i = 0; | 362 | size_t i = 0; |
363 | char *data; | 363 | char *data; |
364 | size_t data_len; | 364 | size_t data_len; |
365 | size_t message_len; | 365 | size_t message_len; |
366 | int rc; | 366 | int rc; |
367 | 367 | ||
368 | /* | 368 | /* |
369 | * ***** TAG 65 Packet Format ***** | 369 | * ***** TAG 65 Packet Format ***** |
370 | * | Content Type | 1 byte | | 370 | * | Content Type | 1 byte | |
371 | * | Status Indicator | 1 byte | | 371 | * | Status Indicator | 1 byte | |
372 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | 372 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | |
373 | * | Encrypted File Encryption Key | arbitrary | | 373 | * | Encrypted File Encryption Key | arbitrary | |
374 | */ | 374 | */ |
375 | message_len = msg->data_len; | 375 | message_len = msg->data_len; |
376 | data = msg->data; | 376 | data = msg->data; |
377 | /* verify that everything through the encrypted FEK size is present */ | 377 | /* verify that everything through the encrypted FEK size is present */ |
378 | if (message_len < 4) { | 378 | if (message_len < 4) { |
379 | rc = -EIO; | 379 | rc = -EIO; |
380 | printk(KERN_ERR "%s: message_len is [%zd]; minimum acceptable " | 380 | printk(KERN_ERR "%s: message_len is [%zd]; minimum acceptable " |
381 | "message length is [%d]\n", __func__, message_len, 4); | 381 | "message length is [%d]\n", __func__, message_len, 4); |
382 | goto out; | 382 | goto out; |
383 | } | 383 | } |
384 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { | 384 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { |
385 | rc = -EIO; | 385 | rc = -EIO; |
386 | printk(KERN_ERR "%s: Type should be ECRYPTFS_TAG_67\n", | 386 | printk(KERN_ERR "%s: Type should be ECRYPTFS_TAG_67\n", |
387 | __func__); | 387 | __func__); |
388 | goto out; | 388 | goto out; |
389 | } | 389 | } |
390 | if (data[i++]) { | 390 | if (data[i++]) { |
391 | rc = -EIO; | 391 | rc = -EIO; |
392 | printk(KERN_ERR "%s: Status indicator has non zero " | 392 | printk(KERN_ERR "%s: Status indicator has non zero " |
393 | "value [%d]\n", __func__, data[i-1]); | 393 | "value [%d]\n", __func__, data[i-1]); |
394 | 394 | ||
395 | goto out; | 395 | goto out; |
396 | } | 396 | } |
397 | rc = ecryptfs_parse_packet_length(&data[i], &key_rec->enc_key_size, | 397 | rc = ecryptfs_parse_packet_length(&data[i], &key_rec->enc_key_size, |
398 | &data_len); | 398 | &data_len); |
399 | if (rc) { | 399 | if (rc) { |
400 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | 400 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " |
401 | "rc = [%d]\n", rc); | 401 | "rc = [%d]\n", rc); |
402 | goto out; | 402 | goto out; |
403 | } | 403 | } |
404 | i += data_len; | 404 | i += data_len; |
405 | if (message_len < (i + key_rec->enc_key_size)) { | 405 | if (message_len < (i + key_rec->enc_key_size)) { |
406 | rc = -EIO; | 406 | rc = -EIO; |
407 | printk(KERN_ERR "%s: message_len [%zd]; max len is [%zd]\n", | 407 | printk(KERN_ERR "%s: message_len [%zd]; max len is [%zd]\n", |
408 | __func__, message_len, (i + key_rec->enc_key_size)); | 408 | __func__, message_len, (i + key_rec->enc_key_size)); |
409 | goto out; | 409 | goto out; |
410 | } | 410 | } |
411 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | 411 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { |
412 | rc = -EIO; | 412 | rc = -EIO; |
413 | printk(KERN_ERR "%s: Encrypted key_size [%zd] larger than " | 413 | printk(KERN_ERR "%s: Encrypted key_size [%zd] larger than " |
414 | "the maximum key size [%d]\n", __func__, | 414 | "the maximum key size [%d]\n", __func__, |
415 | key_rec->enc_key_size, | 415 | key_rec->enc_key_size, |
416 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | 416 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); |
417 | goto out; | 417 | goto out; |
418 | } | 418 | } |
419 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); | 419 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); |
420 | out: | 420 | out: |
421 | return rc; | 421 | return rc; |
422 | } | 422 | } |
423 | 423 | ||
424 | /** | 424 | /** |
425 | * ecryptfs_verify_version | 425 | * ecryptfs_verify_version |
426 | * @version: The version number to confirm | 426 | * @version: The version number to confirm |
427 | * | 427 | * |
428 | * Returns zero on good version; non-zero otherwise | 428 | * Returns zero on good version; non-zero otherwise |
429 | */ | 429 | */ |
430 | static int ecryptfs_verify_version(u16 version) | 430 | static int ecryptfs_verify_version(u16 version) |
431 | { | 431 | { |
432 | int rc = 0; | 432 | int rc = 0; |
433 | unsigned char major; | 433 | unsigned char major; |
434 | unsigned char minor; | 434 | unsigned char minor; |
435 | 435 | ||
436 | major = ((version >> 8) & 0xFF); | 436 | major = ((version >> 8) & 0xFF); |
437 | minor = (version & 0xFF); | 437 | minor = (version & 0xFF); |
438 | if (major != ECRYPTFS_VERSION_MAJOR) { | 438 | if (major != ECRYPTFS_VERSION_MAJOR) { |
439 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | 439 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " |
440 | "Expected [%d]; got [%d]\n", | 440 | "Expected [%d]; got [%d]\n", |
441 | ECRYPTFS_VERSION_MAJOR, major); | 441 | ECRYPTFS_VERSION_MAJOR, major); |
442 | rc = -EINVAL; | 442 | rc = -EINVAL; |
443 | goto out; | 443 | goto out; |
444 | } | 444 | } |
445 | if (minor != ECRYPTFS_VERSION_MINOR) { | 445 | if (minor != ECRYPTFS_VERSION_MINOR) { |
446 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | 446 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " |
447 | "Expected [%d]; got [%d]\n", | 447 | "Expected [%d]; got [%d]\n", |
448 | ECRYPTFS_VERSION_MINOR, minor); | 448 | ECRYPTFS_VERSION_MINOR, minor); |
449 | rc = -EINVAL; | 449 | rc = -EINVAL; |
450 | goto out; | 450 | goto out; |
451 | } | 451 | } |
452 | out: | 452 | out: |
453 | return rc; | 453 | return rc; |
454 | } | 454 | } |
455 | 455 | ||
456 | /** | 456 | /** |
457 | * ecryptfs_verify_auth_tok_from_key | 457 | * ecryptfs_verify_auth_tok_from_key |
458 | * @auth_tok_key: key containing the authentication token | 458 | * @auth_tok_key: key containing the authentication token |
459 | * @auth_tok: authentication token | 459 | * @auth_tok: authentication token |
460 | * | 460 | * |
461 | * Returns zero on valid auth tok; -EINVAL otherwise | 461 | * Returns zero on valid auth tok; -EINVAL otherwise |
462 | */ | 462 | */ |
463 | static int | 463 | static int |
464 | ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, | 464 | ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, |
465 | struct ecryptfs_auth_tok **auth_tok) | 465 | struct ecryptfs_auth_tok **auth_tok) |
466 | { | 466 | { |
467 | int rc = 0; | 467 | int rc = 0; |
468 | 468 | ||
469 | (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); | 469 | (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); |
470 | if (ecryptfs_verify_version((*auth_tok)->version)) { | 470 | if (ecryptfs_verify_version((*auth_tok)->version)) { |
471 | printk(KERN_ERR "Data structure version mismatch. Userspace " | 471 | printk(KERN_ERR "Data structure version mismatch. Userspace " |
472 | "tools must match eCryptfs kernel module with major " | 472 | "tools must match eCryptfs kernel module with major " |
473 | "version [%d] and minor version [%d]\n", | 473 | "version [%d] and minor version [%d]\n", |
474 | ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR); | 474 | ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR); |
475 | rc = -EINVAL; | 475 | rc = -EINVAL; |
476 | goto out; | 476 | goto out; |
477 | } | 477 | } |
478 | if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD | 478 | if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD |
479 | && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { | 479 | && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { |
480 | printk(KERN_ERR "Invalid auth_tok structure " | 480 | printk(KERN_ERR "Invalid auth_tok structure " |
481 | "returned from key query\n"); | 481 | "returned from key query\n"); |
482 | rc = -EINVAL; | 482 | rc = -EINVAL; |
483 | goto out; | 483 | goto out; |
484 | } | 484 | } |
485 | out: | 485 | out: |
486 | return rc; | 486 | return rc; |
487 | } | 487 | } |
488 | 488 | ||
489 | static int | 489 | static int |
490 | ecryptfs_find_global_auth_tok_for_sig( | 490 | ecryptfs_find_global_auth_tok_for_sig( |
491 | struct key **auth_tok_key, | 491 | struct key **auth_tok_key, |
492 | struct ecryptfs_auth_tok **auth_tok, | 492 | struct ecryptfs_auth_tok **auth_tok, |
493 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) | 493 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) |
494 | { | 494 | { |
495 | struct ecryptfs_global_auth_tok *walker; | 495 | struct ecryptfs_global_auth_tok *walker; |
496 | int rc = 0; | 496 | int rc = 0; |
497 | 497 | ||
498 | (*auth_tok_key) = NULL; | 498 | (*auth_tok_key) = NULL; |
499 | (*auth_tok) = NULL; | 499 | (*auth_tok) = NULL; |
500 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | 500 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
501 | list_for_each_entry(walker, | 501 | list_for_each_entry(walker, |
502 | &mount_crypt_stat->global_auth_tok_list, | 502 | &mount_crypt_stat->global_auth_tok_list, |
503 | mount_crypt_stat_list) { | 503 | mount_crypt_stat_list) { |
504 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX)) | 504 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX)) |
505 | continue; | 505 | continue; |
506 | 506 | ||
507 | if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) { | 507 | if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) { |
508 | rc = -EINVAL; | 508 | rc = -EINVAL; |
509 | goto out; | 509 | goto out; |
510 | } | 510 | } |
511 | 511 | ||
512 | rc = key_validate(walker->global_auth_tok_key); | 512 | rc = key_validate(walker->global_auth_tok_key); |
513 | if (rc) { | 513 | if (rc) { |
514 | if (rc == -EKEYEXPIRED) | 514 | if (rc == -EKEYEXPIRED) |
515 | goto out; | 515 | goto out; |
516 | goto out_invalid_auth_tok; | 516 | goto out_invalid_auth_tok; |
517 | } | 517 | } |
518 | 518 | ||
519 | down_write(&(walker->global_auth_tok_key->sem)); | 519 | down_write(&(walker->global_auth_tok_key->sem)); |
520 | rc = ecryptfs_verify_auth_tok_from_key( | 520 | rc = ecryptfs_verify_auth_tok_from_key( |
521 | walker->global_auth_tok_key, auth_tok); | 521 | walker->global_auth_tok_key, auth_tok); |
522 | if (rc) | 522 | if (rc) |
523 | goto out_invalid_auth_tok_unlock; | 523 | goto out_invalid_auth_tok_unlock; |
524 | 524 | ||
525 | (*auth_tok_key) = walker->global_auth_tok_key; | 525 | (*auth_tok_key) = walker->global_auth_tok_key; |
526 | key_get(*auth_tok_key); | 526 | key_get(*auth_tok_key); |
527 | goto out; | 527 | goto out; |
528 | } | 528 | } |
529 | rc = -ENOENT; | 529 | rc = -ENOENT; |
530 | goto out; | 530 | goto out; |
531 | out_invalid_auth_tok_unlock: | 531 | out_invalid_auth_tok_unlock: |
532 | up_write(&(walker->global_auth_tok_key->sem)); | 532 | up_write(&(walker->global_auth_tok_key->sem)); |
533 | out_invalid_auth_tok: | 533 | out_invalid_auth_tok: |
534 | printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); | 534 | printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); |
535 | walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; | 535 | walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
536 | key_put(walker->global_auth_tok_key); | 536 | key_put(walker->global_auth_tok_key); |
537 | walker->global_auth_tok_key = NULL; | 537 | walker->global_auth_tok_key = NULL; |
538 | out: | 538 | out: |
539 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | 539 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); |
540 | return rc; | 540 | return rc; |
541 | } | 541 | } |
542 | 542 | ||
543 | /** | 543 | /** |
544 | * ecryptfs_find_auth_tok_for_sig | 544 | * ecryptfs_find_auth_tok_for_sig |
545 | * @auth_tok: Set to the matching auth_tok; NULL if not found | 545 | * @auth_tok: Set to the matching auth_tok; NULL if not found |
546 | * @crypt_stat: inode crypt_stat crypto context | 546 | * @crypt_stat: inode crypt_stat crypto context |
547 | * @sig: Sig of auth_tok to find | 547 | * @sig: Sig of auth_tok to find |
548 | * | 548 | * |
549 | * For now, this function simply looks at the registered auth_tok's | 549 | * For now, this function simply looks at the registered auth_tok's |
550 | * linked off the mount_crypt_stat, so all the auth_toks that can be | 550 | * linked off the mount_crypt_stat, so all the auth_toks that can be |
551 | * used must be registered at mount time. This function could | 551 | * used must be registered at mount time. This function could |
552 | * potentially try a lot harder to find auth_tok's (e.g., by calling | 552 | * potentially try a lot harder to find auth_tok's (e.g., by calling |
553 | * out to ecryptfsd to dynamically retrieve an auth_tok object) so | 553 | * out to ecryptfsd to dynamically retrieve an auth_tok object) so |
554 | * that static registration of auth_tok's will no longer be necessary. | 554 | * that static registration of auth_tok's will no longer be necessary. |
555 | * | 555 | * |
556 | * Returns zero on no error; non-zero on error | 556 | * Returns zero on no error; non-zero on error |
557 | */ | 557 | */ |
558 | static int | 558 | static int |
559 | ecryptfs_find_auth_tok_for_sig( | 559 | ecryptfs_find_auth_tok_for_sig( |
560 | struct key **auth_tok_key, | 560 | struct key **auth_tok_key, |
561 | struct ecryptfs_auth_tok **auth_tok, | 561 | struct ecryptfs_auth_tok **auth_tok, |
562 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 562 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
563 | char *sig) | 563 | char *sig) |
564 | { | 564 | { |
565 | int rc = 0; | 565 | int rc = 0; |
566 | 566 | ||
567 | rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok, | 567 | rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok, |
568 | mount_crypt_stat, sig); | 568 | mount_crypt_stat, sig); |
569 | if (rc == -ENOENT) { | 569 | if (rc == -ENOENT) { |
570 | /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the | 570 | /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the |
571 | * mount_crypt_stat structure, we prevent to use auth toks that | 571 | * mount_crypt_stat structure, we prevent to use auth toks that |
572 | * are not inserted through the ecryptfs_add_global_auth_tok | 572 | * are not inserted through the ecryptfs_add_global_auth_tok |
573 | * function. | 573 | * function. |
574 | */ | 574 | */ |
575 | if (mount_crypt_stat->flags | 575 | if (mount_crypt_stat->flags |
576 | & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY) | 576 | & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY) |
577 | return -EINVAL; | 577 | return -EINVAL; |
578 | 578 | ||
579 | rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, | 579 | rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, |
580 | sig); | 580 | sig); |
581 | } | 581 | } |
582 | return rc; | 582 | return rc; |
583 | } | 583 | } |
584 | 584 | ||
585 | /** | 585 | /** |
586 | * write_tag_70_packet can gobble a lot of stack space. We stuff most | 586 | * write_tag_70_packet can gobble a lot of stack space. We stuff most |
587 | * of the function's parameters in a kmalloc'd struct to help reduce | 587 | * of the function's parameters in a kmalloc'd struct to help reduce |
588 | * eCryptfs' overall stack usage. | 588 | * eCryptfs' overall stack usage. |
589 | */ | 589 | */ |
590 | struct ecryptfs_write_tag_70_packet_silly_stack { | 590 | struct ecryptfs_write_tag_70_packet_silly_stack { |
591 | u8 cipher_code; | 591 | u8 cipher_code; |
592 | size_t max_packet_size; | 592 | size_t max_packet_size; |
593 | size_t packet_size_len; | 593 | size_t packet_size_len; |
594 | size_t block_aligned_filename_size; | 594 | size_t block_aligned_filename_size; |
595 | size_t block_size; | 595 | size_t block_size; |
596 | size_t i; | 596 | size_t i; |
597 | size_t j; | 597 | size_t j; |
598 | size_t num_rand_bytes; | 598 | size_t num_rand_bytes; |
599 | struct mutex *tfm_mutex; | 599 | struct mutex *tfm_mutex; |
600 | char *block_aligned_filename; | 600 | char *block_aligned_filename; |
601 | struct ecryptfs_auth_tok *auth_tok; | 601 | struct ecryptfs_auth_tok *auth_tok; |
602 | struct scatterlist src_sg[2]; | 602 | struct scatterlist src_sg[2]; |
603 | struct scatterlist dst_sg[2]; | 603 | struct scatterlist dst_sg[2]; |
604 | struct blkcipher_desc desc; | 604 | struct blkcipher_desc desc; |
605 | char iv[ECRYPTFS_MAX_IV_BYTES]; | 605 | char iv[ECRYPTFS_MAX_IV_BYTES]; |
606 | char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; | 606 | char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; |
607 | char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; | 607 | char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; |
608 | struct hash_desc hash_desc; | 608 | struct hash_desc hash_desc; |
609 | struct scatterlist hash_sg; | 609 | struct scatterlist hash_sg; |
610 | }; | 610 | }; |
611 | 611 | ||
612 | /** | 612 | /** |
613 | * write_tag_70_packet - Write encrypted filename (EFN) packet against FNEK | 613 | * write_tag_70_packet - Write encrypted filename (EFN) packet against FNEK |
614 | * @filename: NULL-terminated filename string | 614 | * @filename: NULL-terminated filename string |
615 | * | 615 | * |
616 | * This is the simplest mechanism for achieving filename encryption in | 616 | * This is the simplest mechanism for achieving filename encryption in |
617 | * eCryptfs. It encrypts the given filename with the mount-wide | 617 | * eCryptfs. It encrypts the given filename with the mount-wide |
618 | * filename encryption key (FNEK) and stores it in a packet to @dest, | 618 | * filename encryption key (FNEK) and stores it in a packet to @dest, |
619 | * which the callee will encode and write directly into the dentry | 619 | * which the callee will encode and write directly into the dentry |
620 | * name. | 620 | * name. |
621 | */ | 621 | */ |
622 | int | 622 | int |
623 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | 623 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, |
624 | size_t *packet_size, | 624 | size_t *packet_size, |
625 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 625 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
626 | char *filename, size_t filename_size) | 626 | char *filename, size_t filename_size) |
627 | { | 627 | { |
628 | struct ecryptfs_write_tag_70_packet_silly_stack *s; | 628 | struct ecryptfs_write_tag_70_packet_silly_stack *s; |
629 | struct key *auth_tok_key = NULL; | 629 | struct key *auth_tok_key = NULL; |
630 | int rc = 0; | 630 | int rc = 0; |
631 | 631 | ||
632 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 632 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
633 | if (!s) { | 633 | if (!s) { |
634 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | 634 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " |
635 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | 635 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); |
636 | rc = -ENOMEM; | 636 | rc = -ENOMEM; |
637 | goto out; | 637 | goto out; |
638 | } | 638 | } |
639 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 639 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
640 | (*packet_size) = 0; | 640 | (*packet_size) = 0; |
641 | rc = ecryptfs_find_auth_tok_for_sig( | 641 | rc = ecryptfs_find_auth_tok_for_sig( |
642 | &auth_tok_key, | 642 | &auth_tok_key, |
643 | &s->auth_tok, mount_crypt_stat, | 643 | &s->auth_tok, mount_crypt_stat, |
644 | mount_crypt_stat->global_default_fnek_sig); | 644 | mount_crypt_stat->global_default_fnek_sig); |
645 | if (rc) { | 645 | if (rc) { |
646 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | 646 | printk(KERN_ERR "%s: Error attempting to find auth tok for " |
647 | "fnek sig [%s]; rc = [%d]\n", __func__, | 647 | "fnek sig [%s]; rc = [%d]\n", __func__, |
648 | mount_crypt_stat->global_default_fnek_sig, rc); | 648 | mount_crypt_stat->global_default_fnek_sig, rc); |
649 | goto out; | 649 | goto out; |
650 | } | 650 | } |
651 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( | 651 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( |
652 | &s->desc.tfm, | 652 | &s->desc.tfm, |
653 | &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); | 653 | &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); |
654 | if (unlikely(rc)) { | 654 | if (unlikely(rc)) { |
655 | printk(KERN_ERR "Internal error whilst attempting to get " | 655 | printk(KERN_ERR "Internal error whilst attempting to get " |
656 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", | 656 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", |
657 | mount_crypt_stat->global_default_fn_cipher_name, rc); | 657 | mount_crypt_stat->global_default_fn_cipher_name, rc); |
658 | goto out; | 658 | goto out; |
659 | } | 659 | } |
660 | mutex_lock(s->tfm_mutex); | 660 | mutex_lock(s->tfm_mutex); |
661 | s->block_size = crypto_blkcipher_blocksize(s->desc.tfm); | 661 | s->block_size = crypto_blkcipher_blocksize(s->desc.tfm); |
662 | /* Plus one for the \0 separator between the random prefix | 662 | /* Plus one for the \0 separator between the random prefix |
663 | * and the plaintext filename */ | 663 | * and the plaintext filename */ |
664 | s->num_rand_bytes = (ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + 1); | 664 | s->num_rand_bytes = (ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + 1); |
665 | s->block_aligned_filename_size = (s->num_rand_bytes + filename_size); | 665 | s->block_aligned_filename_size = (s->num_rand_bytes + filename_size); |
666 | if ((s->block_aligned_filename_size % s->block_size) != 0) { | 666 | if ((s->block_aligned_filename_size % s->block_size) != 0) { |
667 | s->num_rand_bytes += (s->block_size | 667 | s->num_rand_bytes += (s->block_size |
668 | - (s->block_aligned_filename_size | 668 | - (s->block_aligned_filename_size |
669 | % s->block_size)); | 669 | % s->block_size)); |
670 | s->block_aligned_filename_size = (s->num_rand_bytes | 670 | s->block_aligned_filename_size = (s->num_rand_bytes |
671 | + filename_size); | 671 | + filename_size); |
672 | } | 672 | } |
673 | /* Octet 0: Tag 70 identifier | 673 | /* Octet 0: Tag 70 identifier |
674 | * Octets 1-N1: Tag 70 packet size (includes cipher identifier | 674 | * Octets 1-N1: Tag 70 packet size (includes cipher identifier |
675 | * and block-aligned encrypted filename size) | 675 | * and block-aligned encrypted filename size) |
676 | * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) | 676 | * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) |
677 | * Octet N2-N3: Cipher identifier (1 octet) | 677 | * Octet N2-N3: Cipher identifier (1 octet) |
678 | * Octets N3-N4: Block-aligned encrypted filename | 678 | * Octets N3-N4: Block-aligned encrypted filename |
679 | * - Consists of a minimum number of random characters, a \0 | 679 | * - Consists of a minimum number of random characters, a \0 |
680 | * separator, and then the filename */ | 680 | * separator, and then the filename */ |
681 | s->max_packet_size = (1 /* Tag 70 identifier */ | 681 | s->max_packet_size = (1 /* Tag 70 identifier */ |
682 | + 3 /* Max Tag 70 packet size */ | 682 | + 3 /* Max Tag 70 packet size */ |
683 | + ECRYPTFS_SIG_SIZE /* FNEK sig */ | 683 | + ECRYPTFS_SIG_SIZE /* FNEK sig */ |
684 | + 1 /* Cipher identifier */ | 684 | + 1 /* Cipher identifier */ |
685 | + s->block_aligned_filename_size); | 685 | + s->block_aligned_filename_size); |
686 | if (dest == NULL) { | 686 | if (dest == NULL) { |
687 | (*packet_size) = s->max_packet_size; | 687 | (*packet_size) = s->max_packet_size; |
688 | goto out_unlock; | 688 | goto out_unlock; |
689 | } | 689 | } |
690 | if (s->max_packet_size > (*remaining_bytes)) { | 690 | if (s->max_packet_size > (*remaining_bytes)) { |
691 | printk(KERN_WARNING "%s: Require [%zd] bytes to write; only " | 691 | printk(KERN_WARNING "%s: Require [%zd] bytes to write; only " |
692 | "[%zd] available\n", __func__, s->max_packet_size, | 692 | "[%zd] available\n", __func__, s->max_packet_size, |
693 | (*remaining_bytes)); | 693 | (*remaining_bytes)); |
694 | rc = -EINVAL; | 694 | rc = -EINVAL; |
695 | goto out_unlock; | 695 | goto out_unlock; |
696 | } | 696 | } |
697 | s->block_aligned_filename = kzalloc(s->block_aligned_filename_size, | 697 | s->block_aligned_filename = kzalloc(s->block_aligned_filename_size, |
698 | GFP_KERNEL); | 698 | GFP_KERNEL); |
699 | if (!s->block_aligned_filename) { | 699 | if (!s->block_aligned_filename) { |
700 | printk(KERN_ERR "%s: Out of kernel memory whilst attempting to " | 700 | printk(KERN_ERR "%s: Out of kernel memory whilst attempting to " |
701 | "kzalloc [%zd] bytes\n", __func__, | 701 | "kzalloc [%zd] bytes\n", __func__, |
702 | s->block_aligned_filename_size); | 702 | s->block_aligned_filename_size); |
703 | rc = -ENOMEM; | 703 | rc = -ENOMEM; |
704 | goto out_unlock; | 704 | goto out_unlock; |
705 | } | 705 | } |
706 | s->i = 0; | 706 | s->i = 0; |
707 | dest[s->i++] = ECRYPTFS_TAG_70_PACKET_TYPE; | 707 | dest[s->i++] = ECRYPTFS_TAG_70_PACKET_TYPE; |
708 | rc = ecryptfs_write_packet_length(&dest[s->i], | 708 | rc = ecryptfs_write_packet_length(&dest[s->i], |
709 | (ECRYPTFS_SIG_SIZE | 709 | (ECRYPTFS_SIG_SIZE |
710 | + 1 /* Cipher code */ | 710 | + 1 /* Cipher code */ |
711 | + s->block_aligned_filename_size), | 711 | + s->block_aligned_filename_size), |
712 | &s->packet_size_len); | 712 | &s->packet_size_len); |
713 | if (rc) { | 713 | if (rc) { |
714 | printk(KERN_ERR "%s: Error generating tag 70 packet " | 714 | printk(KERN_ERR "%s: Error generating tag 70 packet " |
715 | "header; cannot generate packet length; rc = [%d]\n", | 715 | "header; cannot generate packet length; rc = [%d]\n", |
716 | __func__, rc); | 716 | __func__, rc); |
717 | goto out_free_unlock; | 717 | goto out_free_unlock; |
718 | } | 718 | } |
719 | s->i += s->packet_size_len; | 719 | s->i += s->packet_size_len; |
720 | ecryptfs_from_hex(&dest[s->i], | 720 | ecryptfs_from_hex(&dest[s->i], |
721 | mount_crypt_stat->global_default_fnek_sig, | 721 | mount_crypt_stat->global_default_fnek_sig, |
722 | ECRYPTFS_SIG_SIZE); | 722 | ECRYPTFS_SIG_SIZE); |
723 | s->i += ECRYPTFS_SIG_SIZE; | 723 | s->i += ECRYPTFS_SIG_SIZE; |
724 | s->cipher_code = ecryptfs_code_for_cipher_string( | 724 | s->cipher_code = ecryptfs_code_for_cipher_string( |
725 | mount_crypt_stat->global_default_fn_cipher_name, | 725 | mount_crypt_stat->global_default_fn_cipher_name, |
726 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 726 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
727 | if (s->cipher_code == 0) { | 727 | if (s->cipher_code == 0) { |
728 | printk(KERN_WARNING "%s: Unable to generate code for " | 728 | printk(KERN_WARNING "%s: Unable to generate code for " |
729 | "cipher [%s] with key bytes [%zd]\n", __func__, | 729 | "cipher [%s] with key bytes [%zd]\n", __func__, |
730 | mount_crypt_stat->global_default_fn_cipher_name, | 730 | mount_crypt_stat->global_default_fn_cipher_name, |
731 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 731 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
732 | rc = -EINVAL; | 732 | rc = -EINVAL; |
733 | goto out_free_unlock; | 733 | goto out_free_unlock; |
734 | } | 734 | } |
735 | dest[s->i++] = s->cipher_code; | 735 | dest[s->i++] = s->cipher_code; |
736 | /* TODO: Support other key modules than passphrase for | 736 | /* TODO: Support other key modules than passphrase for |
737 | * filename encryption */ | 737 | * filename encryption */ |
738 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { | 738 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { |
739 | rc = -EOPNOTSUPP; | 739 | rc = -EOPNOTSUPP; |
740 | printk(KERN_INFO "%s: Filename encryption only supports " | 740 | printk(KERN_INFO "%s: Filename encryption only supports " |
741 | "password tokens\n", __func__); | 741 | "password tokens\n", __func__); |
742 | goto out_free_unlock; | 742 | goto out_free_unlock; |
743 | } | 743 | } |
744 | sg_init_one( | 744 | sg_init_one( |
745 | &s->hash_sg, | 745 | &s->hash_sg, |
746 | (u8 *)s->auth_tok->token.password.session_key_encryption_key, | 746 | (u8 *)s->auth_tok->token.password.session_key_encryption_key, |
747 | s->auth_tok->token.password.session_key_encryption_key_bytes); | 747 | s->auth_tok->token.password.session_key_encryption_key_bytes); |
748 | s->hash_desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 748 | s->hash_desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
749 | s->hash_desc.tfm = crypto_alloc_hash(ECRYPTFS_TAG_70_DIGEST, 0, | 749 | s->hash_desc.tfm = crypto_alloc_hash(ECRYPTFS_TAG_70_DIGEST, 0, |
750 | CRYPTO_ALG_ASYNC); | 750 | CRYPTO_ALG_ASYNC); |
751 | if (IS_ERR(s->hash_desc.tfm)) { | 751 | if (IS_ERR(s->hash_desc.tfm)) { |
752 | rc = PTR_ERR(s->hash_desc.tfm); | 752 | rc = PTR_ERR(s->hash_desc.tfm); |
753 | printk(KERN_ERR "%s: Error attempting to " | 753 | printk(KERN_ERR "%s: Error attempting to " |
754 | "allocate hash crypto context; rc = [%d]\n", | 754 | "allocate hash crypto context; rc = [%d]\n", |
755 | __func__, rc); | 755 | __func__, rc); |
756 | goto out_free_unlock; | 756 | goto out_free_unlock; |
757 | } | 757 | } |
758 | rc = crypto_hash_init(&s->hash_desc); | 758 | rc = crypto_hash_init(&s->hash_desc); |
759 | if (rc) { | 759 | if (rc) { |
760 | printk(KERN_ERR | 760 | printk(KERN_ERR |
761 | "%s: Error initializing crypto hash; rc = [%d]\n", | 761 | "%s: Error initializing crypto hash; rc = [%d]\n", |
762 | __func__, rc); | 762 | __func__, rc); |
763 | goto out_release_free_unlock; | 763 | goto out_release_free_unlock; |
764 | } | 764 | } |
765 | rc = crypto_hash_update( | 765 | rc = crypto_hash_update( |
766 | &s->hash_desc, &s->hash_sg, | 766 | &s->hash_desc, &s->hash_sg, |
767 | s->auth_tok->token.password.session_key_encryption_key_bytes); | 767 | s->auth_tok->token.password.session_key_encryption_key_bytes); |
768 | if (rc) { | 768 | if (rc) { |
769 | printk(KERN_ERR | 769 | printk(KERN_ERR |
770 | "%s: Error updating crypto hash; rc = [%d]\n", | 770 | "%s: Error updating crypto hash; rc = [%d]\n", |
771 | __func__, rc); | 771 | __func__, rc); |
772 | goto out_release_free_unlock; | 772 | goto out_release_free_unlock; |
773 | } | 773 | } |
774 | rc = crypto_hash_final(&s->hash_desc, s->hash); | 774 | rc = crypto_hash_final(&s->hash_desc, s->hash); |
775 | if (rc) { | 775 | if (rc) { |
776 | printk(KERN_ERR | 776 | printk(KERN_ERR |
777 | "%s: Error finalizing crypto hash; rc = [%d]\n", | 777 | "%s: Error finalizing crypto hash; rc = [%d]\n", |
778 | __func__, rc); | 778 | __func__, rc); |
779 | goto out_release_free_unlock; | 779 | goto out_release_free_unlock; |
780 | } | 780 | } |
781 | for (s->j = 0; s->j < (s->num_rand_bytes - 1); s->j++) { | 781 | for (s->j = 0; s->j < (s->num_rand_bytes - 1); s->j++) { |
782 | s->block_aligned_filename[s->j] = | 782 | s->block_aligned_filename[s->j] = |
783 | s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)]; | 783 | s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)]; |
784 | if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE) | 784 | if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE) |
785 | == (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) { | 785 | == (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) { |
786 | sg_init_one(&s->hash_sg, (u8 *)s->hash, | 786 | sg_init_one(&s->hash_sg, (u8 *)s->hash, |
787 | ECRYPTFS_TAG_70_DIGEST_SIZE); | 787 | ECRYPTFS_TAG_70_DIGEST_SIZE); |
788 | rc = crypto_hash_init(&s->hash_desc); | 788 | rc = crypto_hash_init(&s->hash_desc); |
789 | if (rc) { | 789 | if (rc) { |
790 | printk(KERN_ERR | 790 | printk(KERN_ERR |
791 | "%s: Error initializing crypto hash; " | 791 | "%s: Error initializing crypto hash; " |
792 | "rc = [%d]\n", __func__, rc); | 792 | "rc = [%d]\n", __func__, rc); |
793 | goto out_release_free_unlock; | 793 | goto out_release_free_unlock; |
794 | } | 794 | } |
795 | rc = crypto_hash_update(&s->hash_desc, &s->hash_sg, | 795 | rc = crypto_hash_update(&s->hash_desc, &s->hash_sg, |
796 | ECRYPTFS_TAG_70_DIGEST_SIZE); | 796 | ECRYPTFS_TAG_70_DIGEST_SIZE); |
797 | if (rc) { | 797 | if (rc) { |
798 | printk(KERN_ERR | 798 | printk(KERN_ERR |
799 | "%s: Error updating crypto hash; " | 799 | "%s: Error updating crypto hash; " |
800 | "rc = [%d]\n", __func__, rc); | 800 | "rc = [%d]\n", __func__, rc); |
801 | goto out_release_free_unlock; | 801 | goto out_release_free_unlock; |
802 | } | 802 | } |
803 | rc = crypto_hash_final(&s->hash_desc, s->tmp_hash); | 803 | rc = crypto_hash_final(&s->hash_desc, s->tmp_hash); |
804 | if (rc) { | 804 | if (rc) { |
805 | printk(KERN_ERR | 805 | printk(KERN_ERR |
806 | "%s: Error finalizing crypto hash; " | 806 | "%s: Error finalizing crypto hash; " |
807 | "rc = [%d]\n", __func__, rc); | 807 | "rc = [%d]\n", __func__, rc); |
808 | goto out_release_free_unlock; | 808 | goto out_release_free_unlock; |
809 | } | 809 | } |
810 | memcpy(s->hash, s->tmp_hash, | 810 | memcpy(s->hash, s->tmp_hash, |
811 | ECRYPTFS_TAG_70_DIGEST_SIZE); | 811 | ECRYPTFS_TAG_70_DIGEST_SIZE); |
812 | } | 812 | } |
813 | if (s->block_aligned_filename[s->j] == '\0') | 813 | if (s->block_aligned_filename[s->j] == '\0') |
814 | s->block_aligned_filename[s->j] = ECRYPTFS_NON_NULL; | 814 | s->block_aligned_filename[s->j] = ECRYPTFS_NON_NULL; |
815 | } | 815 | } |
816 | memcpy(&s->block_aligned_filename[s->num_rand_bytes], filename, | 816 | memcpy(&s->block_aligned_filename[s->num_rand_bytes], filename, |
817 | filename_size); | 817 | filename_size); |
818 | rc = virt_to_scatterlist(s->block_aligned_filename, | 818 | rc = virt_to_scatterlist(s->block_aligned_filename, |
819 | s->block_aligned_filename_size, s->src_sg, 2); | 819 | s->block_aligned_filename_size, s->src_sg, 2); |
820 | if (rc < 1) { | 820 | if (rc < 1) { |
821 | printk(KERN_ERR "%s: Internal error whilst attempting to " | 821 | printk(KERN_ERR "%s: Internal error whilst attempting to " |
822 | "convert filename memory to scatterlist; rc = [%d]. " | 822 | "convert filename memory to scatterlist; rc = [%d]. " |
823 | "block_aligned_filename_size = [%zd]\n", __func__, rc, | 823 | "block_aligned_filename_size = [%zd]\n", __func__, rc, |
824 | s->block_aligned_filename_size); | 824 | s->block_aligned_filename_size); |
825 | goto out_release_free_unlock; | 825 | goto out_release_free_unlock; |
826 | } | 826 | } |
827 | rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size, | 827 | rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size, |
828 | s->dst_sg, 2); | 828 | s->dst_sg, 2); |
829 | if (rc < 1) { | 829 | if (rc < 1) { |
830 | printk(KERN_ERR "%s: Internal error whilst attempting to " | 830 | printk(KERN_ERR "%s: Internal error whilst attempting to " |
831 | "convert encrypted filename memory to scatterlist; " | 831 | "convert encrypted filename memory to scatterlist; " |
832 | "rc = [%d]. block_aligned_filename_size = [%zd]\n", | 832 | "rc = [%d]. block_aligned_filename_size = [%zd]\n", |
833 | __func__, rc, s->block_aligned_filename_size); | 833 | __func__, rc, s->block_aligned_filename_size); |
834 | goto out_release_free_unlock; | 834 | goto out_release_free_unlock; |
835 | } | 835 | } |
836 | /* The characters in the first block effectively do the job | 836 | /* The characters in the first block effectively do the job |
837 | * of the IV here, so we just use 0's for the IV. Note the | 837 | * of the IV here, so we just use 0's for the IV. Note the |
838 | * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES | 838 | * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES |
839 | * >= ECRYPTFS_MAX_IV_BYTES. */ | 839 | * >= ECRYPTFS_MAX_IV_BYTES. */ |
840 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); | 840 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); |
841 | s->desc.info = s->iv; | 841 | s->desc.info = s->iv; |
842 | rc = crypto_blkcipher_setkey( | 842 | rc = crypto_blkcipher_setkey( |
843 | s->desc.tfm, | 843 | s->desc.tfm, |
844 | s->auth_tok->token.password.session_key_encryption_key, | 844 | s->auth_tok->token.password.session_key_encryption_key, |
845 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 845 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
846 | if (rc < 0) { | 846 | if (rc < 0) { |
847 | printk(KERN_ERR "%s: Error setting key for crypto context; " | 847 | printk(KERN_ERR "%s: Error setting key for crypto context; " |
848 | "rc = [%d]. s->auth_tok->token.password.session_key_" | 848 | "rc = [%d]. s->auth_tok->token.password.session_key_" |
849 | "encryption_key = [0x%p]; mount_crypt_stat->" | 849 | "encryption_key = [0x%p]; mount_crypt_stat->" |
850 | "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, | 850 | "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, |
851 | rc, | 851 | rc, |
852 | s->auth_tok->token.password.session_key_encryption_key, | 852 | s->auth_tok->token.password.session_key_encryption_key, |
853 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 853 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
854 | goto out_release_free_unlock; | 854 | goto out_release_free_unlock; |
855 | } | 855 | } |
856 | rc = crypto_blkcipher_encrypt_iv(&s->desc, s->dst_sg, s->src_sg, | 856 | rc = crypto_blkcipher_encrypt_iv(&s->desc, s->dst_sg, s->src_sg, |
857 | s->block_aligned_filename_size); | 857 | s->block_aligned_filename_size); |
858 | if (rc) { | 858 | if (rc) { |
859 | printk(KERN_ERR "%s: Error attempting to encrypt filename; " | 859 | printk(KERN_ERR "%s: Error attempting to encrypt filename; " |
860 | "rc = [%d]\n", __func__, rc); | 860 | "rc = [%d]\n", __func__, rc); |
861 | goto out_release_free_unlock; | 861 | goto out_release_free_unlock; |
862 | } | 862 | } |
863 | s->i += s->block_aligned_filename_size; | 863 | s->i += s->block_aligned_filename_size; |
864 | (*packet_size) = s->i; | 864 | (*packet_size) = s->i; |
865 | (*remaining_bytes) -= (*packet_size); | 865 | (*remaining_bytes) -= (*packet_size); |
866 | out_release_free_unlock: | 866 | out_release_free_unlock: |
867 | crypto_free_hash(s->hash_desc.tfm); | 867 | crypto_free_hash(s->hash_desc.tfm); |
868 | out_free_unlock: | 868 | out_free_unlock: |
869 | kzfree(s->block_aligned_filename); | 869 | kzfree(s->block_aligned_filename); |
870 | out_unlock: | 870 | out_unlock: |
871 | mutex_unlock(s->tfm_mutex); | 871 | mutex_unlock(s->tfm_mutex); |
872 | out: | 872 | out: |
873 | if (auth_tok_key) { | 873 | if (auth_tok_key) { |
874 | up_write(&(auth_tok_key->sem)); | 874 | up_write(&(auth_tok_key->sem)); |
875 | key_put(auth_tok_key); | 875 | key_put(auth_tok_key); |
876 | } | 876 | } |
877 | kfree(s); | 877 | kfree(s); |
878 | return rc; | 878 | return rc; |
879 | } | 879 | } |
880 | 880 | ||
881 | struct ecryptfs_parse_tag_70_packet_silly_stack { | 881 | struct ecryptfs_parse_tag_70_packet_silly_stack { |
882 | u8 cipher_code; | 882 | u8 cipher_code; |
883 | size_t max_packet_size; | 883 | size_t max_packet_size; |
884 | size_t packet_size_len; | 884 | size_t packet_size_len; |
885 | size_t parsed_tag_70_packet_size; | 885 | size_t parsed_tag_70_packet_size; |
886 | size_t block_aligned_filename_size; | 886 | size_t block_aligned_filename_size; |
887 | size_t block_size; | 887 | size_t block_size; |
888 | size_t i; | 888 | size_t i; |
889 | struct mutex *tfm_mutex; | 889 | struct mutex *tfm_mutex; |
890 | char *decrypted_filename; | 890 | char *decrypted_filename; |
891 | struct ecryptfs_auth_tok *auth_tok; | 891 | struct ecryptfs_auth_tok *auth_tok; |
892 | struct scatterlist src_sg[2]; | 892 | struct scatterlist src_sg[2]; |
893 | struct scatterlist dst_sg[2]; | 893 | struct scatterlist dst_sg[2]; |
894 | struct blkcipher_desc desc; | 894 | struct blkcipher_desc desc; |
895 | char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; | 895 | char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; |
896 | char iv[ECRYPTFS_MAX_IV_BYTES]; | 896 | char iv[ECRYPTFS_MAX_IV_BYTES]; |
897 | char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; | 897 | char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; |
898 | }; | 898 | }; |
899 | 899 | ||
900 | /** | 900 | /** |
901 | * parse_tag_70_packet - Parse and process FNEK-encrypted passphrase packet | 901 | * parse_tag_70_packet - Parse and process FNEK-encrypted passphrase packet |
902 | * @filename: This function kmalloc's the memory for the filename | 902 | * @filename: This function kmalloc's the memory for the filename |
903 | * @filename_size: This function sets this to the amount of memory | 903 | * @filename_size: This function sets this to the amount of memory |
904 | * kmalloc'd for the filename | 904 | * kmalloc'd for the filename |
905 | * @packet_size: This function sets this to the the number of octets | 905 | * @packet_size: This function sets this to the the number of octets |
906 | * in the packet parsed | 906 | * in the packet parsed |
907 | * @mount_crypt_stat: The mount-wide cryptographic context | 907 | * @mount_crypt_stat: The mount-wide cryptographic context |
908 | * @data: The memory location containing the start of the tag 70 | 908 | * @data: The memory location containing the start of the tag 70 |
909 | * packet | 909 | * packet |
910 | * @max_packet_size: The maximum legal size of the packet to be parsed | 910 | * @max_packet_size: The maximum legal size of the packet to be parsed |
911 | * from @data | 911 | * from @data |
912 | * | 912 | * |
913 | * Returns zero on success; non-zero otherwise | 913 | * Returns zero on success; non-zero otherwise |
914 | */ | 914 | */ |
915 | int | 915 | int |
916 | ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | 916 | ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, |
917 | size_t *packet_size, | 917 | size_t *packet_size, |
918 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 918 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
919 | char *data, size_t max_packet_size) | 919 | char *data, size_t max_packet_size) |
920 | { | 920 | { |
921 | struct ecryptfs_parse_tag_70_packet_silly_stack *s; | 921 | struct ecryptfs_parse_tag_70_packet_silly_stack *s; |
922 | struct key *auth_tok_key = NULL; | 922 | struct key *auth_tok_key = NULL; |
923 | int rc = 0; | 923 | int rc = 0; |
924 | 924 | ||
925 | (*packet_size) = 0; | 925 | (*packet_size) = 0; |
926 | (*filename_size) = 0; | 926 | (*filename_size) = 0; |
927 | (*filename) = NULL; | 927 | (*filename) = NULL; |
928 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 928 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
929 | if (!s) { | 929 | if (!s) { |
930 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | 930 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " |
931 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | 931 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); |
932 | rc = -ENOMEM; | 932 | rc = -ENOMEM; |
933 | goto out; | 933 | goto out; |
934 | } | 934 | } |
935 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 935 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
936 | if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) { | 936 | if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) { |
937 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " | 937 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " |
938 | "at least [%d]\n", __func__, max_packet_size, | 938 | "at least [%d]\n", __func__, max_packet_size, |
939 | (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)); | 939 | (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)); |
940 | rc = -EINVAL; | 940 | rc = -EINVAL; |
941 | goto out; | 941 | goto out; |
942 | } | 942 | } |
943 | /* Octet 0: Tag 70 identifier | 943 | /* Octet 0: Tag 70 identifier |
944 | * Octets 1-N1: Tag 70 packet size (includes cipher identifier | 944 | * Octets 1-N1: Tag 70 packet size (includes cipher identifier |
945 | * and block-aligned encrypted filename size) | 945 | * and block-aligned encrypted filename size) |
946 | * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) | 946 | * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) |
947 | * Octet N2-N3: Cipher identifier (1 octet) | 947 | * Octet N2-N3: Cipher identifier (1 octet) |
948 | * Octets N3-N4: Block-aligned encrypted filename | 948 | * Octets N3-N4: Block-aligned encrypted filename |
949 | * - Consists of a minimum number of random numbers, a \0 | 949 | * - Consists of a minimum number of random numbers, a \0 |
950 | * separator, and then the filename */ | 950 | * separator, and then the filename */ |
951 | if (data[(*packet_size)++] != ECRYPTFS_TAG_70_PACKET_TYPE) { | 951 | if (data[(*packet_size)++] != ECRYPTFS_TAG_70_PACKET_TYPE) { |
952 | printk(KERN_WARNING "%s: Invalid packet tag [0x%.2x]; must be " | 952 | printk(KERN_WARNING "%s: Invalid packet tag [0x%.2x]; must be " |
953 | "tag [0x%.2x]\n", __func__, | 953 | "tag [0x%.2x]\n", __func__, |
954 | data[((*packet_size) - 1)], ECRYPTFS_TAG_70_PACKET_TYPE); | 954 | data[((*packet_size) - 1)], ECRYPTFS_TAG_70_PACKET_TYPE); |
955 | rc = -EINVAL; | 955 | rc = -EINVAL; |
956 | goto out; | 956 | goto out; |
957 | } | 957 | } |
958 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], | 958 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], |
959 | &s->parsed_tag_70_packet_size, | 959 | &s->parsed_tag_70_packet_size, |
960 | &s->packet_size_len); | 960 | &s->packet_size_len); |
961 | if (rc) { | 961 | if (rc) { |
962 | printk(KERN_WARNING "%s: Error parsing packet length; " | 962 | printk(KERN_WARNING "%s: Error parsing packet length; " |
963 | "rc = [%d]\n", __func__, rc); | 963 | "rc = [%d]\n", __func__, rc); |
964 | goto out; | 964 | goto out; |
965 | } | 965 | } |
966 | s->block_aligned_filename_size = (s->parsed_tag_70_packet_size | 966 | s->block_aligned_filename_size = (s->parsed_tag_70_packet_size |
967 | - ECRYPTFS_SIG_SIZE - 1); | 967 | - ECRYPTFS_SIG_SIZE - 1); |
968 | if ((1 + s->packet_size_len + s->parsed_tag_70_packet_size) | 968 | if ((1 + s->packet_size_len + s->parsed_tag_70_packet_size) |
969 | > max_packet_size) { | 969 | > max_packet_size) { |
970 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; real packet " | 970 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; real packet " |
971 | "size is [%zd]\n", __func__, max_packet_size, | 971 | "size is [%zd]\n", __func__, max_packet_size, |
972 | (1 + s->packet_size_len + 1 | 972 | (1 + s->packet_size_len + 1 |
973 | + s->block_aligned_filename_size)); | 973 | + s->block_aligned_filename_size)); |
974 | rc = -EINVAL; | 974 | rc = -EINVAL; |
975 | goto out; | 975 | goto out; |
976 | } | 976 | } |
977 | (*packet_size) += s->packet_size_len; | 977 | (*packet_size) += s->packet_size_len; |
978 | ecryptfs_to_hex(s->fnek_sig_hex, &data[(*packet_size)], | 978 | ecryptfs_to_hex(s->fnek_sig_hex, &data[(*packet_size)], |
979 | ECRYPTFS_SIG_SIZE); | 979 | ECRYPTFS_SIG_SIZE); |
980 | s->fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 980 | s->fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
981 | (*packet_size) += ECRYPTFS_SIG_SIZE; | 981 | (*packet_size) += ECRYPTFS_SIG_SIZE; |
982 | s->cipher_code = data[(*packet_size)++]; | 982 | s->cipher_code = data[(*packet_size)++]; |
983 | rc = ecryptfs_cipher_code_to_string(s->cipher_string, s->cipher_code); | 983 | rc = ecryptfs_cipher_code_to_string(s->cipher_string, s->cipher_code); |
984 | if (rc) { | 984 | if (rc) { |
985 | printk(KERN_WARNING "%s: Cipher code [%d] is invalid\n", | 985 | printk(KERN_WARNING "%s: Cipher code [%d] is invalid\n", |
986 | __func__, s->cipher_code); | 986 | __func__, s->cipher_code); |
987 | goto out; | 987 | goto out; |
988 | } | 988 | } |
989 | rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, | 989 | rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, |
990 | &s->auth_tok, mount_crypt_stat, | 990 | &s->auth_tok, mount_crypt_stat, |
991 | s->fnek_sig_hex); | 991 | s->fnek_sig_hex); |
992 | if (rc) { | 992 | if (rc) { |
993 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | 993 | printk(KERN_ERR "%s: Error attempting to find auth tok for " |
994 | "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, | 994 | "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, |
995 | rc); | 995 | rc); |
996 | goto out; | 996 | goto out; |
997 | } | 997 | } |
998 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, | 998 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, |
999 | &s->tfm_mutex, | 999 | &s->tfm_mutex, |
1000 | s->cipher_string); | 1000 | s->cipher_string); |
1001 | if (unlikely(rc)) { | 1001 | if (unlikely(rc)) { |
1002 | printk(KERN_ERR "Internal error whilst attempting to get " | 1002 | printk(KERN_ERR "Internal error whilst attempting to get " |
1003 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", | 1003 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", |
1004 | s->cipher_string, rc); | 1004 | s->cipher_string, rc); |
1005 | goto out; | 1005 | goto out; |
1006 | } | 1006 | } |
1007 | mutex_lock(s->tfm_mutex); | 1007 | mutex_lock(s->tfm_mutex); |
1008 | rc = virt_to_scatterlist(&data[(*packet_size)], | 1008 | rc = virt_to_scatterlist(&data[(*packet_size)], |
1009 | s->block_aligned_filename_size, s->src_sg, 2); | 1009 | s->block_aligned_filename_size, s->src_sg, 2); |
1010 | if (rc < 1) { | 1010 | if (rc < 1) { |
1011 | printk(KERN_ERR "%s: Internal error whilst attempting to " | 1011 | printk(KERN_ERR "%s: Internal error whilst attempting to " |
1012 | "convert encrypted filename memory to scatterlist; " | 1012 | "convert encrypted filename memory to scatterlist; " |
1013 | "rc = [%d]. block_aligned_filename_size = [%zd]\n", | 1013 | "rc = [%d]. block_aligned_filename_size = [%zd]\n", |
1014 | __func__, rc, s->block_aligned_filename_size); | 1014 | __func__, rc, s->block_aligned_filename_size); |
1015 | goto out_unlock; | 1015 | goto out_unlock; |
1016 | } | 1016 | } |
1017 | (*packet_size) += s->block_aligned_filename_size; | 1017 | (*packet_size) += s->block_aligned_filename_size; |
1018 | s->decrypted_filename = kmalloc(s->block_aligned_filename_size, | 1018 | s->decrypted_filename = kmalloc(s->block_aligned_filename_size, |
1019 | GFP_KERNEL); | 1019 | GFP_KERNEL); |
1020 | if (!s->decrypted_filename) { | 1020 | if (!s->decrypted_filename) { |
1021 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | 1021 | printk(KERN_ERR "%s: Out of memory whilst attempting to " |
1022 | "kmalloc [%zd] bytes\n", __func__, | 1022 | "kmalloc [%zd] bytes\n", __func__, |
1023 | s->block_aligned_filename_size); | 1023 | s->block_aligned_filename_size); |
1024 | rc = -ENOMEM; | 1024 | rc = -ENOMEM; |
1025 | goto out_unlock; | 1025 | goto out_unlock; |
1026 | } | 1026 | } |
1027 | rc = virt_to_scatterlist(s->decrypted_filename, | 1027 | rc = virt_to_scatterlist(s->decrypted_filename, |
1028 | s->block_aligned_filename_size, s->dst_sg, 2); | 1028 | s->block_aligned_filename_size, s->dst_sg, 2); |
1029 | if (rc < 1) { | 1029 | if (rc < 1) { |
1030 | printk(KERN_ERR "%s: Internal error whilst attempting to " | 1030 | printk(KERN_ERR "%s: Internal error whilst attempting to " |
1031 | "convert decrypted filename memory to scatterlist; " | 1031 | "convert decrypted filename memory to scatterlist; " |
1032 | "rc = [%d]. block_aligned_filename_size = [%zd]\n", | 1032 | "rc = [%d]. block_aligned_filename_size = [%zd]\n", |
1033 | __func__, rc, s->block_aligned_filename_size); | 1033 | __func__, rc, s->block_aligned_filename_size); |
1034 | goto out_free_unlock; | 1034 | goto out_free_unlock; |
1035 | } | 1035 | } |
1036 | /* The characters in the first block effectively do the job of | 1036 | /* The characters in the first block effectively do the job of |
1037 | * the IV here, so we just use 0's for the IV. Note the | 1037 | * the IV here, so we just use 0's for the IV. Note the |
1038 | * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES | 1038 | * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES |
1039 | * >= ECRYPTFS_MAX_IV_BYTES. */ | 1039 | * >= ECRYPTFS_MAX_IV_BYTES. */ |
1040 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); | 1040 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); |
1041 | s->desc.info = s->iv; | 1041 | s->desc.info = s->iv; |
1042 | /* TODO: Support other key modules than passphrase for | 1042 | /* TODO: Support other key modules than passphrase for |
1043 | * filename encryption */ | 1043 | * filename encryption */ |
1044 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { | 1044 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { |
1045 | rc = -EOPNOTSUPP; | 1045 | rc = -EOPNOTSUPP; |
1046 | printk(KERN_INFO "%s: Filename encryption only supports " | 1046 | printk(KERN_INFO "%s: Filename encryption only supports " |
1047 | "password tokens\n", __func__); | 1047 | "password tokens\n", __func__); |
1048 | goto out_free_unlock; | 1048 | goto out_free_unlock; |
1049 | } | 1049 | } |
1050 | rc = crypto_blkcipher_setkey( | 1050 | rc = crypto_blkcipher_setkey( |
1051 | s->desc.tfm, | 1051 | s->desc.tfm, |
1052 | s->auth_tok->token.password.session_key_encryption_key, | 1052 | s->auth_tok->token.password.session_key_encryption_key, |
1053 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 1053 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
1054 | if (rc < 0) { | 1054 | if (rc < 0) { |
1055 | printk(KERN_ERR "%s: Error setting key for crypto context; " | 1055 | printk(KERN_ERR "%s: Error setting key for crypto context; " |
1056 | "rc = [%d]. s->auth_tok->token.password.session_key_" | 1056 | "rc = [%d]. s->auth_tok->token.password.session_key_" |
1057 | "encryption_key = [0x%p]; mount_crypt_stat->" | 1057 | "encryption_key = [0x%p]; mount_crypt_stat->" |
1058 | "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, | 1058 | "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, |
1059 | rc, | 1059 | rc, |
1060 | s->auth_tok->token.password.session_key_encryption_key, | 1060 | s->auth_tok->token.password.session_key_encryption_key, |
1061 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 1061 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
1062 | goto out_free_unlock; | 1062 | goto out_free_unlock; |
1063 | } | 1063 | } |
1064 | rc = crypto_blkcipher_decrypt_iv(&s->desc, s->dst_sg, s->src_sg, | 1064 | rc = crypto_blkcipher_decrypt_iv(&s->desc, s->dst_sg, s->src_sg, |
1065 | s->block_aligned_filename_size); | 1065 | s->block_aligned_filename_size); |
1066 | if (rc) { | 1066 | if (rc) { |
1067 | printk(KERN_ERR "%s: Error attempting to decrypt filename; " | 1067 | printk(KERN_ERR "%s: Error attempting to decrypt filename; " |
1068 | "rc = [%d]\n", __func__, rc); | 1068 | "rc = [%d]\n", __func__, rc); |
1069 | goto out_free_unlock; | 1069 | goto out_free_unlock; |
1070 | } | 1070 | } |
1071 | s->i = 0; | 1071 | s->i = 0; |
1072 | while (s->decrypted_filename[s->i] != '\0' | 1072 | while (s->decrypted_filename[s->i] != '\0' |
1073 | && s->i < s->block_aligned_filename_size) | 1073 | && s->i < s->block_aligned_filename_size) |
1074 | s->i++; | 1074 | s->i++; |
1075 | if (s->i == s->block_aligned_filename_size) { | 1075 | if (s->i == s->block_aligned_filename_size) { |
1076 | printk(KERN_WARNING "%s: Invalid tag 70 packet; could not " | 1076 | printk(KERN_WARNING "%s: Invalid tag 70 packet; could not " |
1077 | "find valid separator between random characters and " | 1077 | "find valid separator between random characters and " |
1078 | "the filename\n", __func__); | 1078 | "the filename\n", __func__); |
1079 | rc = -EINVAL; | 1079 | rc = -EINVAL; |
1080 | goto out_free_unlock; | 1080 | goto out_free_unlock; |
1081 | } | 1081 | } |
1082 | s->i++; | 1082 | s->i++; |
1083 | (*filename_size) = (s->block_aligned_filename_size - s->i); | 1083 | (*filename_size) = (s->block_aligned_filename_size - s->i); |
1084 | if (!((*filename_size) > 0 && (*filename_size < PATH_MAX))) { | 1084 | if (!((*filename_size) > 0 && (*filename_size < PATH_MAX))) { |
1085 | printk(KERN_WARNING "%s: Filename size is [%zd], which is " | 1085 | printk(KERN_WARNING "%s: Filename size is [%zd], which is " |
1086 | "invalid\n", __func__, (*filename_size)); | 1086 | "invalid\n", __func__, (*filename_size)); |
1087 | rc = -EINVAL; | 1087 | rc = -EINVAL; |
1088 | goto out_free_unlock; | 1088 | goto out_free_unlock; |
1089 | } | 1089 | } |
1090 | (*filename) = kmalloc(((*filename_size) + 1), GFP_KERNEL); | 1090 | (*filename) = kmalloc(((*filename_size) + 1), GFP_KERNEL); |
1091 | if (!(*filename)) { | 1091 | if (!(*filename)) { |
1092 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | 1092 | printk(KERN_ERR "%s: Out of memory whilst attempting to " |
1093 | "kmalloc [%zd] bytes\n", __func__, | 1093 | "kmalloc [%zd] bytes\n", __func__, |
1094 | ((*filename_size) + 1)); | 1094 | ((*filename_size) + 1)); |
1095 | rc = -ENOMEM; | 1095 | rc = -ENOMEM; |
1096 | goto out_free_unlock; | 1096 | goto out_free_unlock; |
1097 | } | 1097 | } |
1098 | memcpy((*filename), &s->decrypted_filename[s->i], (*filename_size)); | 1098 | memcpy((*filename), &s->decrypted_filename[s->i], (*filename_size)); |
1099 | (*filename)[(*filename_size)] = '\0'; | 1099 | (*filename)[(*filename_size)] = '\0'; |
1100 | out_free_unlock: | 1100 | out_free_unlock: |
1101 | kfree(s->decrypted_filename); | 1101 | kfree(s->decrypted_filename); |
1102 | out_unlock: | 1102 | out_unlock: |
1103 | mutex_unlock(s->tfm_mutex); | 1103 | mutex_unlock(s->tfm_mutex); |
1104 | out: | 1104 | out: |
1105 | if (rc) { | 1105 | if (rc) { |
1106 | (*packet_size) = 0; | 1106 | (*packet_size) = 0; |
1107 | (*filename_size) = 0; | 1107 | (*filename_size) = 0; |
1108 | (*filename) = NULL; | 1108 | (*filename) = NULL; |
1109 | } | 1109 | } |
1110 | if (auth_tok_key) { | 1110 | if (auth_tok_key) { |
1111 | up_write(&(auth_tok_key->sem)); | 1111 | up_write(&(auth_tok_key->sem)); |
1112 | key_put(auth_tok_key); | 1112 | key_put(auth_tok_key); |
1113 | } | 1113 | } |
1114 | kfree(s); | 1114 | kfree(s); |
1115 | return rc; | 1115 | return rc; |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | static int | 1118 | static int |
1119 | ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok) | 1119 | ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok) |
1120 | { | 1120 | { |
1121 | int rc = 0; | 1121 | int rc = 0; |
1122 | 1122 | ||
1123 | (*sig) = NULL; | 1123 | (*sig) = NULL; |
1124 | switch (auth_tok->token_type) { | 1124 | switch (auth_tok->token_type) { |
1125 | case ECRYPTFS_PASSWORD: | 1125 | case ECRYPTFS_PASSWORD: |
1126 | (*sig) = auth_tok->token.password.signature; | 1126 | (*sig) = auth_tok->token.password.signature; |
1127 | break; | 1127 | break; |
1128 | case ECRYPTFS_PRIVATE_KEY: | 1128 | case ECRYPTFS_PRIVATE_KEY: |
1129 | (*sig) = auth_tok->token.private_key.signature; | 1129 | (*sig) = auth_tok->token.private_key.signature; |
1130 | break; | 1130 | break; |
1131 | default: | 1131 | default: |
1132 | printk(KERN_ERR "Cannot get sig for auth_tok of type [%d]\n", | 1132 | printk(KERN_ERR "Cannot get sig for auth_tok of type [%d]\n", |
1133 | auth_tok->token_type); | 1133 | auth_tok->token_type); |
1134 | rc = -EINVAL; | 1134 | rc = -EINVAL; |
1135 | } | 1135 | } |
1136 | return rc; | 1136 | return rc; |
1137 | } | 1137 | } |
1138 | 1138 | ||
1139 | /** | 1139 | /** |
1140 | * decrypt_pki_encrypted_session_key - Decrypt the session key with the given auth_tok. | 1140 | * decrypt_pki_encrypted_session_key - Decrypt the session key with the given auth_tok. |
1141 | * @auth_tok: The key authentication token used to decrypt the session key | 1141 | * @auth_tok: The key authentication token used to decrypt the session key |
1142 | * @crypt_stat: The cryptographic context | 1142 | * @crypt_stat: The cryptographic context |
1143 | * | 1143 | * |
1144 | * Returns zero on success; non-zero error otherwise. | 1144 | * Returns zero on success; non-zero error otherwise. |
1145 | */ | 1145 | */ |
1146 | static int | 1146 | static int |
1147 | decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, | 1147 | decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, |
1148 | struct ecryptfs_crypt_stat *crypt_stat) | 1148 | struct ecryptfs_crypt_stat *crypt_stat) |
1149 | { | 1149 | { |
1150 | u8 cipher_code = 0; | 1150 | u8 cipher_code = 0; |
1151 | struct ecryptfs_msg_ctx *msg_ctx; | 1151 | struct ecryptfs_msg_ctx *msg_ctx; |
1152 | struct ecryptfs_message *msg = NULL; | 1152 | struct ecryptfs_message *msg = NULL; |
1153 | char *auth_tok_sig; | 1153 | char *auth_tok_sig; |
1154 | char *payload; | 1154 | char *payload; |
1155 | size_t payload_len; | 1155 | size_t payload_len; |
1156 | int rc; | 1156 | int rc; |
1157 | 1157 | ||
1158 | rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok); | 1158 | rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok); |
1159 | if (rc) { | 1159 | if (rc) { |
1160 | printk(KERN_ERR "Unrecognized auth tok type: [%d]\n", | 1160 | printk(KERN_ERR "Unrecognized auth tok type: [%d]\n", |
1161 | auth_tok->token_type); | 1161 | auth_tok->token_type); |
1162 | goto out; | 1162 | goto out; |
1163 | } | 1163 | } |
1164 | rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key), | 1164 | rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key), |
1165 | &payload, &payload_len); | 1165 | &payload, &payload_len); |
1166 | if (rc) { | 1166 | if (rc) { |
1167 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet\n"); | 1167 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet\n"); |
1168 | goto out; | 1168 | goto out; |
1169 | } | 1169 | } |
1170 | rc = ecryptfs_send_message(payload, payload_len, &msg_ctx); | 1170 | rc = ecryptfs_send_message(payload, payload_len, &msg_ctx); |
1171 | if (rc) { | 1171 | if (rc) { |
1172 | ecryptfs_printk(KERN_ERR, "Error sending message to " | 1172 | ecryptfs_printk(KERN_ERR, "Error sending message to " |
1173 | "ecryptfsd\n"); | 1173 | "ecryptfsd\n"); |
1174 | goto out; | 1174 | goto out; |
1175 | } | 1175 | } |
1176 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | 1176 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); |
1177 | if (rc) { | 1177 | if (rc) { |
1178 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 65 packet " | 1178 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 65 packet " |
1179 | "from the user space daemon\n"); | 1179 | "from the user space daemon\n"); |
1180 | rc = -EIO; | 1180 | rc = -EIO; |
1181 | goto out; | 1181 | goto out; |
1182 | } | 1182 | } |
1183 | rc = parse_tag_65_packet(&(auth_tok->session_key), | 1183 | rc = parse_tag_65_packet(&(auth_tok->session_key), |
1184 | &cipher_code, msg); | 1184 | &cipher_code, msg); |
1185 | if (rc) { | 1185 | if (rc) { |
1186 | printk(KERN_ERR "Failed to parse tag 65 packet; rc = [%d]\n", | 1186 | printk(KERN_ERR "Failed to parse tag 65 packet; rc = [%d]\n", |
1187 | rc); | 1187 | rc); |
1188 | goto out; | 1188 | goto out; |
1189 | } | 1189 | } |
1190 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1190 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
1191 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | 1191 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, |
1192 | auth_tok->session_key.decrypted_key_size); | 1192 | auth_tok->session_key.decrypted_key_size); |
1193 | crypt_stat->key_size = auth_tok->session_key.decrypted_key_size; | 1193 | crypt_stat->key_size = auth_tok->session_key.decrypted_key_size; |
1194 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, cipher_code); | 1194 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, cipher_code); |
1195 | if (rc) { | 1195 | if (rc) { |
1196 | ecryptfs_printk(KERN_ERR, "Cipher code [%d] is invalid\n", | 1196 | ecryptfs_printk(KERN_ERR, "Cipher code [%d] is invalid\n", |
1197 | cipher_code) | 1197 | cipher_code) |
1198 | goto out; | 1198 | goto out; |
1199 | } | 1199 | } |
1200 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | 1200 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
1201 | if (ecryptfs_verbosity > 0) { | 1201 | if (ecryptfs_verbosity > 0) { |
1202 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | 1202 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); |
1203 | ecryptfs_dump_hex(crypt_stat->key, | 1203 | ecryptfs_dump_hex(crypt_stat->key, |
1204 | crypt_stat->key_size); | 1204 | crypt_stat->key_size); |
1205 | } | 1205 | } |
1206 | out: | 1206 | out: |
1207 | if (msg) | 1207 | if (msg) |
1208 | kfree(msg); | 1208 | kfree(msg); |
1209 | return rc; | 1209 | return rc; |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | 1212 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) |
1213 | { | 1213 | { |
1214 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 1214 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
1215 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp; | 1215 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp; |
1216 | 1216 | ||
1217 | list_for_each_entry_safe(auth_tok_list_item, auth_tok_list_item_tmp, | 1217 | list_for_each_entry_safe(auth_tok_list_item, auth_tok_list_item_tmp, |
1218 | auth_tok_list_head, list) { | 1218 | auth_tok_list_head, list) { |
1219 | list_del(&auth_tok_list_item->list); | 1219 | list_del(&auth_tok_list_item->list); |
1220 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | 1220 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, |
1221 | auth_tok_list_item); | 1221 | auth_tok_list_item); |
1222 | } | 1222 | } |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | 1225 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; |
1226 | 1226 | ||
1227 | /** | 1227 | /** |
1228 | * parse_tag_1_packet | 1228 | * parse_tag_1_packet |
1229 | * @crypt_stat: The cryptographic context to modify based on packet contents | 1229 | * @crypt_stat: The cryptographic context to modify based on packet contents |
1230 | * @data: The raw bytes of the packet. | 1230 | * @data: The raw bytes of the packet. |
1231 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; | 1231 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; |
1232 | * a new authentication token will be placed at the | 1232 | * a new authentication token will be placed at the |
1233 | * end of this list for this packet. | 1233 | * end of this list for this packet. |
1234 | * @new_auth_tok: Pointer to a pointer to memory that this function | 1234 | * @new_auth_tok: Pointer to a pointer to memory that this function |
1235 | * allocates; sets the memory address of the pointer to | 1235 | * allocates; sets the memory address of the pointer to |
1236 | * NULL on error. This object is added to the | 1236 | * NULL on error. This object is added to the |
1237 | * auth_tok_list. | 1237 | * auth_tok_list. |
1238 | * @packet_size: This function writes the size of the parsed packet | 1238 | * @packet_size: This function writes the size of the parsed packet |
1239 | * into this memory location; zero on error. | 1239 | * into this memory location; zero on error. |
1240 | * @max_packet_size: The maximum allowable packet size | 1240 | * @max_packet_size: The maximum allowable packet size |
1241 | * | 1241 | * |
1242 | * Returns zero on success; non-zero on error. | 1242 | * Returns zero on success; non-zero on error. |
1243 | */ | 1243 | */ |
1244 | static int | 1244 | static int |
1245 | parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | 1245 | parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, |
1246 | unsigned char *data, struct list_head *auth_tok_list, | 1246 | unsigned char *data, struct list_head *auth_tok_list, |
1247 | struct ecryptfs_auth_tok **new_auth_tok, | 1247 | struct ecryptfs_auth_tok **new_auth_tok, |
1248 | size_t *packet_size, size_t max_packet_size) | 1248 | size_t *packet_size, size_t max_packet_size) |
1249 | { | 1249 | { |
1250 | size_t body_size; | 1250 | size_t body_size; |
1251 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 1251 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
1252 | size_t length_size; | 1252 | size_t length_size; |
1253 | int rc = 0; | 1253 | int rc = 0; |
1254 | 1254 | ||
1255 | (*packet_size) = 0; | 1255 | (*packet_size) = 0; |
1256 | (*new_auth_tok) = NULL; | 1256 | (*new_auth_tok) = NULL; |
1257 | /** | 1257 | /** |
1258 | * This format is inspired by OpenPGP; see RFC 2440 | 1258 | * This format is inspired by OpenPGP; see RFC 2440 |
1259 | * packet tag 1 | 1259 | * packet tag 1 |
1260 | * | 1260 | * |
1261 | * Tag 1 identifier (1 byte) | 1261 | * Tag 1 identifier (1 byte) |
1262 | * Max Tag 1 packet size (max 3 bytes) | 1262 | * Max Tag 1 packet size (max 3 bytes) |
1263 | * Version (1 byte) | 1263 | * Version (1 byte) |
1264 | * Key identifier (8 bytes; ECRYPTFS_SIG_SIZE) | 1264 | * Key identifier (8 bytes; ECRYPTFS_SIG_SIZE) |
1265 | * Cipher identifier (1 byte) | 1265 | * Cipher identifier (1 byte) |
1266 | * Encrypted key size (arbitrary) | 1266 | * Encrypted key size (arbitrary) |
1267 | * | 1267 | * |
1268 | * 12 bytes minimum packet size | 1268 | * 12 bytes minimum packet size |
1269 | */ | 1269 | */ |
1270 | if (unlikely(max_packet_size < 12)) { | 1270 | if (unlikely(max_packet_size < 12)) { |
1271 | printk(KERN_ERR "Invalid max packet size; must be >=12\n"); | 1271 | printk(KERN_ERR "Invalid max packet size; must be >=12\n"); |
1272 | rc = -EINVAL; | 1272 | rc = -EINVAL; |
1273 | goto out; | 1273 | goto out; |
1274 | } | 1274 | } |
1275 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { | 1275 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { |
1276 | printk(KERN_ERR "Enter w/ first byte != 0x%.2x\n", | 1276 | printk(KERN_ERR "Enter w/ first byte != 0x%.2x\n", |
1277 | ECRYPTFS_TAG_1_PACKET_TYPE); | 1277 | ECRYPTFS_TAG_1_PACKET_TYPE); |
1278 | rc = -EINVAL; | 1278 | rc = -EINVAL; |
1279 | goto out; | 1279 | goto out; |
1280 | } | 1280 | } |
1281 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 1281 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
1282 | * at end of function upon failure */ | 1282 | * at end of function upon failure */ |
1283 | auth_tok_list_item = | 1283 | auth_tok_list_item = |
1284 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, | 1284 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, |
1285 | GFP_KERNEL); | 1285 | GFP_KERNEL); |
1286 | if (!auth_tok_list_item) { | 1286 | if (!auth_tok_list_item) { |
1287 | printk(KERN_ERR "Unable to allocate memory\n"); | 1287 | printk(KERN_ERR "Unable to allocate memory\n"); |
1288 | rc = -ENOMEM; | 1288 | rc = -ENOMEM; |
1289 | goto out; | 1289 | goto out; |
1290 | } | 1290 | } |
1291 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 1291 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
1292 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, | 1292 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, |
1293 | &length_size); | 1293 | &length_size); |
1294 | if (rc) { | 1294 | if (rc) { |
1295 | printk(KERN_WARNING "Error parsing packet length; " | 1295 | printk(KERN_WARNING "Error parsing packet length; " |
1296 | "rc = [%d]\n", rc); | 1296 | "rc = [%d]\n", rc); |
1297 | goto out_free; | 1297 | goto out_free; |
1298 | } | 1298 | } |
1299 | if (unlikely(body_size < (ECRYPTFS_SIG_SIZE + 2))) { | 1299 | if (unlikely(body_size < (ECRYPTFS_SIG_SIZE + 2))) { |
1300 | printk(KERN_WARNING "Invalid body size ([%td])\n", body_size); | 1300 | printk(KERN_WARNING "Invalid body size ([%td])\n", body_size); |
1301 | rc = -EINVAL; | 1301 | rc = -EINVAL; |
1302 | goto out_free; | 1302 | goto out_free; |
1303 | } | 1303 | } |
1304 | (*packet_size) += length_size; | 1304 | (*packet_size) += length_size; |
1305 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | 1305 | if (unlikely((*packet_size) + body_size > max_packet_size)) { |
1306 | printk(KERN_WARNING "Packet size exceeds max\n"); | 1306 | printk(KERN_WARNING "Packet size exceeds max\n"); |
1307 | rc = -EINVAL; | 1307 | rc = -EINVAL; |
1308 | goto out_free; | 1308 | goto out_free; |
1309 | } | 1309 | } |
1310 | if (unlikely(data[(*packet_size)++] != 0x03)) { | 1310 | if (unlikely(data[(*packet_size)++] != 0x03)) { |
1311 | printk(KERN_WARNING "Unknown version number [%d]\n", | 1311 | printk(KERN_WARNING "Unknown version number [%d]\n", |
1312 | data[(*packet_size) - 1]); | 1312 | data[(*packet_size) - 1]); |
1313 | rc = -EINVAL; | 1313 | rc = -EINVAL; |
1314 | goto out_free; | 1314 | goto out_free; |
1315 | } | 1315 | } |
1316 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, | 1316 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, |
1317 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); | 1317 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); |
1318 | *packet_size += ECRYPTFS_SIG_SIZE; | 1318 | *packet_size += ECRYPTFS_SIG_SIZE; |
1319 | /* This byte is skipped because the kernel does not need to | 1319 | /* This byte is skipped because the kernel does not need to |
1320 | * know which public key encryption algorithm was used */ | 1320 | * know which public key encryption algorithm was used */ |
1321 | (*packet_size)++; | 1321 | (*packet_size)++; |
1322 | (*new_auth_tok)->session_key.encrypted_key_size = | 1322 | (*new_auth_tok)->session_key.encrypted_key_size = |
1323 | body_size - (ECRYPTFS_SIG_SIZE + 2); | 1323 | body_size - (ECRYPTFS_SIG_SIZE + 2); |
1324 | if ((*new_auth_tok)->session_key.encrypted_key_size | 1324 | if ((*new_auth_tok)->session_key.encrypted_key_size |
1325 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | 1325 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { |
1326 | printk(KERN_WARNING "Tag 1 packet contains key larger " | 1326 | printk(KERN_WARNING "Tag 1 packet contains key larger " |
1327 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); | 1327 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); |
1328 | rc = -EINVAL; | 1328 | rc = -EINVAL; |
1329 | goto out; | 1329 | goto out; |
1330 | } | 1330 | } |
1331 | memcpy((*new_auth_tok)->session_key.encrypted_key, | 1331 | memcpy((*new_auth_tok)->session_key.encrypted_key, |
1332 | &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2))); | 1332 | &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2))); |
1333 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; | 1333 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; |
1334 | (*new_auth_tok)->session_key.flags &= | 1334 | (*new_auth_tok)->session_key.flags &= |
1335 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1335 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
1336 | (*new_auth_tok)->session_key.flags |= | 1336 | (*new_auth_tok)->session_key.flags |= |
1337 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | 1337 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; |
1338 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; | 1338 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; |
1339 | (*new_auth_tok)->flags = 0; | 1339 | (*new_auth_tok)->flags = 0; |
1340 | (*new_auth_tok)->session_key.flags &= | 1340 | (*new_auth_tok)->session_key.flags &= |
1341 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | 1341 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); |
1342 | (*new_auth_tok)->session_key.flags &= | 1342 | (*new_auth_tok)->session_key.flags &= |
1343 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | 1343 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); |
1344 | list_add(&auth_tok_list_item->list, auth_tok_list); | 1344 | list_add(&auth_tok_list_item->list, auth_tok_list); |
1345 | goto out; | 1345 | goto out; |
1346 | out_free: | 1346 | out_free: |
1347 | (*new_auth_tok) = NULL; | 1347 | (*new_auth_tok) = NULL; |
1348 | memset(auth_tok_list_item, 0, | 1348 | memset(auth_tok_list_item, 0, |
1349 | sizeof(struct ecryptfs_auth_tok_list_item)); | 1349 | sizeof(struct ecryptfs_auth_tok_list_item)); |
1350 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | 1350 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, |
1351 | auth_tok_list_item); | 1351 | auth_tok_list_item); |
1352 | out: | 1352 | out: |
1353 | if (rc) | 1353 | if (rc) |
1354 | (*packet_size) = 0; | 1354 | (*packet_size) = 0; |
1355 | return rc; | 1355 | return rc; |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | /** | 1358 | /** |
1359 | * parse_tag_3_packet | 1359 | * parse_tag_3_packet |
1360 | * @crypt_stat: The cryptographic context to modify based on packet | 1360 | * @crypt_stat: The cryptographic context to modify based on packet |
1361 | * contents. | 1361 | * contents. |
1362 | * @data: The raw bytes of the packet. | 1362 | * @data: The raw bytes of the packet. |
1363 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; | 1363 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; |
1364 | * a new authentication token will be placed at the end | 1364 | * a new authentication token will be placed at the end |
1365 | * of this list for this packet. | 1365 | * of this list for this packet. |
1366 | * @new_auth_tok: Pointer to a pointer to memory that this function | 1366 | * @new_auth_tok: Pointer to a pointer to memory that this function |
1367 | * allocates; sets the memory address of the pointer to | 1367 | * allocates; sets the memory address of the pointer to |
1368 | * NULL on error. This object is added to the | 1368 | * NULL on error. This object is added to the |
1369 | * auth_tok_list. | 1369 | * auth_tok_list. |
1370 | * @packet_size: This function writes the size of the parsed packet | 1370 | * @packet_size: This function writes the size of the parsed packet |
1371 | * into this memory location; zero on error. | 1371 | * into this memory location; zero on error. |
1372 | * @max_packet_size: maximum number of bytes to parse | 1372 | * @max_packet_size: maximum number of bytes to parse |
1373 | * | 1373 | * |
1374 | * Returns zero on success; non-zero on error. | 1374 | * Returns zero on success; non-zero on error. |
1375 | */ | 1375 | */ |
1376 | static int | 1376 | static int |
1377 | parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | 1377 | parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, |
1378 | unsigned char *data, struct list_head *auth_tok_list, | 1378 | unsigned char *data, struct list_head *auth_tok_list, |
1379 | struct ecryptfs_auth_tok **new_auth_tok, | 1379 | struct ecryptfs_auth_tok **new_auth_tok, |
1380 | size_t *packet_size, size_t max_packet_size) | 1380 | size_t *packet_size, size_t max_packet_size) |
1381 | { | 1381 | { |
1382 | size_t body_size; | 1382 | size_t body_size; |
1383 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 1383 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
1384 | size_t length_size; | 1384 | size_t length_size; |
1385 | int rc = 0; | 1385 | int rc = 0; |
1386 | 1386 | ||
1387 | (*packet_size) = 0; | 1387 | (*packet_size) = 0; |
1388 | (*new_auth_tok) = NULL; | 1388 | (*new_auth_tok) = NULL; |
1389 | /** | 1389 | /** |
1390 | *This format is inspired by OpenPGP; see RFC 2440 | 1390 | *This format is inspired by OpenPGP; see RFC 2440 |
1391 | * packet tag 3 | 1391 | * packet tag 3 |
1392 | * | 1392 | * |
1393 | * Tag 3 identifier (1 byte) | 1393 | * Tag 3 identifier (1 byte) |
1394 | * Max Tag 3 packet size (max 3 bytes) | 1394 | * Max Tag 3 packet size (max 3 bytes) |
1395 | * Version (1 byte) | 1395 | * Version (1 byte) |
1396 | * Cipher code (1 byte) | 1396 | * Cipher code (1 byte) |
1397 | * S2K specifier (1 byte) | 1397 | * S2K specifier (1 byte) |
1398 | * Hash identifier (1 byte) | 1398 | * Hash identifier (1 byte) |
1399 | * Salt (ECRYPTFS_SALT_SIZE) | 1399 | * Salt (ECRYPTFS_SALT_SIZE) |
1400 | * Hash iterations (1 byte) | 1400 | * Hash iterations (1 byte) |
1401 | * Encrypted key (arbitrary) | 1401 | * Encrypted key (arbitrary) |
1402 | * | 1402 | * |
1403 | * (ECRYPTFS_SALT_SIZE + 7) minimum packet size | 1403 | * (ECRYPTFS_SALT_SIZE + 7) minimum packet size |
1404 | */ | 1404 | */ |
1405 | if (max_packet_size < (ECRYPTFS_SALT_SIZE + 7)) { | 1405 | if (max_packet_size < (ECRYPTFS_SALT_SIZE + 7)) { |
1406 | printk(KERN_ERR "Max packet size too large\n"); | 1406 | printk(KERN_ERR "Max packet size too large\n"); |
1407 | rc = -EINVAL; | 1407 | rc = -EINVAL; |
1408 | goto out; | 1408 | goto out; |
1409 | } | 1409 | } |
1410 | if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) { | 1410 | if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) { |
1411 | printk(KERN_ERR "First byte != 0x%.2x; invalid packet\n", | 1411 | printk(KERN_ERR "First byte != 0x%.2x; invalid packet\n", |
1412 | ECRYPTFS_TAG_3_PACKET_TYPE); | 1412 | ECRYPTFS_TAG_3_PACKET_TYPE); |
1413 | rc = -EINVAL; | 1413 | rc = -EINVAL; |
1414 | goto out; | 1414 | goto out; |
1415 | } | 1415 | } |
1416 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 1416 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
1417 | * at end of function upon failure */ | 1417 | * at end of function upon failure */ |
1418 | auth_tok_list_item = | 1418 | auth_tok_list_item = |
1419 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); | 1419 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); |
1420 | if (!auth_tok_list_item) { | 1420 | if (!auth_tok_list_item) { |
1421 | printk(KERN_ERR "Unable to allocate memory\n"); | 1421 | printk(KERN_ERR "Unable to allocate memory\n"); |
1422 | rc = -ENOMEM; | 1422 | rc = -ENOMEM; |
1423 | goto out; | 1423 | goto out; |
1424 | } | 1424 | } |
1425 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 1425 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
1426 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, | 1426 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, |
1427 | &length_size); | 1427 | &length_size); |
1428 | if (rc) { | 1428 | if (rc) { |
1429 | printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n", | 1429 | printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n", |
1430 | rc); | 1430 | rc); |
1431 | goto out_free; | 1431 | goto out_free; |
1432 | } | 1432 | } |
1433 | if (unlikely(body_size < (ECRYPTFS_SALT_SIZE + 5))) { | 1433 | if (unlikely(body_size < (ECRYPTFS_SALT_SIZE + 5))) { |
1434 | printk(KERN_WARNING "Invalid body size ([%td])\n", body_size); | 1434 | printk(KERN_WARNING "Invalid body size ([%td])\n", body_size); |
1435 | rc = -EINVAL; | 1435 | rc = -EINVAL; |
1436 | goto out_free; | 1436 | goto out_free; |
1437 | } | 1437 | } |
1438 | (*packet_size) += length_size; | 1438 | (*packet_size) += length_size; |
1439 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | 1439 | if (unlikely((*packet_size) + body_size > max_packet_size)) { |
1440 | printk(KERN_ERR "Packet size exceeds max\n"); | 1440 | printk(KERN_ERR "Packet size exceeds max\n"); |
1441 | rc = -EINVAL; | 1441 | rc = -EINVAL; |
1442 | goto out_free; | 1442 | goto out_free; |
1443 | } | 1443 | } |
1444 | (*new_auth_tok)->session_key.encrypted_key_size = | 1444 | (*new_auth_tok)->session_key.encrypted_key_size = |
1445 | (body_size - (ECRYPTFS_SALT_SIZE + 5)); | 1445 | (body_size - (ECRYPTFS_SALT_SIZE + 5)); |
1446 | if ((*new_auth_tok)->session_key.encrypted_key_size | 1446 | if ((*new_auth_tok)->session_key.encrypted_key_size |
1447 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | 1447 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { |
1448 | printk(KERN_WARNING "Tag 3 packet contains key larger " | 1448 | printk(KERN_WARNING "Tag 3 packet contains key larger " |
1449 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n"); | 1449 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n"); |
1450 | rc = -EINVAL; | 1450 | rc = -EINVAL; |
1451 | goto out_free; | 1451 | goto out_free; |
1452 | } | 1452 | } |
1453 | if (unlikely(data[(*packet_size)++] != 0x04)) { | 1453 | if (unlikely(data[(*packet_size)++] != 0x04)) { |
1454 | printk(KERN_WARNING "Unknown version number [%d]\n", | 1454 | printk(KERN_WARNING "Unknown version number [%d]\n", |
1455 | data[(*packet_size) - 1]); | 1455 | data[(*packet_size) - 1]); |
1456 | rc = -EINVAL; | 1456 | rc = -EINVAL; |
1457 | goto out_free; | 1457 | goto out_free; |
1458 | } | 1458 | } |
1459 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, | 1459 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, |
1460 | (u16)data[(*packet_size)]); | 1460 | (u16)data[(*packet_size)]); |
1461 | if (rc) | 1461 | if (rc) |
1462 | goto out_free; | 1462 | goto out_free; |
1463 | /* A little extra work to differentiate among the AES key | 1463 | /* A little extra work to differentiate among the AES key |
1464 | * sizes; see RFC2440 */ | 1464 | * sizes; see RFC2440 */ |
1465 | switch(data[(*packet_size)++]) { | 1465 | switch(data[(*packet_size)++]) { |
1466 | case RFC2440_CIPHER_AES_192: | 1466 | case RFC2440_CIPHER_AES_192: |
1467 | crypt_stat->key_size = 24; | 1467 | crypt_stat->key_size = 24; |
1468 | break; | 1468 | break; |
1469 | default: | 1469 | default: |
1470 | crypt_stat->key_size = | 1470 | crypt_stat->key_size = |
1471 | (*new_auth_tok)->session_key.encrypted_key_size; | 1471 | (*new_auth_tok)->session_key.encrypted_key_size; |
1472 | } | 1472 | } |
1473 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | 1473 | rc = ecryptfs_init_crypt_ctx(crypt_stat); |
1474 | if (rc) | 1474 | if (rc) |
1475 | goto out_free; | 1475 | goto out_free; |
1476 | if (unlikely(data[(*packet_size)++] != 0x03)) { | 1476 | if (unlikely(data[(*packet_size)++] != 0x03)) { |
1477 | printk(KERN_WARNING "Only S2K ID 3 is currently supported\n"); | 1477 | printk(KERN_WARNING "Only S2K ID 3 is currently supported\n"); |
1478 | rc = -ENOSYS; | 1478 | rc = -ENOSYS; |
1479 | goto out_free; | 1479 | goto out_free; |
1480 | } | 1480 | } |
1481 | /* TODO: finish the hash mapping */ | 1481 | /* TODO: finish the hash mapping */ |
1482 | switch (data[(*packet_size)++]) { | 1482 | switch (data[(*packet_size)++]) { |
1483 | case 0x01: /* See RFC2440 for these numbers and their mappings */ | 1483 | case 0x01: /* See RFC2440 for these numbers and their mappings */ |
1484 | /* Choose MD5 */ | 1484 | /* Choose MD5 */ |
1485 | memcpy((*new_auth_tok)->token.password.salt, | 1485 | memcpy((*new_auth_tok)->token.password.salt, |
1486 | &data[(*packet_size)], ECRYPTFS_SALT_SIZE); | 1486 | &data[(*packet_size)], ECRYPTFS_SALT_SIZE); |
1487 | (*packet_size) += ECRYPTFS_SALT_SIZE; | 1487 | (*packet_size) += ECRYPTFS_SALT_SIZE; |
1488 | /* This conversion was taken straight from RFC2440 */ | 1488 | /* This conversion was taken straight from RFC2440 */ |
1489 | (*new_auth_tok)->token.password.hash_iterations = | 1489 | (*new_auth_tok)->token.password.hash_iterations = |
1490 | ((u32) 16 + (data[(*packet_size)] & 15)) | 1490 | ((u32) 16 + (data[(*packet_size)] & 15)) |
1491 | << ((data[(*packet_size)] >> 4) + 6); | 1491 | << ((data[(*packet_size)] >> 4) + 6); |
1492 | (*packet_size)++; | 1492 | (*packet_size)++; |
1493 | /* Friendly reminder: | 1493 | /* Friendly reminder: |
1494 | * (*new_auth_tok)->session_key.encrypted_key_size = | 1494 | * (*new_auth_tok)->session_key.encrypted_key_size = |
1495 | * (body_size - (ECRYPTFS_SALT_SIZE + 5)); */ | 1495 | * (body_size - (ECRYPTFS_SALT_SIZE + 5)); */ |
1496 | memcpy((*new_auth_tok)->session_key.encrypted_key, | 1496 | memcpy((*new_auth_tok)->session_key.encrypted_key, |
1497 | &data[(*packet_size)], | 1497 | &data[(*packet_size)], |
1498 | (*new_auth_tok)->session_key.encrypted_key_size); | 1498 | (*new_auth_tok)->session_key.encrypted_key_size); |
1499 | (*packet_size) += | 1499 | (*packet_size) += |
1500 | (*new_auth_tok)->session_key.encrypted_key_size; | 1500 | (*new_auth_tok)->session_key.encrypted_key_size; |
1501 | (*new_auth_tok)->session_key.flags &= | 1501 | (*new_auth_tok)->session_key.flags &= |
1502 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1502 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
1503 | (*new_auth_tok)->session_key.flags |= | 1503 | (*new_auth_tok)->session_key.flags |= |
1504 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | 1504 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; |
1505 | (*new_auth_tok)->token.password.hash_algo = 0x01; /* MD5 */ | 1505 | (*new_auth_tok)->token.password.hash_algo = 0x01; /* MD5 */ |
1506 | break; | 1506 | break; |
1507 | default: | 1507 | default: |
1508 | ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: " | 1508 | ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: " |
1509 | "[%d]\n", data[(*packet_size) - 1]); | 1509 | "[%d]\n", data[(*packet_size) - 1]); |
1510 | rc = -ENOSYS; | 1510 | rc = -ENOSYS; |
1511 | goto out_free; | 1511 | goto out_free; |
1512 | } | 1512 | } |
1513 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; | 1513 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; |
1514 | /* TODO: Parametarize; we might actually want userspace to | 1514 | /* TODO: Parametarize; we might actually want userspace to |
1515 | * decrypt the session key. */ | 1515 | * decrypt the session key. */ |
1516 | (*new_auth_tok)->session_key.flags &= | 1516 | (*new_auth_tok)->session_key.flags &= |
1517 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | 1517 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); |
1518 | (*new_auth_tok)->session_key.flags &= | 1518 | (*new_auth_tok)->session_key.flags &= |
1519 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | 1519 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); |
1520 | list_add(&auth_tok_list_item->list, auth_tok_list); | 1520 | list_add(&auth_tok_list_item->list, auth_tok_list); |
1521 | goto out; | 1521 | goto out; |
1522 | out_free: | 1522 | out_free: |
1523 | (*new_auth_tok) = NULL; | 1523 | (*new_auth_tok) = NULL; |
1524 | memset(auth_tok_list_item, 0, | 1524 | memset(auth_tok_list_item, 0, |
1525 | sizeof(struct ecryptfs_auth_tok_list_item)); | 1525 | sizeof(struct ecryptfs_auth_tok_list_item)); |
1526 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | 1526 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, |
1527 | auth_tok_list_item); | 1527 | auth_tok_list_item); |
1528 | out: | 1528 | out: |
1529 | if (rc) | 1529 | if (rc) |
1530 | (*packet_size) = 0; | 1530 | (*packet_size) = 0; |
1531 | return rc; | 1531 | return rc; |
1532 | } | 1532 | } |
1533 | 1533 | ||
1534 | /** | 1534 | /** |
1535 | * parse_tag_11_packet | 1535 | * parse_tag_11_packet |
1536 | * @data: The raw bytes of the packet | 1536 | * @data: The raw bytes of the packet |
1537 | * @contents: This function writes the data contents of the literal | 1537 | * @contents: This function writes the data contents of the literal |
1538 | * packet into this memory location | 1538 | * packet into this memory location |
1539 | * @max_contents_bytes: The maximum number of bytes that this function | 1539 | * @max_contents_bytes: The maximum number of bytes that this function |
1540 | * is allowed to write into contents | 1540 | * is allowed to write into contents |
1541 | * @tag_11_contents_size: This function writes the size of the parsed | 1541 | * @tag_11_contents_size: This function writes the size of the parsed |
1542 | * contents into this memory location; zero on | 1542 | * contents into this memory location; zero on |
1543 | * error | 1543 | * error |
1544 | * @packet_size: This function writes the size of the parsed packet | 1544 | * @packet_size: This function writes the size of the parsed packet |
1545 | * into this memory location; zero on error | 1545 | * into this memory location; zero on error |
1546 | * @max_packet_size: maximum number of bytes to parse | 1546 | * @max_packet_size: maximum number of bytes to parse |
1547 | * | 1547 | * |
1548 | * Returns zero on success; non-zero on error. | 1548 | * Returns zero on success; non-zero on error. |
1549 | */ | 1549 | */ |
1550 | static int | 1550 | static int |
1551 | parse_tag_11_packet(unsigned char *data, unsigned char *contents, | 1551 | parse_tag_11_packet(unsigned char *data, unsigned char *contents, |
1552 | size_t max_contents_bytes, size_t *tag_11_contents_size, | 1552 | size_t max_contents_bytes, size_t *tag_11_contents_size, |
1553 | size_t *packet_size, size_t max_packet_size) | 1553 | size_t *packet_size, size_t max_packet_size) |
1554 | { | 1554 | { |
1555 | size_t body_size; | 1555 | size_t body_size; |
1556 | size_t length_size; | 1556 | size_t length_size; |
1557 | int rc = 0; | 1557 | int rc = 0; |
1558 | 1558 | ||
1559 | (*packet_size) = 0; | 1559 | (*packet_size) = 0; |
1560 | (*tag_11_contents_size) = 0; | 1560 | (*tag_11_contents_size) = 0; |
1561 | /* This format is inspired by OpenPGP; see RFC 2440 | 1561 | /* This format is inspired by OpenPGP; see RFC 2440 |
1562 | * packet tag 11 | 1562 | * packet tag 11 |
1563 | * | 1563 | * |
1564 | * Tag 11 identifier (1 byte) | 1564 | * Tag 11 identifier (1 byte) |
1565 | * Max Tag 11 packet size (max 3 bytes) | 1565 | * Max Tag 11 packet size (max 3 bytes) |
1566 | * Binary format specifier (1 byte) | 1566 | * Binary format specifier (1 byte) |
1567 | * Filename length (1 byte) | 1567 | * Filename length (1 byte) |
1568 | * Filename ("_CONSOLE") (8 bytes) | 1568 | * Filename ("_CONSOLE") (8 bytes) |
1569 | * Modification date (4 bytes) | 1569 | * Modification date (4 bytes) |
1570 | * Literal data (arbitrary) | 1570 | * Literal data (arbitrary) |
1571 | * | 1571 | * |
1572 | * We need at least 16 bytes of data for the packet to even be | 1572 | * We need at least 16 bytes of data for the packet to even be |
1573 | * valid. | 1573 | * valid. |
1574 | */ | 1574 | */ |
1575 | if (max_packet_size < 16) { | 1575 | if (max_packet_size < 16) { |
1576 | printk(KERN_ERR "Maximum packet size too small\n"); | 1576 | printk(KERN_ERR "Maximum packet size too small\n"); |
1577 | rc = -EINVAL; | 1577 | rc = -EINVAL; |
1578 | goto out; | 1578 | goto out; |
1579 | } | 1579 | } |
1580 | if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) { | 1580 | if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) { |
1581 | printk(KERN_WARNING "Invalid tag 11 packet format\n"); | 1581 | printk(KERN_WARNING "Invalid tag 11 packet format\n"); |
1582 | rc = -EINVAL; | 1582 | rc = -EINVAL; |
1583 | goto out; | 1583 | goto out; |
1584 | } | 1584 | } |
1585 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, | 1585 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, |
1586 | &length_size); | 1586 | &length_size); |
1587 | if (rc) { | 1587 | if (rc) { |
1588 | printk(KERN_WARNING "Invalid tag 11 packet format\n"); | 1588 | printk(KERN_WARNING "Invalid tag 11 packet format\n"); |
1589 | goto out; | 1589 | goto out; |
1590 | } | 1590 | } |
1591 | if (body_size < 14) { | 1591 | if (body_size < 14) { |
1592 | printk(KERN_WARNING "Invalid body size ([%td])\n", body_size); | 1592 | printk(KERN_WARNING "Invalid body size ([%td])\n", body_size); |
1593 | rc = -EINVAL; | 1593 | rc = -EINVAL; |
1594 | goto out; | 1594 | goto out; |
1595 | } | 1595 | } |
1596 | (*packet_size) += length_size; | 1596 | (*packet_size) += length_size; |
1597 | (*tag_11_contents_size) = (body_size - 14); | 1597 | (*tag_11_contents_size) = (body_size - 14); |
1598 | if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) { | 1598 | if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) { |
1599 | printk(KERN_ERR "Packet size exceeds max\n"); | 1599 | printk(KERN_ERR "Packet size exceeds max\n"); |
1600 | rc = -EINVAL; | 1600 | rc = -EINVAL; |
1601 | goto out; | 1601 | goto out; |
1602 | } | 1602 | } |
1603 | if (unlikely((*tag_11_contents_size) > max_contents_bytes)) { | 1603 | if (unlikely((*tag_11_contents_size) > max_contents_bytes)) { |
1604 | printk(KERN_ERR "Literal data section in tag 11 packet exceeds " | 1604 | printk(KERN_ERR "Literal data section in tag 11 packet exceeds " |
1605 | "expected size\n"); | 1605 | "expected size\n"); |
1606 | rc = -EINVAL; | 1606 | rc = -EINVAL; |
1607 | goto out; | 1607 | goto out; |
1608 | } | 1608 | } |
1609 | if (data[(*packet_size)++] != 0x62) { | 1609 | if (data[(*packet_size)++] != 0x62) { |
1610 | printk(KERN_WARNING "Unrecognizable packet\n"); | 1610 | printk(KERN_WARNING "Unrecognizable packet\n"); |
1611 | rc = -EINVAL; | 1611 | rc = -EINVAL; |
1612 | goto out; | 1612 | goto out; |
1613 | } | 1613 | } |
1614 | if (data[(*packet_size)++] != 0x08) { | 1614 | if (data[(*packet_size)++] != 0x08) { |
1615 | printk(KERN_WARNING "Unrecognizable packet\n"); | 1615 | printk(KERN_WARNING "Unrecognizable packet\n"); |
1616 | rc = -EINVAL; | 1616 | rc = -EINVAL; |
1617 | goto out; | 1617 | goto out; |
1618 | } | 1618 | } |
1619 | (*packet_size) += 12; /* Ignore filename and modification date */ | 1619 | (*packet_size) += 12; /* Ignore filename and modification date */ |
1620 | memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size)); | 1620 | memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size)); |
1621 | (*packet_size) += (*tag_11_contents_size); | 1621 | (*packet_size) += (*tag_11_contents_size); |
1622 | out: | 1622 | out: |
1623 | if (rc) { | 1623 | if (rc) { |
1624 | (*packet_size) = 0; | 1624 | (*packet_size) = 0; |
1625 | (*tag_11_contents_size) = 0; | 1625 | (*tag_11_contents_size) = 0; |
1626 | } | 1626 | } |
1627 | return rc; | 1627 | return rc; |
1628 | } | 1628 | } |
1629 | 1629 | ||
1630 | int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | 1630 | int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, |
1631 | struct ecryptfs_auth_tok **auth_tok, | 1631 | struct ecryptfs_auth_tok **auth_tok, |
1632 | char *sig) | 1632 | char *sig) |
1633 | { | 1633 | { |
1634 | int rc = 0; | 1634 | int rc = 0; |
1635 | 1635 | ||
1636 | (*auth_tok_key) = request_key(&key_type_user, sig, NULL); | 1636 | (*auth_tok_key) = request_key(&key_type_user, sig, NULL); |
1637 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { | 1637 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { |
1638 | (*auth_tok_key) = ecryptfs_get_encrypted_key(sig); | 1638 | (*auth_tok_key) = ecryptfs_get_encrypted_key(sig); |
1639 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { | 1639 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { |
1640 | printk(KERN_ERR "Could not find key with description: [%s]\n", | 1640 | printk(KERN_ERR "Could not find key with description: [%s]\n", |
1641 | sig); | 1641 | sig); |
1642 | rc = process_request_key_err(PTR_ERR(*auth_tok_key)); | 1642 | rc = process_request_key_err(PTR_ERR(*auth_tok_key)); |
1643 | (*auth_tok_key) = NULL; | 1643 | (*auth_tok_key) = NULL; |
1644 | goto out; | 1644 | goto out; |
1645 | } | 1645 | } |
1646 | } | 1646 | } |
1647 | down_write(&(*auth_tok_key)->sem); | 1647 | down_write(&(*auth_tok_key)->sem); |
1648 | rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); | 1648 | rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); |
1649 | if (rc) { | 1649 | if (rc) { |
1650 | up_write(&(*auth_tok_key)->sem); | 1650 | up_write(&(*auth_tok_key)->sem); |
1651 | key_put(*auth_tok_key); | 1651 | key_put(*auth_tok_key); |
1652 | (*auth_tok_key) = NULL; | 1652 | (*auth_tok_key) = NULL; |
1653 | goto out; | 1653 | goto out; |
1654 | } | 1654 | } |
1655 | out: | 1655 | out: |
1656 | return rc; | 1656 | return rc; |
1657 | } | 1657 | } |
1658 | 1658 | ||
1659 | /** | 1659 | /** |
1660 | * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok. | 1660 | * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok. |
1661 | * @auth_tok: The passphrase authentication token to use to encrypt the FEK | 1661 | * @auth_tok: The passphrase authentication token to use to encrypt the FEK |
1662 | * @crypt_stat: The cryptographic context | 1662 | * @crypt_stat: The cryptographic context |
1663 | * | 1663 | * |
1664 | * Returns zero on success; non-zero error otherwise | 1664 | * Returns zero on success; non-zero error otherwise |
1665 | */ | 1665 | */ |
1666 | static int | 1666 | static int |
1667 | decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, | 1667 | decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, |
1668 | struct ecryptfs_crypt_stat *crypt_stat) | 1668 | struct ecryptfs_crypt_stat *crypt_stat) |
1669 | { | 1669 | { |
1670 | struct scatterlist dst_sg[2]; | 1670 | struct scatterlist dst_sg[2]; |
1671 | struct scatterlist src_sg[2]; | 1671 | struct scatterlist src_sg[2]; |
1672 | struct mutex *tfm_mutex; | 1672 | struct mutex *tfm_mutex; |
1673 | struct blkcipher_desc desc = { | 1673 | struct blkcipher_desc desc = { |
1674 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | 1674 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP |
1675 | }; | 1675 | }; |
1676 | int rc = 0; | 1676 | int rc = 0; |
1677 | 1677 | ||
1678 | if (unlikely(ecryptfs_verbosity > 0)) { | 1678 | if (unlikely(ecryptfs_verbosity > 0)) { |
1679 | ecryptfs_printk( | 1679 | ecryptfs_printk( |
1680 | KERN_DEBUG, "Session key encryption key (size [%d]):\n", | 1680 | KERN_DEBUG, "Session key encryption key (size [%d]):\n", |
1681 | auth_tok->token.password.session_key_encryption_key_bytes); | 1681 | auth_tok->token.password.session_key_encryption_key_bytes); |
1682 | ecryptfs_dump_hex( | 1682 | ecryptfs_dump_hex( |
1683 | auth_tok->token.password.session_key_encryption_key, | 1683 | auth_tok->token.password.session_key_encryption_key, |
1684 | auth_tok->token.password.session_key_encryption_key_bytes); | 1684 | auth_tok->token.password.session_key_encryption_key_bytes); |
1685 | } | 1685 | } |
1686 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, | 1686 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, |
1687 | crypt_stat->cipher); | 1687 | crypt_stat->cipher); |
1688 | if (unlikely(rc)) { | 1688 | if (unlikely(rc)) { |
1689 | printk(KERN_ERR "Internal error whilst attempting to get " | 1689 | printk(KERN_ERR "Internal error whilst attempting to get " |
1690 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", | 1690 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", |
1691 | crypt_stat->cipher, rc); | 1691 | crypt_stat->cipher, rc); |
1692 | goto out; | 1692 | goto out; |
1693 | } | 1693 | } |
1694 | rc = virt_to_scatterlist(auth_tok->session_key.encrypted_key, | 1694 | rc = virt_to_scatterlist(auth_tok->session_key.encrypted_key, |
1695 | auth_tok->session_key.encrypted_key_size, | 1695 | auth_tok->session_key.encrypted_key_size, |
1696 | src_sg, 2); | 1696 | src_sg, 2); |
1697 | if (rc < 1 || rc > 2) { | 1697 | if (rc < 1 || rc > 2) { |
1698 | printk(KERN_ERR "Internal error whilst attempting to convert " | 1698 | printk(KERN_ERR "Internal error whilst attempting to convert " |
1699 | "auth_tok->session_key.encrypted_key to scatterlist; " | 1699 | "auth_tok->session_key.encrypted_key to scatterlist; " |
1700 | "expected rc = 1; got rc = [%d]. " | 1700 | "expected rc = 1; got rc = [%d]. " |
1701 | "auth_tok->session_key.encrypted_key_size = [%d]\n", rc, | 1701 | "auth_tok->session_key.encrypted_key_size = [%d]\n", rc, |
1702 | auth_tok->session_key.encrypted_key_size); | 1702 | auth_tok->session_key.encrypted_key_size); |
1703 | goto out; | 1703 | goto out; |
1704 | } | 1704 | } |
1705 | auth_tok->session_key.decrypted_key_size = | 1705 | auth_tok->session_key.decrypted_key_size = |
1706 | auth_tok->session_key.encrypted_key_size; | 1706 | auth_tok->session_key.encrypted_key_size; |
1707 | rc = virt_to_scatterlist(auth_tok->session_key.decrypted_key, | 1707 | rc = virt_to_scatterlist(auth_tok->session_key.decrypted_key, |
1708 | auth_tok->session_key.decrypted_key_size, | 1708 | auth_tok->session_key.decrypted_key_size, |
1709 | dst_sg, 2); | 1709 | dst_sg, 2); |
1710 | if (rc < 1 || rc > 2) { | 1710 | if (rc < 1 || rc > 2) { |
1711 | printk(KERN_ERR "Internal error whilst attempting to convert " | 1711 | printk(KERN_ERR "Internal error whilst attempting to convert " |
1712 | "auth_tok->session_key.decrypted_key to scatterlist; " | 1712 | "auth_tok->session_key.decrypted_key to scatterlist; " |
1713 | "expected rc = 1; got rc = [%d]\n", rc); | 1713 | "expected rc = 1; got rc = [%d]\n", rc); |
1714 | goto out; | 1714 | goto out; |
1715 | } | 1715 | } |
1716 | mutex_lock(tfm_mutex); | 1716 | mutex_lock(tfm_mutex); |
1717 | rc = crypto_blkcipher_setkey( | 1717 | rc = crypto_blkcipher_setkey( |
1718 | desc.tfm, auth_tok->token.password.session_key_encryption_key, | 1718 | desc.tfm, auth_tok->token.password.session_key_encryption_key, |
1719 | crypt_stat->key_size); | 1719 | crypt_stat->key_size); |
1720 | if (unlikely(rc < 0)) { | 1720 | if (unlikely(rc < 0)) { |
1721 | mutex_unlock(tfm_mutex); | 1721 | mutex_unlock(tfm_mutex); |
1722 | printk(KERN_ERR "Error setting key for crypto context\n"); | 1722 | printk(KERN_ERR "Error setting key for crypto context\n"); |
1723 | rc = -EINVAL; | 1723 | rc = -EINVAL; |
1724 | goto out; | 1724 | goto out; |
1725 | } | 1725 | } |
1726 | rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, | 1726 | rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, |
1727 | auth_tok->session_key.encrypted_key_size); | 1727 | auth_tok->session_key.encrypted_key_size); |
1728 | mutex_unlock(tfm_mutex); | 1728 | mutex_unlock(tfm_mutex); |
1729 | if (unlikely(rc)) { | 1729 | if (unlikely(rc)) { |
1730 | printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); | 1730 | printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); |
1731 | goto out; | 1731 | goto out; |
1732 | } | 1732 | } |
1733 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1733 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
1734 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | 1734 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, |
1735 | auth_tok->session_key.decrypted_key_size); | 1735 | auth_tok->session_key.decrypted_key_size); |
1736 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | 1736 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
1737 | if (unlikely(ecryptfs_verbosity > 0)) { | 1737 | if (unlikely(ecryptfs_verbosity > 0)) { |
1738 | ecryptfs_printk(KERN_DEBUG, "FEK of size [%zd]:\n", | 1738 | ecryptfs_printk(KERN_DEBUG, "FEK of size [%zd]:\n", |
1739 | crypt_stat->key_size); | 1739 | crypt_stat->key_size); |
1740 | ecryptfs_dump_hex(crypt_stat->key, | 1740 | ecryptfs_dump_hex(crypt_stat->key, |
1741 | crypt_stat->key_size); | 1741 | crypt_stat->key_size); |
1742 | } | 1742 | } |
1743 | out: | 1743 | out: |
1744 | return rc; | 1744 | return rc; |
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | /** | 1747 | /** |
1748 | * ecryptfs_parse_packet_set | 1748 | * ecryptfs_parse_packet_set |
1749 | * @crypt_stat: The cryptographic context | 1749 | * @crypt_stat: The cryptographic context |
1750 | * @src: Virtual address of region of memory containing the packets | 1750 | * @src: Virtual address of region of memory containing the packets |
1751 | * @ecryptfs_dentry: The eCryptfs dentry associated with the packet set | 1751 | * @ecryptfs_dentry: The eCryptfs dentry associated with the packet set |
1752 | * | 1752 | * |
1753 | * Get crypt_stat to have the file's session key if the requisite key | 1753 | * Get crypt_stat to have the file's session key if the requisite key |
1754 | * is available to decrypt the session key. | 1754 | * is available to decrypt the session key. |
1755 | * | 1755 | * |
1756 | * Returns Zero if a valid authentication token was retrieved and | 1756 | * Returns Zero if a valid authentication token was retrieved and |
1757 | * processed; negative value for file not encrypted or for error | 1757 | * processed; negative value for file not encrypted or for error |
1758 | * conditions. | 1758 | * conditions. |
1759 | */ | 1759 | */ |
1760 | int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | 1760 | int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, |
1761 | unsigned char *src, | 1761 | unsigned char *src, |
1762 | struct dentry *ecryptfs_dentry) | 1762 | struct dentry *ecryptfs_dentry) |
1763 | { | 1763 | { |
1764 | size_t i = 0; | 1764 | size_t i = 0; |
1765 | size_t found_auth_tok; | 1765 | size_t found_auth_tok; |
1766 | size_t next_packet_is_auth_tok_packet; | 1766 | size_t next_packet_is_auth_tok_packet; |
1767 | struct list_head auth_tok_list; | 1767 | struct list_head auth_tok_list; |
1768 | struct ecryptfs_auth_tok *matching_auth_tok; | 1768 | struct ecryptfs_auth_tok *matching_auth_tok; |
1769 | struct ecryptfs_auth_tok *candidate_auth_tok; | 1769 | struct ecryptfs_auth_tok *candidate_auth_tok; |
1770 | char *candidate_auth_tok_sig; | 1770 | char *candidate_auth_tok_sig; |
1771 | size_t packet_size; | 1771 | size_t packet_size; |
1772 | struct ecryptfs_auth_tok *new_auth_tok; | 1772 | struct ecryptfs_auth_tok *new_auth_tok; |
1773 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; | 1773 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; |
1774 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 1774 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
1775 | size_t tag_11_contents_size; | 1775 | size_t tag_11_contents_size; |
1776 | size_t tag_11_packet_size; | 1776 | size_t tag_11_packet_size; |
1777 | struct key *auth_tok_key = NULL; | 1777 | struct key *auth_tok_key = NULL; |
1778 | int rc = 0; | 1778 | int rc = 0; |
1779 | 1779 | ||
1780 | INIT_LIST_HEAD(&auth_tok_list); | 1780 | INIT_LIST_HEAD(&auth_tok_list); |
1781 | /* Parse the header to find as many packets as we can; these will be | 1781 | /* Parse the header to find as many packets as we can; these will be |
1782 | * added the our &auth_tok_list */ | 1782 | * added the our &auth_tok_list */ |
1783 | next_packet_is_auth_tok_packet = 1; | 1783 | next_packet_is_auth_tok_packet = 1; |
1784 | while (next_packet_is_auth_tok_packet) { | 1784 | while (next_packet_is_auth_tok_packet) { |
1785 | size_t max_packet_size = ((PAGE_CACHE_SIZE - 8) - i); | 1785 | size_t max_packet_size = ((PAGE_CACHE_SIZE - 8) - i); |
1786 | 1786 | ||
1787 | switch (src[i]) { | 1787 | switch (src[i]) { |
1788 | case ECRYPTFS_TAG_3_PACKET_TYPE: | 1788 | case ECRYPTFS_TAG_3_PACKET_TYPE: |
1789 | rc = parse_tag_3_packet(crypt_stat, | 1789 | rc = parse_tag_3_packet(crypt_stat, |
1790 | (unsigned char *)&src[i], | 1790 | (unsigned char *)&src[i], |
1791 | &auth_tok_list, &new_auth_tok, | 1791 | &auth_tok_list, &new_auth_tok, |
1792 | &packet_size, max_packet_size); | 1792 | &packet_size, max_packet_size); |
1793 | if (rc) { | 1793 | if (rc) { |
1794 | ecryptfs_printk(KERN_ERR, "Error parsing " | 1794 | ecryptfs_printk(KERN_ERR, "Error parsing " |
1795 | "tag 3 packet\n"); | 1795 | "tag 3 packet\n"); |
1796 | rc = -EIO; | 1796 | rc = -EIO; |
1797 | goto out_wipe_list; | 1797 | goto out_wipe_list; |
1798 | } | 1798 | } |
1799 | i += packet_size; | 1799 | i += packet_size; |
1800 | rc = parse_tag_11_packet((unsigned char *)&src[i], | 1800 | rc = parse_tag_11_packet((unsigned char *)&src[i], |
1801 | sig_tmp_space, | 1801 | sig_tmp_space, |
1802 | ECRYPTFS_SIG_SIZE, | 1802 | ECRYPTFS_SIG_SIZE, |
1803 | &tag_11_contents_size, | 1803 | &tag_11_contents_size, |
1804 | &tag_11_packet_size, | 1804 | &tag_11_packet_size, |
1805 | max_packet_size); | 1805 | max_packet_size); |
1806 | if (rc) { | 1806 | if (rc) { |
1807 | ecryptfs_printk(KERN_ERR, "No valid " | 1807 | ecryptfs_printk(KERN_ERR, "No valid " |
1808 | "(ecryptfs-specific) literal " | 1808 | "(ecryptfs-specific) literal " |
1809 | "packet containing " | 1809 | "packet containing " |
1810 | "authentication token " | 1810 | "authentication token " |
1811 | "signature found after " | 1811 | "signature found after " |
1812 | "tag 3 packet\n"); | 1812 | "tag 3 packet\n"); |
1813 | rc = -EIO; | 1813 | rc = -EIO; |
1814 | goto out_wipe_list; | 1814 | goto out_wipe_list; |
1815 | } | 1815 | } |
1816 | i += tag_11_packet_size; | 1816 | i += tag_11_packet_size; |
1817 | if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) { | 1817 | if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) { |
1818 | ecryptfs_printk(KERN_ERR, "Expected " | 1818 | ecryptfs_printk(KERN_ERR, "Expected " |
1819 | "signature of size [%d]; " | 1819 | "signature of size [%d]; " |
1820 | "read size [%zd]\n", | 1820 | "read size [%zd]\n", |
1821 | ECRYPTFS_SIG_SIZE, | 1821 | ECRYPTFS_SIG_SIZE, |
1822 | tag_11_contents_size); | 1822 | tag_11_contents_size); |
1823 | rc = -EIO; | 1823 | rc = -EIO; |
1824 | goto out_wipe_list; | 1824 | goto out_wipe_list; |
1825 | } | 1825 | } |
1826 | ecryptfs_to_hex(new_auth_tok->token.password.signature, | 1826 | ecryptfs_to_hex(new_auth_tok->token.password.signature, |
1827 | sig_tmp_space, tag_11_contents_size); | 1827 | sig_tmp_space, tag_11_contents_size); |
1828 | new_auth_tok->token.password.signature[ | 1828 | new_auth_tok->token.password.signature[ |
1829 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; | 1829 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; |
1830 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; | 1830 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
1831 | break; | 1831 | break; |
1832 | case ECRYPTFS_TAG_1_PACKET_TYPE: | 1832 | case ECRYPTFS_TAG_1_PACKET_TYPE: |
1833 | rc = parse_tag_1_packet(crypt_stat, | 1833 | rc = parse_tag_1_packet(crypt_stat, |
1834 | (unsigned char *)&src[i], | 1834 | (unsigned char *)&src[i], |
1835 | &auth_tok_list, &new_auth_tok, | 1835 | &auth_tok_list, &new_auth_tok, |
1836 | &packet_size, max_packet_size); | 1836 | &packet_size, max_packet_size); |
1837 | if (rc) { | 1837 | if (rc) { |
1838 | ecryptfs_printk(KERN_ERR, "Error parsing " | 1838 | ecryptfs_printk(KERN_ERR, "Error parsing " |
1839 | "tag 1 packet\n"); | 1839 | "tag 1 packet\n"); |
1840 | rc = -EIO; | 1840 | rc = -EIO; |
1841 | goto out_wipe_list; | 1841 | goto out_wipe_list; |
1842 | } | 1842 | } |
1843 | i += packet_size; | 1843 | i += packet_size; |
1844 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; | 1844 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
1845 | break; | 1845 | break; |
1846 | case ECRYPTFS_TAG_11_PACKET_TYPE: | 1846 | case ECRYPTFS_TAG_11_PACKET_TYPE: |
1847 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " | 1847 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " |
1848 | "(Tag 11 not allowed by itself)\n"); | 1848 | "(Tag 11 not allowed by itself)\n"); |
1849 | rc = -EIO; | 1849 | rc = -EIO; |
1850 | goto out_wipe_list; | 1850 | goto out_wipe_list; |
1851 | break; | 1851 | break; |
1852 | default: | 1852 | default: |
1853 | ecryptfs_printk(KERN_DEBUG, "No packet at offset [%zd] " | 1853 | ecryptfs_printk(KERN_DEBUG, "No packet at offset [%zd] " |
1854 | "of the file header; hex value of " | 1854 | "of the file header; hex value of " |
1855 | "character is [0x%.2x]\n", i, src[i]); | 1855 | "character is [0x%.2x]\n", i, src[i]); |
1856 | next_packet_is_auth_tok_packet = 0; | 1856 | next_packet_is_auth_tok_packet = 0; |
1857 | } | 1857 | } |
1858 | } | 1858 | } |
1859 | if (list_empty(&auth_tok_list)) { | 1859 | if (list_empty(&auth_tok_list)) { |
1860 | printk(KERN_ERR "The lower file appears to be a non-encrypted " | 1860 | printk(KERN_ERR "The lower file appears to be a non-encrypted " |
1861 | "eCryptfs file; this is not supported in this version " | 1861 | "eCryptfs file; this is not supported in this version " |
1862 | "of the eCryptfs kernel module\n"); | 1862 | "of the eCryptfs kernel module\n"); |
1863 | rc = -EINVAL; | 1863 | rc = -EINVAL; |
1864 | goto out; | 1864 | goto out; |
1865 | } | 1865 | } |
1866 | /* auth_tok_list contains the set of authentication tokens | 1866 | /* auth_tok_list contains the set of authentication tokens |
1867 | * parsed from the metadata. We need to find a matching | 1867 | * parsed from the metadata. We need to find a matching |
1868 | * authentication token that has the secret component(s) | 1868 | * authentication token that has the secret component(s) |
1869 | * necessary to decrypt the EFEK in the auth_tok parsed from | 1869 | * necessary to decrypt the EFEK in the auth_tok parsed from |
1870 | * the metadata. There may be several potential matches, but | 1870 | * the metadata. There may be several potential matches, but |
1871 | * just one will be sufficient to decrypt to get the FEK. */ | 1871 | * just one will be sufficient to decrypt to get the FEK. */ |
1872 | find_next_matching_auth_tok: | 1872 | find_next_matching_auth_tok: |
1873 | found_auth_tok = 0; | 1873 | found_auth_tok = 0; |
1874 | list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) { | 1874 | list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) { |
1875 | candidate_auth_tok = &auth_tok_list_item->auth_tok; | 1875 | candidate_auth_tok = &auth_tok_list_item->auth_tok; |
1876 | if (unlikely(ecryptfs_verbosity > 0)) { | 1876 | if (unlikely(ecryptfs_verbosity > 0)) { |
1877 | ecryptfs_printk(KERN_DEBUG, | 1877 | ecryptfs_printk(KERN_DEBUG, |
1878 | "Considering cadidate auth tok:\n"); | 1878 | "Considering cadidate auth tok:\n"); |
1879 | ecryptfs_dump_auth_tok(candidate_auth_tok); | 1879 | ecryptfs_dump_auth_tok(candidate_auth_tok); |
1880 | } | 1880 | } |
1881 | rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig, | 1881 | rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig, |
1882 | candidate_auth_tok); | 1882 | candidate_auth_tok); |
1883 | if (rc) { | 1883 | if (rc) { |
1884 | printk(KERN_ERR | 1884 | printk(KERN_ERR |
1885 | "Unrecognized candidate auth tok type: [%d]\n", | 1885 | "Unrecognized candidate auth tok type: [%d]\n", |
1886 | candidate_auth_tok->token_type); | 1886 | candidate_auth_tok->token_type); |
1887 | rc = -EINVAL; | 1887 | rc = -EINVAL; |
1888 | goto out_wipe_list; | 1888 | goto out_wipe_list; |
1889 | } | 1889 | } |
1890 | rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, | 1890 | rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, |
1891 | &matching_auth_tok, | 1891 | &matching_auth_tok, |
1892 | crypt_stat->mount_crypt_stat, | 1892 | crypt_stat->mount_crypt_stat, |
1893 | candidate_auth_tok_sig); | 1893 | candidate_auth_tok_sig); |
1894 | if (!rc) { | 1894 | if (!rc) { |
1895 | found_auth_tok = 1; | 1895 | found_auth_tok = 1; |
1896 | goto found_matching_auth_tok; | 1896 | goto found_matching_auth_tok; |
1897 | } | 1897 | } |
1898 | } | 1898 | } |
1899 | if (!found_auth_tok) { | 1899 | if (!found_auth_tok) { |
1900 | ecryptfs_printk(KERN_ERR, "Could not find a usable " | 1900 | ecryptfs_printk(KERN_ERR, "Could not find a usable " |
1901 | "authentication token\n"); | 1901 | "authentication token\n"); |
1902 | rc = -EIO; | 1902 | rc = -EIO; |
1903 | goto out_wipe_list; | 1903 | goto out_wipe_list; |
1904 | } | 1904 | } |
1905 | found_matching_auth_tok: | 1905 | found_matching_auth_tok: |
1906 | if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | 1906 | if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { |
1907 | memcpy(&(candidate_auth_tok->token.private_key), | 1907 | memcpy(&(candidate_auth_tok->token.private_key), |
1908 | &(matching_auth_tok->token.private_key), | 1908 | &(matching_auth_tok->token.private_key), |
1909 | sizeof(struct ecryptfs_private_key)); | 1909 | sizeof(struct ecryptfs_private_key)); |
1910 | up_write(&(auth_tok_key->sem)); | 1910 | up_write(&(auth_tok_key->sem)); |
1911 | key_put(auth_tok_key); | 1911 | key_put(auth_tok_key); |
1912 | rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, | 1912 | rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, |
1913 | crypt_stat); | 1913 | crypt_stat); |
1914 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { | 1914 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { |
1915 | memcpy(&(candidate_auth_tok->token.password), | 1915 | memcpy(&(candidate_auth_tok->token.password), |
1916 | &(matching_auth_tok->token.password), | 1916 | &(matching_auth_tok->token.password), |
1917 | sizeof(struct ecryptfs_password)); | 1917 | sizeof(struct ecryptfs_password)); |
1918 | up_write(&(auth_tok_key->sem)); | 1918 | up_write(&(auth_tok_key->sem)); |
1919 | key_put(auth_tok_key); | 1919 | key_put(auth_tok_key); |
1920 | rc = decrypt_passphrase_encrypted_session_key( | 1920 | rc = decrypt_passphrase_encrypted_session_key( |
1921 | candidate_auth_tok, crypt_stat); | 1921 | candidate_auth_tok, crypt_stat); |
1922 | } else { | 1922 | } else { |
1923 | up_write(&(auth_tok_key->sem)); | 1923 | up_write(&(auth_tok_key->sem)); |
1924 | key_put(auth_tok_key); | 1924 | key_put(auth_tok_key); |
1925 | rc = -EINVAL; | 1925 | rc = -EINVAL; |
1926 | } | 1926 | } |
1927 | if (rc) { | 1927 | if (rc) { |
1928 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp; | 1928 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp; |
1929 | 1929 | ||
1930 | ecryptfs_printk(KERN_WARNING, "Error decrypting the " | 1930 | ecryptfs_printk(KERN_WARNING, "Error decrypting the " |
1931 | "session key for authentication token with sig " | 1931 | "session key for authentication token with sig " |
1932 | "[%.*s]; rc = [%d]. Removing auth tok " | 1932 | "[%.*s]; rc = [%d]. Removing auth tok " |
1933 | "candidate from the list and searching for " | 1933 | "candidate from the list and searching for " |
1934 | "the next match.\n", ECRYPTFS_SIG_SIZE_HEX, | 1934 | "the next match.\n", ECRYPTFS_SIG_SIZE_HEX, |
1935 | candidate_auth_tok_sig, rc); | 1935 | candidate_auth_tok_sig, rc); |
1936 | list_for_each_entry_safe(auth_tok_list_item, | 1936 | list_for_each_entry_safe(auth_tok_list_item, |
1937 | auth_tok_list_item_tmp, | 1937 | auth_tok_list_item_tmp, |
1938 | &auth_tok_list, list) { | 1938 | &auth_tok_list, list) { |
1939 | if (candidate_auth_tok | 1939 | if (candidate_auth_tok |
1940 | == &auth_tok_list_item->auth_tok) { | 1940 | == &auth_tok_list_item->auth_tok) { |
1941 | list_del(&auth_tok_list_item->list); | 1941 | list_del(&auth_tok_list_item->list); |
1942 | kmem_cache_free( | 1942 | kmem_cache_free( |
1943 | ecryptfs_auth_tok_list_item_cache, | 1943 | ecryptfs_auth_tok_list_item_cache, |
1944 | auth_tok_list_item); | 1944 | auth_tok_list_item); |
1945 | goto find_next_matching_auth_tok; | 1945 | goto find_next_matching_auth_tok; |
1946 | } | 1946 | } |
1947 | } | 1947 | } |
1948 | BUG(); | 1948 | BUG(); |
1949 | } | 1949 | } |
1950 | rc = ecryptfs_compute_root_iv(crypt_stat); | 1950 | rc = ecryptfs_compute_root_iv(crypt_stat); |
1951 | if (rc) { | 1951 | if (rc) { |
1952 | ecryptfs_printk(KERN_ERR, "Error computing " | 1952 | ecryptfs_printk(KERN_ERR, "Error computing " |
1953 | "the root IV\n"); | 1953 | "the root IV\n"); |
1954 | goto out_wipe_list; | 1954 | goto out_wipe_list; |
1955 | } | 1955 | } |
1956 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | 1956 | rc = ecryptfs_init_crypt_ctx(crypt_stat); |
1957 | if (rc) { | 1957 | if (rc) { |
1958 | ecryptfs_printk(KERN_ERR, "Error initializing crypto " | 1958 | ecryptfs_printk(KERN_ERR, "Error initializing crypto " |
1959 | "context for cipher [%s]; rc = [%d]\n", | 1959 | "context for cipher [%s]; rc = [%d]\n", |
1960 | crypt_stat->cipher, rc); | 1960 | crypt_stat->cipher, rc); |
1961 | } | 1961 | } |
1962 | out_wipe_list: | 1962 | out_wipe_list: |
1963 | wipe_auth_tok_list(&auth_tok_list); | 1963 | wipe_auth_tok_list(&auth_tok_list); |
1964 | out: | 1964 | out: |
1965 | return rc; | 1965 | return rc; |
1966 | } | 1966 | } |
1967 | 1967 | ||
1968 | static int | 1968 | static int |
1969 | pki_encrypt_session_key(struct key *auth_tok_key, | 1969 | pki_encrypt_session_key(struct key *auth_tok_key, |
1970 | struct ecryptfs_auth_tok *auth_tok, | 1970 | struct ecryptfs_auth_tok *auth_tok, |
1971 | struct ecryptfs_crypt_stat *crypt_stat, | 1971 | struct ecryptfs_crypt_stat *crypt_stat, |
1972 | struct ecryptfs_key_record *key_rec) | 1972 | struct ecryptfs_key_record *key_rec) |
1973 | { | 1973 | { |
1974 | struct ecryptfs_msg_ctx *msg_ctx = NULL; | 1974 | struct ecryptfs_msg_ctx *msg_ctx = NULL; |
1975 | char *payload = NULL; | 1975 | char *payload = NULL; |
1976 | size_t payload_len; | 1976 | size_t payload_len = 0; |
1977 | struct ecryptfs_message *msg; | 1977 | struct ecryptfs_message *msg; |
1978 | int rc; | 1978 | int rc; |
1979 | 1979 | ||
1980 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, | 1980 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, |
1981 | ecryptfs_code_for_cipher_string( | 1981 | ecryptfs_code_for_cipher_string( |
1982 | crypt_stat->cipher, | 1982 | crypt_stat->cipher, |
1983 | crypt_stat->key_size), | 1983 | crypt_stat->key_size), |
1984 | crypt_stat, &payload, &payload_len); | 1984 | crypt_stat, &payload, &payload_len); |
1985 | up_write(&(auth_tok_key->sem)); | 1985 | up_write(&(auth_tok_key->sem)); |
1986 | key_put(auth_tok_key); | 1986 | key_put(auth_tok_key); |
1987 | if (rc) { | 1987 | if (rc) { |
1988 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); | 1988 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); |
1989 | goto out; | 1989 | goto out; |
1990 | } | 1990 | } |
1991 | rc = ecryptfs_send_message(payload, payload_len, &msg_ctx); | 1991 | rc = ecryptfs_send_message(payload, payload_len, &msg_ctx); |
1992 | if (rc) { | 1992 | if (rc) { |
1993 | ecryptfs_printk(KERN_ERR, "Error sending message to " | 1993 | ecryptfs_printk(KERN_ERR, "Error sending message to " |
1994 | "ecryptfsd\n"); | 1994 | "ecryptfsd\n"); |
1995 | goto out; | 1995 | goto out; |
1996 | } | 1996 | } |
1997 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | 1997 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); |
1998 | if (rc) { | 1998 | if (rc) { |
1999 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 67 packet " | 1999 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 67 packet " |
2000 | "from the user space daemon\n"); | 2000 | "from the user space daemon\n"); |
2001 | rc = -EIO; | 2001 | rc = -EIO; |
2002 | goto out; | 2002 | goto out; |
2003 | } | 2003 | } |
2004 | rc = parse_tag_67_packet(key_rec, msg); | 2004 | rc = parse_tag_67_packet(key_rec, msg); |
2005 | if (rc) | 2005 | if (rc) |
2006 | ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n"); | 2006 | ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n"); |
2007 | kfree(msg); | 2007 | kfree(msg); |
2008 | out: | 2008 | out: |
2009 | kfree(payload); | 2009 | kfree(payload); |
2010 | return rc; | 2010 | return rc; |
2011 | } | 2011 | } |
2012 | /** | 2012 | /** |
2013 | * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet | 2013 | * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet |
2014 | * @dest: Buffer into which to write the packet | 2014 | * @dest: Buffer into which to write the packet |
2015 | * @remaining_bytes: Maximum number of bytes that can be writtn | 2015 | * @remaining_bytes: Maximum number of bytes that can be writtn |
2016 | * @auth_tok_key: The authentication token key to unlock and put when done with | 2016 | * @auth_tok_key: The authentication token key to unlock and put when done with |
2017 | * @auth_tok | 2017 | * @auth_tok |
2018 | * @auth_tok: The authentication token used for generating the tag 1 packet | 2018 | * @auth_tok: The authentication token used for generating the tag 1 packet |
2019 | * @crypt_stat: The cryptographic context | 2019 | * @crypt_stat: The cryptographic context |
2020 | * @key_rec: The key record struct for the tag 1 packet | 2020 | * @key_rec: The key record struct for the tag 1 packet |
2021 | * @packet_size: This function will write the number of bytes that end | 2021 | * @packet_size: This function will write the number of bytes that end |
2022 | * up constituting the packet; set to zero on error | 2022 | * up constituting the packet; set to zero on error |
2023 | * | 2023 | * |
2024 | * Returns zero on success; non-zero on error. | 2024 | * Returns zero on success; non-zero on error. |
2025 | */ | 2025 | */ |
2026 | static int | 2026 | static int |
2027 | write_tag_1_packet(char *dest, size_t *remaining_bytes, | 2027 | write_tag_1_packet(char *dest, size_t *remaining_bytes, |
2028 | struct key *auth_tok_key, struct ecryptfs_auth_tok *auth_tok, | 2028 | struct key *auth_tok_key, struct ecryptfs_auth_tok *auth_tok, |
2029 | struct ecryptfs_crypt_stat *crypt_stat, | 2029 | struct ecryptfs_crypt_stat *crypt_stat, |
2030 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 2030 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
2031 | { | 2031 | { |
2032 | size_t i; | 2032 | size_t i; |
2033 | size_t encrypted_session_key_valid = 0; | 2033 | size_t encrypted_session_key_valid = 0; |
2034 | size_t packet_size_length; | 2034 | size_t packet_size_length; |
2035 | size_t max_packet_size; | 2035 | size_t max_packet_size; |
2036 | int rc = 0; | 2036 | int rc = 0; |
2037 | 2037 | ||
2038 | (*packet_size) = 0; | 2038 | (*packet_size) = 0; |
2039 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.private_key.signature, | 2039 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.private_key.signature, |
2040 | ECRYPTFS_SIG_SIZE); | 2040 | ECRYPTFS_SIG_SIZE); |
2041 | encrypted_session_key_valid = 0; | 2041 | encrypted_session_key_valid = 0; |
2042 | for (i = 0; i < crypt_stat->key_size; i++) | 2042 | for (i = 0; i < crypt_stat->key_size; i++) |
2043 | encrypted_session_key_valid |= | 2043 | encrypted_session_key_valid |= |
2044 | auth_tok->session_key.encrypted_key[i]; | 2044 | auth_tok->session_key.encrypted_key[i]; |
2045 | if (encrypted_session_key_valid) { | 2045 | if (encrypted_session_key_valid) { |
2046 | memcpy(key_rec->enc_key, | 2046 | memcpy(key_rec->enc_key, |
2047 | auth_tok->session_key.encrypted_key, | 2047 | auth_tok->session_key.encrypted_key, |
2048 | auth_tok->session_key.encrypted_key_size); | 2048 | auth_tok->session_key.encrypted_key_size); |
2049 | up_write(&(auth_tok_key->sem)); | 2049 | up_write(&(auth_tok_key->sem)); |
2050 | key_put(auth_tok_key); | 2050 | key_put(auth_tok_key); |
2051 | goto encrypted_session_key_set; | 2051 | goto encrypted_session_key_set; |
2052 | } | 2052 | } |
2053 | if (auth_tok->session_key.encrypted_key_size == 0) | 2053 | if (auth_tok->session_key.encrypted_key_size == 0) |
2054 | auth_tok->session_key.encrypted_key_size = | 2054 | auth_tok->session_key.encrypted_key_size = |
2055 | auth_tok->token.private_key.key_size; | 2055 | auth_tok->token.private_key.key_size; |
2056 | rc = pki_encrypt_session_key(auth_tok_key, auth_tok, crypt_stat, | 2056 | rc = pki_encrypt_session_key(auth_tok_key, auth_tok, crypt_stat, |
2057 | key_rec); | 2057 | key_rec); |
2058 | if (rc) { | 2058 | if (rc) { |
2059 | printk(KERN_ERR "Failed to encrypt session key via a key " | 2059 | printk(KERN_ERR "Failed to encrypt session key via a key " |
2060 | "module; rc = [%d]\n", rc); | 2060 | "module; rc = [%d]\n", rc); |
2061 | goto out; | 2061 | goto out; |
2062 | } | 2062 | } |
2063 | if (ecryptfs_verbosity > 0) { | 2063 | if (ecryptfs_verbosity > 0) { |
2064 | ecryptfs_printk(KERN_DEBUG, "Encrypted key:\n"); | 2064 | ecryptfs_printk(KERN_DEBUG, "Encrypted key:\n"); |
2065 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); | 2065 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); |
2066 | } | 2066 | } |
2067 | encrypted_session_key_set: | 2067 | encrypted_session_key_set: |
2068 | /* This format is inspired by OpenPGP; see RFC 2440 | 2068 | /* This format is inspired by OpenPGP; see RFC 2440 |
2069 | * packet tag 1 */ | 2069 | * packet tag 1 */ |
2070 | max_packet_size = (1 /* Tag 1 identifier */ | 2070 | max_packet_size = (1 /* Tag 1 identifier */ |
2071 | + 3 /* Max Tag 1 packet size */ | 2071 | + 3 /* Max Tag 1 packet size */ |
2072 | + 1 /* Version */ | 2072 | + 1 /* Version */ |
2073 | + ECRYPTFS_SIG_SIZE /* Key identifier */ | 2073 | + ECRYPTFS_SIG_SIZE /* Key identifier */ |
2074 | + 1 /* Cipher identifier */ | 2074 | + 1 /* Cipher identifier */ |
2075 | + key_rec->enc_key_size); /* Encrypted key size */ | 2075 | + key_rec->enc_key_size); /* Encrypted key size */ |
2076 | if (max_packet_size > (*remaining_bytes)) { | 2076 | if (max_packet_size > (*remaining_bytes)) { |
2077 | printk(KERN_ERR "Packet length larger than maximum allowable; " | 2077 | printk(KERN_ERR "Packet length larger than maximum allowable; " |
2078 | "need up to [%td] bytes, but there are only [%td] " | 2078 | "need up to [%td] bytes, but there are only [%td] " |
2079 | "available\n", max_packet_size, (*remaining_bytes)); | 2079 | "available\n", max_packet_size, (*remaining_bytes)); |
2080 | rc = -EINVAL; | 2080 | rc = -EINVAL; |
2081 | goto out; | 2081 | goto out; |
2082 | } | 2082 | } |
2083 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; | 2083 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; |
2084 | rc = ecryptfs_write_packet_length(&dest[(*packet_size)], | 2084 | rc = ecryptfs_write_packet_length(&dest[(*packet_size)], |
2085 | (max_packet_size - 4), | 2085 | (max_packet_size - 4), |
2086 | &packet_size_length); | 2086 | &packet_size_length); |
2087 | if (rc) { | 2087 | if (rc) { |
2088 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " | 2088 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " |
2089 | "header; cannot generate packet length\n"); | 2089 | "header; cannot generate packet length\n"); |
2090 | goto out; | 2090 | goto out; |
2091 | } | 2091 | } |
2092 | (*packet_size) += packet_size_length; | 2092 | (*packet_size) += packet_size_length; |
2093 | dest[(*packet_size)++] = 0x03; /* version 3 */ | 2093 | dest[(*packet_size)++] = 0x03; /* version 3 */ |
2094 | memcpy(&dest[(*packet_size)], key_rec->sig, ECRYPTFS_SIG_SIZE); | 2094 | memcpy(&dest[(*packet_size)], key_rec->sig, ECRYPTFS_SIG_SIZE); |
2095 | (*packet_size) += ECRYPTFS_SIG_SIZE; | 2095 | (*packet_size) += ECRYPTFS_SIG_SIZE; |
2096 | dest[(*packet_size)++] = RFC2440_CIPHER_RSA; | 2096 | dest[(*packet_size)++] = RFC2440_CIPHER_RSA; |
2097 | memcpy(&dest[(*packet_size)], key_rec->enc_key, | 2097 | memcpy(&dest[(*packet_size)], key_rec->enc_key, |
2098 | key_rec->enc_key_size); | 2098 | key_rec->enc_key_size); |
2099 | (*packet_size) += key_rec->enc_key_size; | 2099 | (*packet_size) += key_rec->enc_key_size; |
2100 | out: | 2100 | out: |
2101 | if (rc) | 2101 | if (rc) |
2102 | (*packet_size) = 0; | 2102 | (*packet_size) = 0; |
2103 | else | 2103 | else |
2104 | (*remaining_bytes) -= (*packet_size); | 2104 | (*remaining_bytes) -= (*packet_size); |
2105 | return rc; | 2105 | return rc; |
2106 | } | 2106 | } |
2107 | 2107 | ||
2108 | /** | 2108 | /** |
2109 | * write_tag_11_packet | 2109 | * write_tag_11_packet |
2110 | * @dest: Target into which Tag 11 packet is to be written | 2110 | * @dest: Target into which Tag 11 packet is to be written |
2111 | * @remaining_bytes: Maximum packet length | 2111 | * @remaining_bytes: Maximum packet length |
2112 | * @contents: Byte array of contents to copy in | 2112 | * @contents: Byte array of contents to copy in |
2113 | * @contents_length: Number of bytes in contents | 2113 | * @contents_length: Number of bytes in contents |
2114 | * @packet_length: Length of the Tag 11 packet written; zero on error | 2114 | * @packet_length: Length of the Tag 11 packet written; zero on error |
2115 | * | 2115 | * |
2116 | * Returns zero on success; non-zero on error. | 2116 | * Returns zero on success; non-zero on error. |
2117 | */ | 2117 | */ |
2118 | static int | 2118 | static int |
2119 | write_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents, | 2119 | write_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents, |
2120 | size_t contents_length, size_t *packet_length) | 2120 | size_t contents_length, size_t *packet_length) |
2121 | { | 2121 | { |
2122 | size_t packet_size_length; | 2122 | size_t packet_size_length; |
2123 | size_t max_packet_size; | 2123 | size_t max_packet_size; |
2124 | int rc = 0; | 2124 | int rc = 0; |
2125 | 2125 | ||
2126 | (*packet_length) = 0; | 2126 | (*packet_length) = 0; |
2127 | /* This format is inspired by OpenPGP; see RFC 2440 | 2127 | /* This format is inspired by OpenPGP; see RFC 2440 |
2128 | * packet tag 11 */ | 2128 | * packet tag 11 */ |
2129 | max_packet_size = (1 /* Tag 11 identifier */ | 2129 | max_packet_size = (1 /* Tag 11 identifier */ |
2130 | + 3 /* Max Tag 11 packet size */ | 2130 | + 3 /* Max Tag 11 packet size */ |
2131 | + 1 /* Binary format specifier */ | 2131 | + 1 /* Binary format specifier */ |
2132 | + 1 /* Filename length */ | 2132 | + 1 /* Filename length */ |
2133 | + 8 /* Filename ("_CONSOLE") */ | 2133 | + 8 /* Filename ("_CONSOLE") */ |
2134 | + 4 /* Modification date */ | 2134 | + 4 /* Modification date */ |
2135 | + contents_length); /* Literal data */ | 2135 | + contents_length); /* Literal data */ |
2136 | if (max_packet_size > (*remaining_bytes)) { | 2136 | if (max_packet_size > (*remaining_bytes)) { |
2137 | printk(KERN_ERR "Packet length larger than maximum allowable; " | 2137 | printk(KERN_ERR "Packet length larger than maximum allowable; " |
2138 | "need up to [%td] bytes, but there are only [%td] " | 2138 | "need up to [%td] bytes, but there are only [%td] " |
2139 | "available\n", max_packet_size, (*remaining_bytes)); | 2139 | "available\n", max_packet_size, (*remaining_bytes)); |
2140 | rc = -EINVAL; | 2140 | rc = -EINVAL; |
2141 | goto out; | 2141 | goto out; |
2142 | } | 2142 | } |
2143 | dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE; | 2143 | dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE; |
2144 | rc = ecryptfs_write_packet_length(&dest[(*packet_length)], | 2144 | rc = ecryptfs_write_packet_length(&dest[(*packet_length)], |
2145 | (max_packet_size - 4), | 2145 | (max_packet_size - 4), |
2146 | &packet_size_length); | 2146 | &packet_size_length); |
2147 | if (rc) { | 2147 | if (rc) { |
2148 | printk(KERN_ERR "Error generating tag 11 packet header; cannot " | 2148 | printk(KERN_ERR "Error generating tag 11 packet header; cannot " |
2149 | "generate packet length. rc = [%d]\n", rc); | 2149 | "generate packet length. rc = [%d]\n", rc); |
2150 | goto out; | 2150 | goto out; |
2151 | } | 2151 | } |
2152 | (*packet_length) += packet_size_length; | 2152 | (*packet_length) += packet_size_length; |
2153 | dest[(*packet_length)++] = 0x62; /* binary data format specifier */ | 2153 | dest[(*packet_length)++] = 0x62; /* binary data format specifier */ |
2154 | dest[(*packet_length)++] = 8; | 2154 | dest[(*packet_length)++] = 8; |
2155 | memcpy(&dest[(*packet_length)], "_CONSOLE", 8); | 2155 | memcpy(&dest[(*packet_length)], "_CONSOLE", 8); |
2156 | (*packet_length) += 8; | 2156 | (*packet_length) += 8; |
2157 | memset(&dest[(*packet_length)], 0x00, 4); | 2157 | memset(&dest[(*packet_length)], 0x00, 4); |
2158 | (*packet_length) += 4; | 2158 | (*packet_length) += 4; |
2159 | memcpy(&dest[(*packet_length)], contents, contents_length); | 2159 | memcpy(&dest[(*packet_length)], contents, contents_length); |
2160 | (*packet_length) += contents_length; | 2160 | (*packet_length) += contents_length; |
2161 | out: | 2161 | out: |
2162 | if (rc) | 2162 | if (rc) |
2163 | (*packet_length) = 0; | 2163 | (*packet_length) = 0; |
2164 | else | 2164 | else |
2165 | (*remaining_bytes) -= (*packet_length); | 2165 | (*remaining_bytes) -= (*packet_length); |
2166 | return rc; | 2166 | return rc; |
2167 | } | 2167 | } |
2168 | 2168 | ||
2169 | /** | 2169 | /** |
2170 | * write_tag_3_packet | 2170 | * write_tag_3_packet |
2171 | * @dest: Buffer into which to write the packet | 2171 | * @dest: Buffer into which to write the packet |
2172 | * @remaining_bytes: Maximum number of bytes that can be written | 2172 | * @remaining_bytes: Maximum number of bytes that can be written |
2173 | * @auth_tok: Authentication token | 2173 | * @auth_tok: Authentication token |
2174 | * @crypt_stat: The cryptographic context | 2174 | * @crypt_stat: The cryptographic context |
2175 | * @key_rec: encrypted key | 2175 | * @key_rec: encrypted key |
2176 | * @packet_size: This function will write the number of bytes that end | 2176 | * @packet_size: This function will write the number of bytes that end |
2177 | * up constituting the packet; set to zero on error | 2177 | * up constituting the packet; set to zero on error |
2178 | * | 2178 | * |
2179 | * Returns zero on success; non-zero on error. | 2179 | * Returns zero on success; non-zero on error. |
2180 | */ | 2180 | */ |
2181 | static int | 2181 | static int |
2182 | write_tag_3_packet(char *dest, size_t *remaining_bytes, | 2182 | write_tag_3_packet(char *dest, size_t *remaining_bytes, |
2183 | struct ecryptfs_auth_tok *auth_tok, | 2183 | struct ecryptfs_auth_tok *auth_tok, |
2184 | struct ecryptfs_crypt_stat *crypt_stat, | 2184 | struct ecryptfs_crypt_stat *crypt_stat, |
2185 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 2185 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
2186 | { | 2186 | { |
2187 | size_t i; | 2187 | size_t i; |
2188 | size_t encrypted_session_key_valid = 0; | 2188 | size_t encrypted_session_key_valid = 0; |
2189 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 2189 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
2190 | struct scatterlist dst_sg[2]; | 2190 | struct scatterlist dst_sg[2]; |
2191 | struct scatterlist src_sg[2]; | 2191 | struct scatterlist src_sg[2]; |
2192 | struct mutex *tfm_mutex = NULL; | 2192 | struct mutex *tfm_mutex = NULL; |
2193 | u8 cipher_code; | 2193 | u8 cipher_code; |
2194 | size_t packet_size_length; | 2194 | size_t packet_size_length; |
2195 | size_t max_packet_size; | 2195 | size_t max_packet_size; |
2196 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 2196 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
2197 | crypt_stat->mount_crypt_stat; | 2197 | crypt_stat->mount_crypt_stat; |
2198 | struct blkcipher_desc desc = { | 2198 | struct blkcipher_desc desc = { |
2199 | .tfm = NULL, | 2199 | .tfm = NULL, |
2200 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | 2200 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP |
2201 | }; | 2201 | }; |
2202 | int rc = 0; | 2202 | int rc = 0; |
2203 | 2203 | ||
2204 | (*packet_size) = 0; | 2204 | (*packet_size) = 0; |
2205 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, | 2205 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, |
2206 | ECRYPTFS_SIG_SIZE); | 2206 | ECRYPTFS_SIG_SIZE); |
2207 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, | 2207 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, |
2208 | crypt_stat->cipher); | 2208 | crypt_stat->cipher); |
2209 | if (unlikely(rc)) { | 2209 | if (unlikely(rc)) { |
2210 | printk(KERN_ERR "Internal error whilst attempting to get " | 2210 | printk(KERN_ERR "Internal error whilst attempting to get " |
2211 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", | 2211 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", |
2212 | crypt_stat->cipher, rc); | 2212 | crypt_stat->cipher, rc); |
2213 | goto out; | 2213 | goto out; |
2214 | } | 2214 | } |
2215 | if (mount_crypt_stat->global_default_cipher_key_size == 0) { | 2215 | if (mount_crypt_stat->global_default_cipher_key_size == 0) { |
2216 | struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm); | 2216 | struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm); |
2217 | 2217 | ||
2218 | printk(KERN_WARNING "No key size specified at mount; " | 2218 | printk(KERN_WARNING "No key size specified at mount; " |
2219 | "defaulting to [%d]\n", alg->max_keysize); | 2219 | "defaulting to [%d]\n", alg->max_keysize); |
2220 | mount_crypt_stat->global_default_cipher_key_size = | 2220 | mount_crypt_stat->global_default_cipher_key_size = |
2221 | alg->max_keysize; | 2221 | alg->max_keysize; |
2222 | } | 2222 | } |
2223 | if (crypt_stat->key_size == 0) | 2223 | if (crypt_stat->key_size == 0) |
2224 | crypt_stat->key_size = | 2224 | crypt_stat->key_size = |
2225 | mount_crypt_stat->global_default_cipher_key_size; | 2225 | mount_crypt_stat->global_default_cipher_key_size; |
2226 | if (auth_tok->session_key.encrypted_key_size == 0) | 2226 | if (auth_tok->session_key.encrypted_key_size == 0) |
2227 | auth_tok->session_key.encrypted_key_size = | 2227 | auth_tok->session_key.encrypted_key_size = |
2228 | crypt_stat->key_size; | 2228 | crypt_stat->key_size; |
2229 | if (crypt_stat->key_size == 24 | 2229 | if (crypt_stat->key_size == 24 |
2230 | && strcmp("aes", crypt_stat->cipher) == 0) { | 2230 | && strcmp("aes", crypt_stat->cipher) == 0) { |
2231 | memset((crypt_stat->key + 24), 0, 8); | 2231 | memset((crypt_stat->key + 24), 0, 8); |
2232 | auth_tok->session_key.encrypted_key_size = 32; | 2232 | auth_tok->session_key.encrypted_key_size = 32; |
2233 | } else | 2233 | } else |
2234 | auth_tok->session_key.encrypted_key_size = crypt_stat->key_size; | 2234 | auth_tok->session_key.encrypted_key_size = crypt_stat->key_size; |
2235 | key_rec->enc_key_size = | 2235 | key_rec->enc_key_size = |
2236 | auth_tok->session_key.encrypted_key_size; | 2236 | auth_tok->session_key.encrypted_key_size; |
2237 | encrypted_session_key_valid = 0; | 2237 | encrypted_session_key_valid = 0; |
2238 | for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++) | 2238 | for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++) |
2239 | encrypted_session_key_valid |= | 2239 | encrypted_session_key_valid |= |
2240 | auth_tok->session_key.encrypted_key[i]; | 2240 | auth_tok->session_key.encrypted_key[i]; |
2241 | if (encrypted_session_key_valid) { | 2241 | if (encrypted_session_key_valid) { |
2242 | ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; " | 2242 | ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; " |
2243 | "using auth_tok->session_key.encrypted_key, " | 2243 | "using auth_tok->session_key.encrypted_key, " |
2244 | "where key_rec->enc_key_size = [%zd]\n", | 2244 | "where key_rec->enc_key_size = [%zd]\n", |
2245 | key_rec->enc_key_size); | 2245 | key_rec->enc_key_size); |
2246 | memcpy(key_rec->enc_key, | 2246 | memcpy(key_rec->enc_key, |
2247 | auth_tok->session_key.encrypted_key, | 2247 | auth_tok->session_key.encrypted_key, |
2248 | key_rec->enc_key_size); | 2248 | key_rec->enc_key_size); |
2249 | goto encrypted_session_key_set; | 2249 | goto encrypted_session_key_set; |
2250 | } | 2250 | } |
2251 | if (auth_tok->token.password.flags & | 2251 | if (auth_tok->token.password.flags & |
2252 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { | 2252 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { |
2253 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " | 2253 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " |
2254 | "session key encryption key of size [%d]\n", | 2254 | "session key encryption key of size [%d]\n", |
2255 | auth_tok->token.password. | 2255 | auth_tok->token.password. |
2256 | session_key_encryption_key_bytes); | 2256 | session_key_encryption_key_bytes); |
2257 | memcpy(session_key_encryption_key, | 2257 | memcpy(session_key_encryption_key, |
2258 | auth_tok->token.password.session_key_encryption_key, | 2258 | auth_tok->token.password.session_key_encryption_key, |
2259 | crypt_stat->key_size); | 2259 | crypt_stat->key_size); |
2260 | ecryptfs_printk(KERN_DEBUG, | 2260 | ecryptfs_printk(KERN_DEBUG, |
2261 | "Cached session key encryption key:\n"); | 2261 | "Cached session key encryption key:\n"); |
2262 | if (ecryptfs_verbosity > 0) | 2262 | if (ecryptfs_verbosity > 0) |
2263 | ecryptfs_dump_hex(session_key_encryption_key, 16); | 2263 | ecryptfs_dump_hex(session_key_encryption_key, 16); |
2264 | } | 2264 | } |
2265 | if (unlikely(ecryptfs_verbosity > 0)) { | 2265 | if (unlikely(ecryptfs_verbosity > 0)) { |
2266 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n"); | 2266 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n"); |
2267 | ecryptfs_dump_hex(session_key_encryption_key, 16); | 2267 | ecryptfs_dump_hex(session_key_encryption_key, 16); |
2268 | } | 2268 | } |
2269 | rc = virt_to_scatterlist(crypt_stat->key, key_rec->enc_key_size, | 2269 | rc = virt_to_scatterlist(crypt_stat->key, key_rec->enc_key_size, |
2270 | src_sg, 2); | 2270 | src_sg, 2); |
2271 | if (rc < 1 || rc > 2) { | 2271 | if (rc < 1 || rc > 2) { |
2272 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 2272 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
2273 | "for crypt_stat session key; expected rc = 1; " | 2273 | "for crypt_stat session key; expected rc = 1; " |
2274 | "got rc = [%d]. key_rec->enc_key_size = [%zd]\n", | 2274 | "got rc = [%d]. key_rec->enc_key_size = [%zd]\n", |
2275 | rc, key_rec->enc_key_size); | 2275 | rc, key_rec->enc_key_size); |
2276 | rc = -ENOMEM; | 2276 | rc = -ENOMEM; |
2277 | goto out; | 2277 | goto out; |
2278 | } | 2278 | } |
2279 | rc = virt_to_scatterlist(key_rec->enc_key, key_rec->enc_key_size, | 2279 | rc = virt_to_scatterlist(key_rec->enc_key, key_rec->enc_key_size, |
2280 | dst_sg, 2); | 2280 | dst_sg, 2); |
2281 | if (rc < 1 || rc > 2) { | 2281 | if (rc < 1 || rc > 2) { |
2282 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 2282 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
2283 | "for crypt_stat encrypted session key; " | 2283 | "for crypt_stat encrypted session key; " |
2284 | "expected rc = 1; got rc = [%d]. " | 2284 | "expected rc = 1; got rc = [%d]. " |
2285 | "key_rec->enc_key_size = [%zd]\n", rc, | 2285 | "key_rec->enc_key_size = [%zd]\n", rc, |
2286 | key_rec->enc_key_size); | 2286 | key_rec->enc_key_size); |
2287 | rc = -ENOMEM; | 2287 | rc = -ENOMEM; |
2288 | goto out; | 2288 | goto out; |
2289 | } | 2289 | } |
2290 | mutex_lock(tfm_mutex); | 2290 | mutex_lock(tfm_mutex); |
2291 | rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, | 2291 | rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, |
2292 | crypt_stat->key_size); | 2292 | crypt_stat->key_size); |
2293 | if (rc < 0) { | 2293 | if (rc < 0) { |
2294 | mutex_unlock(tfm_mutex); | 2294 | mutex_unlock(tfm_mutex); |
2295 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " | 2295 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " |
2296 | "context; rc = [%d]\n", rc); | 2296 | "context; rc = [%d]\n", rc); |
2297 | goto out; | 2297 | goto out; |
2298 | } | 2298 | } |
2299 | rc = 0; | 2299 | rc = 0; |
2300 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the key\n", | 2300 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the key\n", |
2301 | crypt_stat->key_size); | 2301 | crypt_stat->key_size); |
2302 | rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg, | 2302 | rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg, |
2303 | (*key_rec).enc_key_size); | 2303 | (*key_rec).enc_key_size); |
2304 | mutex_unlock(tfm_mutex); | 2304 | mutex_unlock(tfm_mutex); |
2305 | if (rc) { | 2305 | if (rc) { |
2306 | printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); | 2306 | printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); |
2307 | goto out; | 2307 | goto out; |
2308 | } | 2308 | } |
2309 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 2309 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
2310 | if (ecryptfs_verbosity > 0) { | 2310 | if (ecryptfs_verbosity > 0) { |
2311 | ecryptfs_printk(KERN_DEBUG, "EFEK of size [%zd]:\n", | 2311 | ecryptfs_printk(KERN_DEBUG, "EFEK of size [%zd]:\n", |
2312 | key_rec->enc_key_size); | 2312 | key_rec->enc_key_size); |
2313 | ecryptfs_dump_hex(key_rec->enc_key, | 2313 | ecryptfs_dump_hex(key_rec->enc_key, |
2314 | key_rec->enc_key_size); | 2314 | key_rec->enc_key_size); |
2315 | } | 2315 | } |
2316 | encrypted_session_key_set: | 2316 | encrypted_session_key_set: |
2317 | /* This format is inspired by OpenPGP; see RFC 2440 | 2317 | /* This format is inspired by OpenPGP; see RFC 2440 |
2318 | * packet tag 3 */ | 2318 | * packet tag 3 */ |
2319 | max_packet_size = (1 /* Tag 3 identifier */ | 2319 | max_packet_size = (1 /* Tag 3 identifier */ |
2320 | + 3 /* Max Tag 3 packet size */ | 2320 | + 3 /* Max Tag 3 packet size */ |
2321 | + 1 /* Version */ | 2321 | + 1 /* Version */ |
2322 | + 1 /* Cipher code */ | 2322 | + 1 /* Cipher code */ |
2323 | + 1 /* S2K specifier */ | 2323 | + 1 /* S2K specifier */ |
2324 | + 1 /* Hash identifier */ | 2324 | + 1 /* Hash identifier */ |
2325 | + ECRYPTFS_SALT_SIZE /* Salt */ | 2325 | + ECRYPTFS_SALT_SIZE /* Salt */ |
2326 | + 1 /* Hash iterations */ | 2326 | + 1 /* Hash iterations */ |
2327 | + key_rec->enc_key_size); /* Encrypted key size */ | 2327 | + key_rec->enc_key_size); /* Encrypted key size */ |
2328 | if (max_packet_size > (*remaining_bytes)) { | 2328 | if (max_packet_size > (*remaining_bytes)) { |
2329 | printk(KERN_ERR "Packet too large; need up to [%td] bytes, but " | 2329 | printk(KERN_ERR "Packet too large; need up to [%td] bytes, but " |
2330 | "there are only [%td] available\n", max_packet_size, | 2330 | "there are only [%td] available\n", max_packet_size, |
2331 | (*remaining_bytes)); | 2331 | (*remaining_bytes)); |
2332 | rc = -EINVAL; | 2332 | rc = -EINVAL; |
2333 | goto out; | 2333 | goto out; |
2334 | } | 2334 | } |
2335 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; | 2335 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; |
2336 | /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3) | 2336 | /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3) |
2337 | * to get the number of octets in the actual Tag 3 packet */ | 2337 | * to get the number of octets in the actual Tag 3 packet */ |
2338 | rc = ecryptfs_write_packet_length(&dest[(*packet_size)], | 2338 | rc = ecryptfs_write_packet_length(&dest[(*packet_size)], |
2339 | (max_packet_size - 4), | 2339 | (max_packet_size - 4), |
2340 | &packet_size_length); | 2340 | &packet_size_length); |
2341 | if (rc) { | 2341 | if (rc) { |
2342 | printk(KERN_ERR "Error generating tag 3 packet header; cannot " | 2342 | printk(KERN_ERR "Error generating tag 3 packet header; cannot " |
2343 | "generate packet length. rc = [%d]\n", rc); | 2343 | "generate packet length. rc = [%d]\n", rc); |
2344 | goto out; | 2344 | goto out; |
2345 | } | 2345 | } |
2346 | (*packet_size) += packet_size_length; | 2346 | (*packet_size) += packet_size_length; |
2347 | dest[(*packet_size)++] = 0x04; /* version 4 */ | 2347 | dest[(*packet_size)++] = 0x04; /* version 4 */ |
2348 | /* TODO: Break from RFC2440 so that arbitrary ciphers can be | 2348 | /* TODO: Break from RFC2440 so that arbitrary ciphers can be |
2349 | * specified with strings */ | 2349 | * specified with strings */ |
2350 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat->cipher, | 2350 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat->cipher, |
2351 | crypt_stat->key_size); | 2351 | crypt_stat->key_size); |
2352 | if (cipher_code == 0) { | 2352 | if (cipher_code == 0) { |
2353 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " | 2353 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " |
2354 | "cipher [%s]\n", crypt_stat->cipher); | 2354 | "cipher [%s]\n", crypt_stat->cipher); |
2355 | rc = -EINVAL; | 2355 | rc = -EINVAL; |
2356 | goto out; | 2356 | goto out; |
2357 | } | 2357 | } |
2358 | dest[(*packet_size)++] = cipher_code; | 2358 | dest[(*packet_size)++] = cipher_code; |
2359 | dest[(*packet_size)++] = 0x03; /* S2K */ | 2359 | dest[(*packet_size)++] = 0x03; /* S2K */ |
2360 | dest[(*packet_size)++] = 0x01; /* MD5 (TODO: parameterize) */ | 2360 | dest[(*packet_size)++] = 0x01; /* MD5 (TODO: parameterize) */ |
2361 | memcpy(&dest[(*packet_size)], auth_tok->token.password.salt, | 2361 | memcpy(&dest[(*packet_size)], auth_tok->token.password.salt, |
2362 | ECRYPTFS_SALT_SIZE); | 2362 | ECRYPTFS_SALT_SIZE); |
2363 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ | 2363 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ |
2364 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ | 2364 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ |
2365 | memcpy(&dest[(*packet_size)], key_rec->enc_key, | 2365 | memcpy(&dest[(*packet_size)], key_rec->enc_key, |
2366 | key_rec->enc_key_size); | 2366 | key_rec->enc_key_size); |
2367 | (*packet_size) += key_rec->enc_key_size; | 2367 | (*packet_size) += key_rec->enc_key_size; |
2368 | out: | 2368 | out: |
2369 | if (rc) | 2369 | if (rc) |
2370 | (*packet_size) = 0; | 2370 | (*packet_size) = 0; |
2371 | else | 2371 | else |
2372 | (*remaining_bytes) -= (*packet_size); | 2372 | (*remaining_bytes) -= (*packet_size); |
2373 | return rc; | 2373 | return rc; |
2374 | } | 2374 | } |
2375 | 2375 | ||
2376 | struct kmem_cache *ecryptfs_key_record_cache; | 2376 | struct kmem_cache *ecryptfs_key_record_cache; |
2377 | 2377 | ||
2378 | /** | 2378 | /** |
2379 | * ecryptfs_generate_key_packet_set | 2379 | * ecryptfs_generate_key_packet_set |
2380 | * @dest_base: Virtual address from which to write the key record set | 2380 | * @dest_base: Virtual address from which to write the key record set |
2381 | * @crypt_stat: The cryptographic context from which the | 2381 | * @crypt_stat: The cryptographic context from which the |
2382 | * authentication tokens will be retrieved | 2382 | * authentication tokens will be retrieved |
2383 | * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat | 2383 | * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat |
2384 | * for the global parameters | 2384 | * for the global parameters |
2385 | * @len: The amount written | 2385 | * @len: The amount written |
2386 | * @max: The maximum amount of data allowed to be written | 2386 | * @max: The maximum amount of data allowed to be written |
2387 | * | 2387 | * |
2388 | * Generates a key packet set and writes it to the virtual address | 2388 | * Generates a key packet set and writes it to the virtual address |
2389 | * passed in. | 2389 | * passed in. |
2390 | * | 2390 | * |
2391 | * Returns zero on success; non-zero on error. | 2391 | * Returns zero on success; non-zero on error. |
2392 | */ | 2392 | */ |
2393 | int | 2393 | int |
2394 | ecryptfs_generate_key_packet_set(char *dest_base, | 2394 | ecryptfs_generate_key_packet_set(char *dest_base, |
2395 | struct ecryptfs_crypt_stat *crypt_stat, | 2395 | struct ecryptfs_crypt_stat *crypt_stat, |
2396 | struct dentry *ecryptfs_dentry, size_t *len, | 2396 | struct dentry *ecryptfs_dentry, size_t *len, |
2397 | size_t max) | 2397 | size_t max) |
2398 | { | 2398 | { |
2399 | struct ecryptfs_auth_tok *auth_tok; | 2399 | struct ecryptfs_auth_tok *auth_tok; |
2400 | struct key *auth_tok_key = NULL; | 2400 | struct key *auth_tok_key = NULL; |
2401 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 2401 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
2402 | &ecryptfs_superblock_to_private( | 2402 | &ecryptfs_superblock_to_private( |
2403 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 2403 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
2404 | size_t written; | 2404 | size_t written; |
2405 | struct ecryptfs_key_record *key_rec; | 2405 | struct ecryptfs_key_record *key_rec; |
2406 | struct ecryptfs_key_sig *key_sig; | 2406 | struct ecryptfs_key_sig *key_sig; |
2407 | int rc = 0; | 2407 | int rc = 0; |
2408 | 2408 | ||
2409 | (*len) = 0; | 2409 | (*len) = 0; |
2410 | mutex_lock(&crypt_stat->keysig_list_mutex); | 2410 | mutex_lock(&crypt_stat->keysig_list_mutex); |
2411 | key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL); | 2411 | key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL); |
2412 | if (!key_rec) { | 2412 | if (!key_rec) { |
2413 | rc = -ENOMEM; | 2413 | rc = -ENOMEM; |
2414 | goto out; | 2414 | goto out; |
2415 | } | 2415 | } |
2416 | list_for_each_entry(key_sig, &crypt_stat->keysig_list, | 2416 | list_for_each_entry(key_sig, &crypt_stat->keysig_list, |
2417 | crypt_stat_list) { | 2417 | crypt_stat_list) { |
2418 | memset(key_rec, 0, sizeof(*key_rec)); | 2418 | memset(key_rec, 0, sizeof(*key_rec)); |
2419 | rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key, | 2419 | rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key, |
2420 | &auth_tok, | 2420 | &auth_tok, |
2421 | mount_crypt_stat, | 2421 | mount_crypt_stat, |
2422 | key_sig->keysig); | 2422 | key_sig->keysig); |
2423 | if (rc) { | 2423 | if (rc) { |
2424 | printk(KERN_WARNING "Unable to retrieve auth tok with " | 2424 | printk(KERN_WARNING "Unable to retrieve auth tok with " |
2425 | "sig = [%s]\n", key_sig->keysig); | 2425 | "sig = [%s]\n", key_sig->keysig); |
2426 | rc = process_find_global_auth_tok_for_sig_err(rc); | 2426 | rc = process_find_global_auth_tok_for_sig_err(rc); |
2427 | goto out_free; | 2427 | goto out_free; |
2428 | } | 2428 | } |
2429 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { | 2429 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { |
2430 | rc = write_tag_3_packet((dest_base + (*len)), | 2430 | rc = write_tag_3_packet((dest_base + (*len)), |
2431 | &max, auth_tok, | 2431 | &max, auth_tok, |
2432 | crypt_stat, key_rec, | 2432 | crypt_stat, key_rec, |
2433 | &written); | 2433 | &written); |
2434 | up_write(&(auth_tok_key->sem)); | 2434 | up_write(&(auth_tok_key->sem)); |
2435 | key_put(auth_tok_key); | 2435 | key_put(auth_tok_key); |
2436 | if (rc) { | 2436 | if (rc) { |
2437 | ecryptfs_printk(KERN_WARNING, "Error " | 2437 | ecryptfs_printk(KERN_WARNING, "Error " |
2438 | "writing tag 3 packet\n"); | 2438 | "writing tag 3 packet\n"); |
2439 | goto out_free; | 2439 | goto out_free; |
2440 | } | 2440 | } |
2441 | (*len) += written; | 2441 | (*len) += written; |
2442 | /* Write auth tok signature packet */ | 2442 | /* Write auth tok signature packet */ |
2443 | rc = write_tag_11_packet((dest_base + (*len)), &max, | 2443 | rc = write_tag_11_packet((dest_base + (*len)), &max, |
2444 | key_rec->sig, | 2444 | key_rec->sig, |
2445 | ECRYPTFS_SIG_SIZE, &written); | 2445 | ECRYPTFS_SIG_SIZE, &written); |
2446 | if (rc) { | 2446 | if (rc) { |
2447 | ecryptfs_printk(KERN_ERR, "Error writing " | 2447 | ecryptfs_printk(KERN_ERR, "Error writing " |
2448 | "auth tok signature packet\n"); | 2448 | "auth tok signature packet\n"); |
2449 | goto out_free; | 2449 | goto out_free; |
2450 | } | 2450 | } |
2451 | (*len) += written; | 2451 | (*len) += written; |
2452 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | 2452 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { |
2453 | rc = write_tag_1_packet(dest_base + (*len), &max, | 2453 | rc = write_tag_1_packet(dest_base + (*len), &max, |
2454 | auth_tok_key, auth_tok, | 2454 | auth_tok_key, auth_tok, |
2455 | crypt_stat, key_rec, &written); | 2455 | crypt_stat, key_rec, &written); |
2456 | if (rc) { | 2456 | if (rc) { |
2457 | ecryptfs_printk(KERN_WARNING, "Error " | 2457 | ecryptfs_printk(KERN_WARNING, "Error " |
2458 | "writing tag 1 packet\n"); | 2458 | "writing tag 1 packet\n"); |
2459 | goto out_free; | 2459 | goto out_free; |
2460 | } | 2460 | } |
2461 | (*len) += written; | 2461 | (*len) += written; |
2462 | } else { | 2462 | } else { |
2463 | up_write(&(auth_tok_key->sem)); | 2463 | up_write(&(auth_tok_key->sem)); |
2464 | key_put(auth_tok_key); | 2464 | key_put(auth_tok_key); |
2465 | ecryptfs_printk(KERN_WARNING, "Unsupported " | 2465 | ecryptfs_printk(KERN_WARNING, "Unsupported " |
2466 | "authentication token type\n"); | 2466 | "authentication token type\n"); |
2467 | rc = -EINVAL; | 2467 | rc = -EINVAL; |
2468 | goto out_free; | 2468 | goto out_free; |
2469 | } | 2469 | } |
2470 | } | 2470 | } |
2471 | if (likely(max > 0)) { | 2471 | if (likely(max > 0)) { |
2472 | dest_base[(*len)] = 0x00; | 2472 | dest_base[(*len)] = 0x00; |
2473 | } else { | 2473 | } else { |
2474 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); | 2474 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); |
2475 | rc = -EIO; | 2475 | rc = -EIO; |
2476 | } | 2476 | } |
2477 | out_free: | 2477 | out_free: |
2478 | kmem_cache_free(ecryptfs_key_record_cache, key_rec); | 2478 | kmem_cache_free(ecryptfs_key_record_cache, key_rec); |
2479 | out: | 2479 | out: |
2480 | if (rc) | 2480 | if (rc) |
2481 | (*len) = 0; | 2481 | (*len) = 0; |
2482 | mutex_unlock(&crypt_stat->keysig_list_mutex); | 2482 | mutex_unlock(&crypt_stat->keysig_list_mutex); |
2483 | return rc; | 2483 | return rc; |
2484 | } | 2484 | } |
2485 | 2485 | ||
2486 | struct kmem_cache *ecryptfs_key_sig_cache; | 2486 | struct kmem_cache *ecryptfs_key_sig_cache; |
2487 | 2487 | ||
2488 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig) | 2488 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig) |
2489 | { | 2489 | { |
2490 | struct ecryptfs_key_sig *new_key_sig; | 2490 | struct ecryptfs_key_sig *new_key_sig; |
2491 | 2491 | ||
2492 | new_key_sig = kmem_cache_alloc(ecryptfs_key_sig_cache, GFP_KERNEL); | 2492 | new_key_sig = kmem_cache_alloc(ecryptfs_key_sig_cache, GFP_KERNEL); |
2493 | if (!new_key_sig) { | 2493 | if (!new_key_sig) { |
2494 | printk(KERN_ERR | 2494 | printk(KERN_ERR |
2495 | "Error allocating from ecryptfs_key_sig_cache\n"); | 2495 | "Error allocating from ecryptfs_key_sig_cache\n"); |
2496 | return -ENOMEM; | 2496 | return -ENOMEM; |
2497 | } | 2497 | } |
2498 | memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); | 2498 | memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); |
2499 | new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 2499 | new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
2500 | /* Caller must hold keysig_list_mutex */ | 2500 | /* Caller must hold keysig_list_mutex */ |
2501 | list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); | 2501 | list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); |
2502 | 2502 | ||
2503 | return 0; | 2503 | return 0; |
2504 | } | 2504 | } |
2505 | 2505 | ||
2506 | struct kmem_cache *ecryptfs_global_auth_tok_cache; | 2506 | struct kmem_cache *ecryptfs_global_auth_tok_cache; |
2507 | 2507 | ||
2508 | int | 2508 | int |
2509 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 2509 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
2510 | char *sig, u32 global_auth_tok_flags) | 2510 | char *sig, u32 global_auth_tok_flags) |
2511 | { | 2511 | { |
2512 | struct ecryptfs_global_auth_tok *new_auth_tok; | 2512 | struct ecryptfs_global_auth_tok *new_auth_tok; |
2513 | int rc = 0; | 2513 | int rc = 0; |
2514 | 2514 | ||
2515 | new_auth_tok = kmem_cache_zalloc(ecryptfs_global_auth_tok_cache, | 2515 | new_auth_tok = kmem_cache_zalloc(ecryptfs_global_auth_tok_cache, |
2516 | GFP_KERNEL); | 2516 | GFP_KERNEL); |
2517 | if (!new_auth_tok) { | 2517 | if (!new_auth_tok) { |
2518 | rc = -ENOMEM; | 2518 | rc = -ENOMEM; |
2519 | printk(KERN_ERR "Error allocating from " | 2519 | printk(KERN_ERR "Error allocating from " |
2520 | "ecryptfs_global_auth_tok_cache\n"); | 2520 | "ecryptfs_global_auth_tok_cache\n"); |
2521 | goto out; | 2521 | goto out; |
2522 | } | 2522 | } |
2523 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); | 2523 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); |
2524 | new_auth_tok->flags = global_auth_tok_flags; | 2524 | new_auth_tok->flags = global_auth_tok_flags; |
2525 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 2525 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
2526 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | 2526 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
2527 | list_add(&new_auth_tok->mount_crypt_stat_list, | 2527 | list_add(&new_auth_tok->mount_crypt_stat_list, |
2528 | &mount_crypt_stat->global_auth_tok_list); | 2528 | &mount_crypt_stat->global_auth_tok_list); |
2529 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | 2529 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); |
2530 | out: | 2530 | out: |
2531 | return rc; | 2531 | return rc; |
2532 | } | 2532 | } |
2533 | 2533 | ||
2534 | 2534 |
fs/ecryptfs/main.c
1 | /** | 1 | /** |
2 | * eCryptfs: Linux filesystem encryption layer | 2 | * eCryptfs: Linux filesystem encryption layer |
3 | * | 3 | * |
4 | * Copyright (C) 1997-2003 Erez Zadok | 4 | * Copyright (C) 1997-2003 Erez Zadok |
5 | * Copyright (C) 2001-2003 Stony Brook University | 5 | * Copyright (C) 2001-2003 Stony Brook University |
6 | * Copyright (C) 2004-2007 International Business Machines Corp. | 6 | * Copyright (C) 2004-2007 International Business Machines Corp. |
7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
8 | * Michael C. Thompson <mcthomps@us.ibm.com> | 8 | * Michael C. Thompson <mcthomps@us.ibm.com> |
9 | * Tyler Hicks <tyhicks@ou.edu> | 9 | * Tyler Hicks <tyhicks@ou.edu> |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
13 | * published by the Free Software Foundation; either version 2 of the | 13 | * published by the Free Software Foundation; either version 2 of the |
14 | * License, or (at your option) any later version. | 14 | * License, or (at your option) any later version. |
15 | * | 15 | * |
16 | * This program is distributed in the hope that it will be useful, but | 16 | * This program is distributed in the hope that it will be useful, but |
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
19 | * General Public License for more details. | 19 | * General Public License for more details. |
20 | * | 20 | * |
21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | 23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
24 | * 02111-1307, USA. | 24 | * 02111-1307, USA. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/dcache.h> | 27 | #include <linux/dcache.h> |
28 | #include <linux/file.h> | 28 | #include <linux/file.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/namei.h> | 30 | #include <linux/namei.h> |
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
33 | #include <linux/mount.h> | 33 | #include <linux/mount.h> |
34 | #include <linux/pagemap.h> | 34 | #include <linux/pagemap.h> |
35 | #include <linux/key.h> | 35 | #include <linux/key.h> |
36 | #include <linux/parser.h> | 36 | #include <linux/parser.h> |
37 | #include <linux/fs_stack.h> | 37 | #include <linux/fs_stack.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/magic.h> | 39 | #include <linux/magic.h> |
40 | #include "ecryptfs_kernel.h" | 40 | #include "ecryptfs_kernel.h" |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * Module parameter that defines the ecryptfs_verbosity level. | 43 | * Module parameter that defines the ecryptfs_verbosity level. |
44 | */ | 44 | */ |
45 | int ecryptfs_verbosity = 0; | 45 | int ecryptfs_verbosity = 0; |
46 | 46 | ||
47 | module_param(ecryptfs_verbosity, int, 0); | 47 | module_param(ecryptfs_verbosity, int, 0); |
48 | MODULE_PARM_DESC(ecryptfs_verbosity, | 48 | MODULE_PARM_DESC(ecryptfs_verbosity, |
49 | "Initial verbosity level (0 or 1; defaults to " | 49 | "Initial verbosity level (0 or 1; defaults to " |
50 | "0, which is Quiet)"); | 50 | "0, which is Quiet)"); |
51 | 51 | ||
52 | /** | 52 | /** |
53 | * Module parameter that defines the number of message buffer elements | 53 | * Module parameter that defines the number of message buffer elements |
54 | */ | 54 | */ |
55 | unsigned int ecryptfs_message_buf_len = ECRYPTFS_DEFAULT_MSG_CTX_ELEMS; | 55 | unsigned int ecryptfs_message_buf_len = ECRYPTFS_DEFAULT_MSG_CTX_ELEMS; |
56 | 56 | ||
57 | module_param(ecryptfs_message_buf_len, uint, 0); | 57 | module_param(ecryptfs_message_buf_len, uint, 0); |
58 | MODULE_PARM_DESC(ecryptfs_message_buf_len, | 58 | MODULE_PARM_DESC(ecryptfs_message_buf_len, |
59 | "Number of message buffer elements"); | 59 | "Number of message buffer elements"); |
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Module parameter that defines the maximum guaranteed amount of time to wait | 62 | * Module parameter that defines the maximum guaranteed amount of time to wait |
63 | * for a response from ecryptfsd. The actual sleep time will be, more than | 63 | * for a response from ecryptfsd. The actual sleep time will be, more than |
64 | * likely, a small amount greater than this specified value, but only less if | 64 | * likely, a small amount greater than this specified value, but only less if |
65 | * the message successfully arrives. | 65 | * the message successfully arrives. |
66 | */ | 66 | */ |
67 | signed long ecryptfs_message_wait_timeout = ECRYPTFS_MAX_MSG_CTX_TTL / HZ; | 67 | signed long ecryptfs_message_wait_timeout = ECRYPTFS_MAX_MSG_CTX_TTL / HZ; |
68 | 68 | ||
69 | module_param(ecryptfs_message_wait_timeout, long, 0); | 69 | module_param(ecryptfs_message_wait_timeout, long, 0); |
70 | MODULE_PARM_DESC(ecryptfs_message_wait_timeout, | 70 | MODULE_PARM_DESC(ecryptfs_message_wait_timeout, |
71 | "Maximum number of seconds that an operation will " | 71 | "Maximum number of seconds that an operation will " |
72 | "sleep while waiting for a message response from " | 72 | "sleep while waiting for a message response from " |
73 | "userspace"); | 73 | "userspace"); |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * Module parameter that is an estimate of the maximum number of users | 76 | * Module parameter that is an estimate of the maximum number of users |
77 | * that will be concurrently using eCryptfs. Set this to the right | 77 | * that will be concurrently using eCryptfs. Set this to the right |
78 | * value to balance performance and memory use. | 78 | * value to balance performance and memory use. |
79 | */ | 79 | */ |
80 | unsigned int ecryptfs_number_of_users = ECRYPTFS_DEFAULT_NUM_USERS; | 80 | unsigned int ecryptfs_number_of_users = ECRYPTFS_DEFAULT_NUM_USERS; |
81 | 81 | ||
82 | module_param(ecryptfs_number_of_users, uint, 0); | 82 | module_param(ecryptfs_number_of_users, uint, 0); |
83 | MODULE_PARM_DESC(ecryptfs_number_of_users, "An estimate of the number of " | 83 | MODULE_PARM_DESC(ecryptfs_number_of_users, "An estimate of the number of " |
84 | "concurrent users of eCryptfs"); | 84 | "concurrent users of eCryptfs"); |
85 | 85 | ||
86 | void __ecryptfs_printk(const char *fmt, ...) | 86 | void __ecryptfs_printk(const char *fmt, ...) |
87 | { | 87 | { |
88 | va_list args; | 88 | va_list args; |
89 | va_start(args, fmt); | 89 | va_start(args, fmt); |
90 | if (fmt[1] == '7') { /* KERN_DEBUG */ | 90 | if (fmt[1] == '7') { /* KERN_DEBUG */ |
91 | if (ecryptfs_verbosity >= 1) | 91 | if (ecryptfs_verbosity >= 1) |
92 | vprintk(fmt, args); | 92 | vprintk(fmt, args); |
93 | } else | 93 | } else |
94 | vprintk(fmt, args); | 94 | vprintk(fmt, args); |
95 | va_end(args); | 95 | va_end(args); |
96 | } | 96 | } |
97 | 97 | ||
98 | /** | 98 | /** |
99 | * ecryptfs_init_lower_file | 99 | * ecryptfs_init_lower_file |
100 | * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with | 100 | * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with |
101 | * the lower dentry and the lower mount set | 101 | * the lower dentry and the lower mount set |
102 | * | 102 | * |
103 | * eCryptfs only ever keeps a single open file for every lower | 103 | * eCryptfs only ever keeps a single open file for every lower |
104 | * inode. All I/O operations to the lower inode occur through that | 104 | * inode. All I/O operations to the lower inode occur through that |
105 | * file. When the first eCryptfs dentry that interposes with the first | 105 | * file. When the first eCryptfs dentry that interposes with the first |
106 | * lower dentry for that inode is created, this function creates the | 106 | * lower dentry for that inode is created, this function creates the |
107 | * lower file struct and associates it with the eCryptfs | 107 | * lower file struct and associates it with the eCryptfs |
108 | * inode. When all eCryptfs files associated with the inode are released, the | 108 | * inode. When all eCryptfs files associated with the inode are released, the |
109 | * file is closed. | 109 | * file is closed. |
110 | * | 110 | * |
111 | * The lower file will be opened with read/write permissions, if | 111 | * The lower file will be opened with read/write permissions, if |
112 | * possible. Otherwise, it is opened read-only. | 112 | * possible. Otherwise, it is opened read-only. |
113 | * | 113 | * |
114 | * This function does nothing if a lower file is already | 114 | * This function does nothing if a lower file is already |
115 | * associated with the eCryptfs inode. | 115 | * associated with the eCryptfs inode. |
116 | * | 116 | * |
117 | * Returns zero on success; non-zero otherwise | 117 | * Returns zero on success; non-zero otherwise |
118 | */ | 118 | */ |
119 | static int ecryptfs_init_lower_file(struct dentry *dentry, | 119 | static int ecryptfs_init_lower_file(struct dentry *dentry, |
120 | struct file **lower_file) | 120 | struct file **lower_file) |
121 | { | 121 | { |
122 | const struct cred *cred = current_cred(); | 122 | const struct cred *cred = current_cred(); |
123 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 123 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
124 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | 124 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); |
125 | int rc; | 125 | int rc; |
126 | 126 | ||
127 | rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, | 127 | rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, |
128 | cred); | 128 | cred); |
129 | if (rc) { | 129 | if (rc) { |
130 | printk(KERN_ERR "Error opening lower file " | 130 | printk(KERN_ERR "Error opening lower file " |
131 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | 131 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " |
132 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); | 132 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); |
133 | (*lower_file) = NULL; | 133 | (*lower_file) = NULL; |
134 | } | 134 | } |
135 | return rc; | 135 | return rc; |
136 | } | 136 | } |
137 | 137 | ||
138 | int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode) | 138 | int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode) |
139 | { | 139 | { |
140 | struct ecryptfs_inode_info *inode_info; | 140 | struct ecryptfs_inode_info *inode_info; |
141 | int count, rc = 0; | 141 | int count, rc = 0; |
142 | 142 | ||
143 | inode_info = ecryptfs_inode_to_private(inode); | 143 | inode_info = ecryptfs_inode_to_private(inode); |
144 | mutex_lock(&inode_info->lower_file_mutex); | 144 | mutex_lock(&inode_info->lower_file_mutex); |
145 | count = atomic_inc_return(&inode_info->lower_file_count); | 145 | count = atomic_inc_return(&inode_info->lower_file_count); |
146 | if (WARN_ON_ONCE(count < 1)) | 146 | if (WARN_ON_ONCE(count < 1)) |
147 | rc = -EINVAL; | 147 | rc = -EINVAL; |
148 | else if (count == 1) { | 148 | else if (count == 1) { |
149 | rc = ecryptfs_init_lower_file(dentry, | 149 | rc = ecryptfs_init_lower_file(dentry, |
150 | &inode_info->lower_file); | 150 | &inode_info->lower_file); |
151 | if (rc) | 151 | if (rc) |
152 | atomic_set(&inode_info->lower_file_count, 0); | 152 | atomic_set(&inode_info->lower_file_count, 0); |
153 | } | 153 | } |
154 | mutex_unlock(&inode_info->lower_file_mutex); | 154 | mutex_unlock(&inode_info->lower_file_mutex); |
155 | return rc; | 155 | return rc; |
156 | } | 156 | } |
157 | 157 | ||
158 | void ecryptfs_put_lower_file(struct inode *inode) | 158 | void ecryptfs_put_lower_file(struct inode *inode) |
159 | { | 159 | { |
160 | struct ecryptfs_inode_info *inode_info; | 160 | struct ecryptfs_inode_info *inode_info; |
161 | 161 | ||
162 | inode_info = ecryptfs_inode_to_private(inode); | 162 | inode_info = ecryptfs_inode_to_private(inode); |
163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, | 163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, |
164 | &inode_info->lower_file_mutex)) { | 164 | &inode_info->lower_file_mutex)) { |
165 | fput(inode_info->lower_file); | 165 | fput(inode_info->lower_file); |
166 | inode_info->lower_file = NULL; | 166 | inode_info->lower_file = NULL; |
167 | mutex_unlock(&inode_info->lower_file_mutex); | 167 | mutex_unlock(&inode_info->lower_file_mutex); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, | 171 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
172 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, | 172 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, |
173 | ecryptfs_opt_ecryptfs_key_bytes, | 173 | ecryptfs_opt_ecryptfs_key_bytes, |
174 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, | 174 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, |
175 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, | 175 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, |
176 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, | 176 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, |
177 | ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, | 177 | ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, |
178 | ecryptfs_opt_check_dev_ruid, | ||
178 | ecryptfs_opt_err }; | 179 | ecryptfs_opt_err }; |
179 | 180 | ||
180 | static const match_table_t tokens = { | 181 | static const match_table_t tokens = { |
181 | {ecryptfs_opt_sig, "sig=%s"}, | 182 | {ecryptfs_opt_sig, "sig=%s"}, |
182 | {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"}, | 183 | {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"}, |
183 | {ecryptfs_opt_cipher, "cipher=%s"}, | 184 | {ecryptfs_opt_cipher, "cipher=%s"}, |
184 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, | 185 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, |
185 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, | 186 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, |
186 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, | 187 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, |
187 | {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, | 188 | {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, |
188 | {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, | 189 | {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, |
189 | {ecryptfs_opt_fnek_sig, "ecryptfs_fnek_sig=%s"}, | 190 | {ecryptfs_opt_fnek_sig, "ecryptfs_fnek_sig=%s"}, |
190 | {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"}, | 191 | {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"}, |
191 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, | 192 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, |
192 | {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, | 193 | {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, |
193 | {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, | 194 | {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, |
195 | {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, | ||
194 | {ecryptfs_opt_err, NULL} | 196 | {ecryptfs_opt_err, NULL} |
195 | }; | 197 | }; |
196 | 198 | ||
197 | static int ecryptfs_init_global_auth_toks( | 199 | static int ecryptfs_init_global_auth_toks( |
198 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 200 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
199 | { | 201 | { |
200 | struct ecryptfs_global_auth_tok *global_auth_tok; | 202 | struct ecryptfs_global_auth_tok *global_auth_tok; |
201 | struct ecryptfs_auth_tok *auth_tok; | 203 | struct ecryptfs_auth_tok *auth_tok; |
202 | int rc = 0; | 204 | int rc = 0; |
203 | 205 | ||
204 | list_for_each_entry(global_auth_tok, | 206 | list_for_each_entry(global_auth_tok, |
205 | &mount_crypt_stat->global_auth_tok_list, | 207 | &mount_crypt_stat->global_auth_tok_list, |
206 | mount_crypt_stat_list) { | 208 | mount_crypt_stat_list) { |
207 | rc = ecryptfs_keyring_auth_tok_for_sig( | 209 | rc = ecryptfs_keyring_auth_tok_for_sig( |
208 | &global_auth_tok->global_auth_tok_key, &auth_tok, | 210 | &global_auth_tok->global_auth_tok_key, &auth_tok, |
209 | global_auth_tok->sig); | 211 | global_auth_tok->sig); |
210 | if (rc) { | 212 | if (rc) { |
211 | printk(KERN_ERR "Could not find valid key in user " | 213 | printk(KERN_ERR "Could not find valid key in user " |
212 | "session keyring for sig specified in mount " | 214 | "session keyring for sig specified in mount " |
213 | "option: [%s]\n", global_auth_tok->sig); | 215 | "option: [%s]\n", global_auth_tok->sig); |
214 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; | 216 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
215 | goto out; | 217 | goto out; |
216 | } else { | 218 | } else { |
217 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; | 219 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
218 | up_write(&(global_auth_tok->global_auth_tok_key)->sem); | 220 | up_write(&(global_auth_tok->global_auth_tok_key)->sem); |
219 | } | 221 | } |
220 | } | 222 | } |
221 | out: | 223 | out: |
222 | return rc; | 224 | return rc; |
223 | } | 225 | } |
224 | 226 | ||
225 | static void ecryptfs_init_mount_crypt_stat( | 227 | static void ecryptfs_init_mount_crypt_stat( |
226 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 228 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
227 | { | 229 | { |
228 | memset((void *)mount_crypt_stat, 0, | 230 | memset((void *)mount_crypt_stat, 0, |
229 | sizeof(struct ecryptfs_mount_crypt_stat)); | 231 | sizeof(struct ecryptfs_mount_crypt_stat)); |
230 | INIT_LIST_HEAD(&mount_crypt_stat->global_auth_tok_list); | 232 | INIT_LIST_HEAD(&mount_crypt_stat->global_auth_tok_list); |
231 | mutex_init(&mount_crypt_stat->global_auth_tok_list_mutex); | 233 | mutex_init(&mount_crypt_stat->global_auth_tok_list_mutex); |
232 | mount_crypt_stat->flags |= ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED; | 234 | mount_crypt_stat->flags |= ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED; |
233 | } | 235 | } |
234 | 236 | ||
235 | /** | 237 | /** |
236 | * ecryptfs_parse_options | 238 | * ecryptfs_parse_options |
237 | * @sb: The ecryptfs super block | 239 | * @sb: The ecryptfs super block |
238 | * @options: The options passed to the kernel | 240 | * @options: The options passed to the kernel |
241 | * @check_ruid: set to 1 if device uid should be checked against the ruid | ||
239 | * | 242 | * |
240 | * Parse mount options: | 243 | * Parse mount options: |
241 | * debug=N - ecryptfs_verbosity level for debug output | 244 | * debug=N - ecryptfs_verbosity level for debug output |
242 | * sig=XXX - description(signature) of the key to use | 245 | * sig=XXX - description(signature) of the key to use |
243 | * | 246 | * |
244 | * Returns the dentry object of the lower-level (lower/interposed) | 247 | * Returns the dentry object of the lower-level (lower/interposed) |
245 | * directory; We want to mount our stackable file system on top of | 248 | * directory; We want to mount our stackable file system on top of |
246 | * that lower directory. | 249 | * that lower directory. |
247 | * | 250 | * |
248 | * The signature of the key to use must be the description of a key | 251 | * The signature of the key to use must be the description of a key |
249 | * already in the keyring. Mounting will fail if the key can not be | 252 | * already in the keyring. Mounting will fail if the key can not be |
250 | * found. | 253 | * found. |
251 | * | 254 | * |
252 | * Returns zero on success; non-zero on error | 255 | * Returns zero on success; non-zero on error |
253 | */ | 256 | */ |
254 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) | 257 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, |
258 | uid_t *check_ruid) | ||
255 | { | 259 | { |
256 | char *p; | 260 | char *p; |
257 | int rc = 0; | 261 | int rc = 0; |
258 | int sig_set = 0; | 262 | int sig_set = 0; |
259 | int cipher_name_set = 0; | 263 | int cipher_name_set = 0; |
260 | int fn_cipher_name_set = 0; | 264 | int fn_cipher_name_set = 0; |
261 | int cipher_key_bytes; | 265 | int cipher_key_bytes; |
262 | int cipher_key_bytes_set = 0; | 266 | int cipher_key_bytes_set = 0; |
263 | int fn_cipher_key_bytes; | 267 | int fn_cipher_key_bytes; |
264 | int fn_cipher_key_bytes_set = 0; | 268 | int fn_cipher_key_bytes_set = 0; |
265 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 269 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
266 | &sbi->mount_crypt_stat; | 270 | &sbi->mount_crypt_stat; |
267 | substring_t args[MAX_OPT_ARGS]; | 271 | substring_t args[MAX_OPT_ARGS]; |
268 | int token; | 272 | int token; |
269 | char *sig_src; | 273 | char *sig_src; |
270 | char *cipher_name_dst; | 274 | char *cipher_name_dst; |
271 | char *cipher_name_src; | 275 | char *cipher_name_src; |
272 | char *fn_cipher_name_dst; | 276 | char *fn_cipher_name_dst; |
273 | char *fn_cipher_name_src; | 277 | char *fn_cipher_name_src; |
274 | char *fnek_dst; | 278 | char *fnek_dst; |
275 | char *fnek_src; | 279 | char *fnek_src; |
276 | char *cipher_key_bytes_src; | 280 | char *cipher_key_bytes_src; |
277 | char *fn_cipher_key_bytes_src; | 281 | char *fn_cipher_key_bytes_src; |
278 | 282 | ||
283 | *check_ruid = 0; | ||
284 | |||
279 | if (!options) { | 285 | if (!options) { |
280 | rc = -EINVAL; | 286 | rc = -EINVAL; |
281 | goto out; | 287 | goto out; |
282 | } | 288 | } |
283 | ecryptfs_init_mount_crypt_stat(mount_crypt_stat); | 289 | ecryptfs_init_mount_crypt_stat(mount_crypt_stat); |
284 | while ((p = strsep(&options, ",")) != NULL) { | 290 | while ((p = strsep(&options, ",")) != NULL) { |
285 | if (!*p) | 291 | if (!*p) |
286 | continue; | 292 | continue; |
287 | token = match_token(p, tokens, args); | 293 | token = match_token(p, tokens, args); |
288 | switch (token) { | 294 | switch (token) { |
289 | case ecryptfs_opt_sig: | 295 | case ecryptfs_opt_sig: |
290 | case ecryptfs_opt_ecryptfs_sig: | 296 | case ecryptfs_opt_ecryptfs_sig: |
291 | sig_src = args[0].from; | 297 | sig_src = args[0].from; |
292 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, | 298 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, |
293 | sig_src, 0); | 299 | sig_src, 0); |
294 | if (rc) { | 300 | if (rc) { |
295 | printk(KERN_ERR "Error attempting to register " | 301 | printk(KERN_ERR "Error attempting to register " |
296 | "global sig; rc = [%d]\n", rc); | 302 | "global sig; rc = [%d]\n", rc); |
297 | goto out; | 303 | goto out; |
298 | } | 304 | } |
299 | sig_set = 1; | 305 | sig_set = 1; |
300 | break; | 306 | break; |
301 | case ecryptfs_opt_cipher: | 307 | case ecryptfs_opt_cipher: |
302 | case ecryptfs_opt_ecryptfs_cipher: | 308 | case ecryptfs_opt_ecryptfs_cipher: |
303 | cipher_name_src = args[0].from; | 309 | cipher_name_src = args[0].from; |
304 | cipher_name_dst = | 310 | cipher_name_dst = |
305 | mount_crypt_stat-> | 311 | mount_crypt_stat-> |
306 | global_default_cipher_name; | 312 | global_default_cipher_name; |
307 | strncpy(cipher_name_dst, cipher_name_src, | 313 | strncpy(cipher_name_dst, cipher_name_src, |
308 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); | 314 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
309 | cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; | 315 | cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; |
310 | cipher_name_set = 1; | 316 | cipher_name_set = 1; |
311 | break; | 317 | break; |
312 | case ecryptfs_opt_ecryptfs_key_bytes: | 318 | case ecryptfs_opt_ecryptfs_key_bytes: |
313 | cipher_key_bytes_src = args[0].from; | 319 | cipher_key_bytes_src = args[0].from; |
314 | cipher_key_bytes = | 320 | cipher_key_bytes = |
315 | (int)simple_strtol(cipher_key_bytes_src, | 321 | (int)simple_strtol(cipher_key_bytes_src, |
316 | &cipher_key_bytes_src, 0); | 322 | &cipher_key_bytes_src, 0); |
317 | mount_crypt_stat->global_default_cipher_key_size = | 323 | mount_crypt_stat->global_default_cipher_key_size = |
318 | cipher_key_bytes; | 324 | cipher_key_bytes; |
319 | cipher_key_bytes_set = 1; | 325 | cipher_key_bytes_set = 1; |
320 | break; | 326 | break; |
321 | case ecryptfs_opt_passthrough: | 327 | case ecryptfs_opt_passthrough: |
322 | mount_crypt_stat->flags |= | 328 | mount_crypt_stat->flags |= |
323 | ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED; | 329 | ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED; |
324 | break; | 330 | break; |
325 | case ecryptfs_opt_xattr_metadata: | 331 | case ecryptfs_opt_xattr_metadata: |
326 | mount_crypt_stat->flags |= | 332 | mount_crypt_stat->flags |= |
327 | ECRYPTFS_XATTR_METADATA_ENABLED; | 333 | ECRYPTFS_XATTR_METADATA_ENABLED; |
328 | break; | 334 | break; |
329 | case ecryptfs_opt_encrypted_view: | 335 | case ecryptfs_opt_encrypted_view: |
330 | mount_crypt_stat->flags |= | 336 | mount_crypt_stat->flags |= |
331 | ECRYPTFS_XATTR_METADATA_ENABLED; | 337 | ECRYPTFS_XATTR_METADATA_ENABLED; |
332 | mount_crypt_stat->flags |= | 338 | mount_crypt_stat->flags |= |
333 | ECRYPTFS_ENCRYPTED_VIEW_ENABLED; | 339 | ECRYPTFS_ENCRYPTED_VIEW_ENABLED; |
334 | break; | 340 | break; |
335 | case ecryptfs_opt_fnek_sig: | 341 | case ecryptfs_opt_fnek_sig: |
336 | fnek_src = args[0].from; | 342 | fnek_src = args[0].from; |
337 | fnek_dst = | 343 | fnek_dst = |
338 | mount_crypt_stat->global_default_fnek_sig; | 344 | mount_crypt_stat->global_default_fnek_sig; |
339 | strncpy(fnek_dst, fnek_src, ECRYPTFS_SIG_SIZE_HEX); | 345 | strncpy(fnek_dst, fnek_src, ECRYPTFS_SIG_SIZE_HEX); |
340 | mount_crypt_stat->global_default_fnek_sig[ | 346 | mount_crypt_stat->global_default_fnek_sig[ |
341 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 347 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
342 | rc = ecryptfs_add_global_auth_tok( | 348 | rc = ecryptfs_add_global_auth_tok( |
343 | mount_crypt_stat, | 349 | mount_crypt_stat, |
344 | mount_crypt_stat->global_default_fnek_sig, | 350 | mount_crypt_stat->global_default_fnek_sig, |
345 | ECRYPTFS_AUTH_TOK_FNEK); | 351 | ECRYPTFS_AUTH_TOK_FNEK); |
346 | if (rc) { | 352 | if (rc) { |
347 | printk(KERN_ERR "Error attempting to register " | 353 | printk(KERN_ERR "Error attempting to register " |
348 | "global fnek sig [%s]; rc = [%d]\n", | 354 | "global fnek sig [%s]; rc = [%d]\n", |
349 | mount_crypt_stat->global_default_fnek_sig, | 355 | mount_crypt_stat->global_default_fnek_sig, |
350 | rc); | 356 | rc); |
351 | goto out; | 357 | goto out; |
352 | } | 358 | } |
353 | mount_crypt_stat->flags |= | 359 | mount_crypt_stat->flags |= |
354 | (ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES | 360 | (ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES |
355 | | ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK); | 361 | | ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK); |
356 | break; | 362 | break; |
357 | case ecryptfs_opt_fn_cipher: | 363 | case ecryptfs_opt_fn_cipher: |
358 | fn_cipher_name_src = args[0].from; | 364 | fn_cipher_name_src = args[0].from; |
359 | fn_cipher_name_dst = | 365 | fn_cipher_name_dst = |
360 | mount_crypt_stat->global_default_fn_cipher_name; | 366 | mount_crypt_stat->global_default_fn_cipher_name; |
361 | strncpy(fn_cipher_name_dst, fn_cipher_name_src, | 367 | strncpy(fn_cipher_name_dst, fn_cipher_name_src, |
362 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); | 368 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
363 | mount_crypt_stat->global_default_fn_cipher_name[ | 369 | mount_crypt_stat->global_default_fn_cipher_name[ |
364 | ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; | 370 | ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; |
365 | fn_cipher_name_set = 1; | 371 | fn_cipher_name_set = 1; |
366 | break; | 372 | break; |
367 | case ecryptfs_opt_fn_cipher_key_bytes: | 373 | case ecryptfs_opt_fn_cipher_key_bytes: |
368 | fn_cipher_key_bytes_src = args[0].from; | 374 | fn_cipher_key_bytes_src = args[0].from; |
369 | fn_cipher_key_bytes = | 375 | fn_cipher_key_bytes = |
370 | (int)simple_strtol(fn_cipher_key_bytes_src, | 376 | (int)simple_strtol(fn_cipher_key_bytes_src, |
371 | &fn_cipher_key_bytes_src, 0); | 377 | &fn_cipher_key_bytes_src, 0); |
372 | mount_crypt_stat->global_default_fn_cipher_key_bytes = | 378 | mount_crypt_stat->global_default_fn_cipher_key_bytes = |
373 | fn_cipher_key_bytes; | 379 | fn_cipher_key_bytes; |
374 | fn_cipher_key_bytes_set = 1; | 380 | fn_cipher_key_bytes_set = 1; |
375 | break; | 381 | break; |
376 | case ecryptfs_opt_unlink_sigs: | 382 | case ecryptfs_opt_unlink_sigs: |
377 | mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS; | 383 | mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS; |
378 | break; | 384 | break; |
379 | case ecryptfs_opt_mount_auth_tok_only: | 385 | case ecryptfs_opt_mount_auth_tok_only: |
380 | mount_crypt_stat->flags |= | 386 | mount_crypt_stat->flags |= |
381 | ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; | 387 | ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; |
382 | break; | 388 | break; |
389 | case ecryptfs_opt_check_dev_ruid: | ||
390 | *check_ruid = 1; | ||
391 | break; | ||
383 | case ecryptfs_opt_err: | 392 | case ecryptfs_opt_err: |
384 | default: | 393 | default: |
385 | printk(KERN_WARNING | 394 | printk(KERN_WARNING |
386 | "%s: eCryptfs: unrecognized option [%s]\n", | 395 | "%s: eCryptfs: unrecognized option [%s]\n", |
387 | __func__, p); | 396 | __func__, p); |
388 | } | 397 | } |
389 | } | 398 | } |
390 | if (!sig_set) { | 399 | if (!sig_set) { |
391 | rc = -EINVAL; | 400 | rc = -EINVAL; |
392 | ecryptfs_printk(KERN_ERR, "You must supply at least one valid " | 401 | ecryptfs_printk(KERN_ERR, "You must supply at least one valid " |
393 | "auth tok signature as a mount " | 402 | "auth tok signature as a mount " |
394 | "parameter; see the eCryptfs README\n"); | 403 | "parameter; see the eCryptfs README\n"); |
395 | goto out; | 404 | goto out; |
396 | } | 405 | } |
397 | if (!cipher_name_set) { | 406 | if (!cipher_name_set) { |
398 | int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); | 407 | int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); |
399 | 408 | ||
400 | BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); | 409 | BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
401 | strcpy(mount_crypt_stat->global_default_cipher_name, | 410 | strcpy(mount_crypt_stat->global_default_cipher_name, |
402 | ECRYPTFS_DEFAULT_CIPHER); | 411 | ECRYPTFS_DEFAULT_CIPHER); |
403 | } | 412 | } |
404 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | 413 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) |
405 | && !fn_cipher_name_set) | 414 | && !fn_cipher_name_set) |
406 | strcpy(mount_crypt_stat->global_default_fn_cipher_name, | 415 | strcpy(mount_crypt_stat->global_default_fn_cipher_name, |
407 | mount_crypt_stat->global_default_cipher_name); | 416 | mount_crypt_stat->global_default_cipher_name); |
408 | if (!cipher_key_bytes_set) | 417 | if (!cipher_key_bytes_set) |
409 | mount_crypt_stat->global_default_cipher_key_size = 0; | 418 | mount_crypt_stat->global_default_cipher_key_size = 0; |
410 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | 419 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) |
411 | && !fn_cipher_key_bytes_set) | 420 | && !fn_cipher_key_bytes_set) |
412 | mount_crypt_stat->global_default_fn_cipher_key_bytes = | 421 | mount_crypt_stat->global_default_fn_cipher_key_bytes = |
413 | mount_crypt_stat->global_default_cipher_key_size; | 422 | mount_crypt_stat->global_default_cipher_key_size; |
414 | mutex_lock(&key_tfm_list_mutex); | 423 | mutex_lock(&key_tfm_list_mutex); |
415 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, | 424 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, |
416 | NULL)) { | 425 | NULL)) { |
417 | rc = ecryptfs_add_new_key_tfm( | 426 | rc = ecryptfs_add_new_key_tfm( |
418 | NULL, mount_crypt_stat->global_default_cipher_name, | 427 | NULL, mount_crypt_stat->global_default_cipher_name, |
419 | mount_crypt_stat->global_default_cipher_key_size); | 428 | mount_crypt_stat->global_default_cipher_key_size); |
420 | if (rc) { | 429 | if (rc) { |
421 | printk(KERN_ERR "Error attempting to initialize " | 430 | printk(KERN_ERR "Error attempting to initialize " |
422 | "cipher with name = [%s] and key size = [%td]; " | 431 | "cipher with name = [%s] and key size = [%td]; " |
423 | "rc = [%d]\n", | 432 | "rc = [%d]\n", |
424 | mount_crypt_stat->global_default_cipher_name, | 433 | mount_crypt_stat->global_default_cipher_name, |
425 | mount_crypt_stat->global_default_cipher_key_size, | 434 | mount_crypt_stat->global_default_cipher_key_size, |
426 | rc); | 435 | rc); |
427 | rc = -EINVAL; | 436 | rc = -EINVAL; |
428 | mutex_unlock(&key_tfm_list_mutex); | 437 | mutex_unlock(&key_tfm_list_mutex); |
429 | goto out; | 438 | goto out; |
430 | } | 439 | } |
431 | } | 440 | } |
432 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | 441 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) |
433 | && !ecryptfs_tfm_exists( | 442 | && !ecryptfs_tfm_exists( |
434 | mount_crypt_stat->global_default_fn_cipher_name, NULL)) { | 443 | mount_crypt_stat->global_default_fn_cipher_name, NULL)) { |
435 | rc = ecryptfs_add_new_key_tfm( | 444 | rc = ecryptfs_add_new_key_tfm( |
436 | NULL, mount_crypt_stat->global_default_fn_cipher_name, | 445 | NULL, mount_crypt_stat->global_default_fn_cipher_name, |
437 | mount_crypt_stat->global_default_fn_cipher_key_bytes); | 446 | mount_crypt_stat->global_default_fn_cipher_key_bytes); |
438 | if (rc) { | 447 | if (rc) { |
439 | printk(KERN_ERR "Error attempting to initialize " | 448 | printk(KERN_ERR "Error attempting to initialize " |
440 | "cipher with name = [%s] and key size = [%td]; " | 449 | "cipher with name = [%s] and key size = [%td]; " |
441 | "rc = [%d]\n", | 450 | "rc = [%d]\n", |
442 | mount_crypt_stat->global_default_fn_cipher_name, | 451 | mount_crypt_stat->global_default_fn_cipher_name, |
443 | mount_crypt_stat->global_default_fn_cipher_key_bytes, | 452 | mount_crypt_stat->global_default_fn_cipher_key_bytes, |
444 | rc); | 453 | rc); |
445 | rc = -EINVAL; | 454 | rc = -EINVAL; |
446 | mutex_unlock(&key_tfm_list_mutex); | 455 | mutex_unlock(&key_tfm_list_mutex); |
447 | goto out; | 456 | goto out; |
448 | } | 457 | } |
449 | } | 458 | } |
450 | mutex_unlock(&key_tfm_list_mutex); | 459 | mutex_unlock(&key_tfm_list_mutex); |
451 | rc = ecryptfs_init_global_auth_toks(mount_crypt_stat); | 460 | rc = ecryptfs_init_global_auth_toks(mount_crypt_stat); |
452 | if (rc) | 461 | if (rc) |
453 | printk(KERN_WARNING "One or more global auth toks could not " | 462 | printk(KERN_WARNING "One or more global auth toks could not " |
454 | "properly register; rc = [%d]\n", rc); | 463 | "properly register; rc = [%d]\n", rc); |
455 | out: | 464 | out: |
456 | return rc; | 465 | return rc; |
457 | } | 466 | } |
458 | 467 | ||
459 | struct kmem_cache *ecryptfs_sb_info_cache; | 468 | struct kmem_cache *ecryptfs_sb_info_cache; |
460 | static struct file_system_type ecryptfs_fs_type; | 469 | static struct file_system_type ecryptfs_fs_type; |
461 | 470 | ||
462 | /** | 471 | /** |
463 | * ecryptfs_get_sb | 472 | * ecryptfs_get_sb |
464 | * @fs_type | 473 | * @fs_type |
465 | * @flags | 474 | * @flags |
466 | * @dev_name: The path to mount over | 475 | * @dev_name: The path to mount over |
467 | * @raw_data: The options passed into the kernel | 476 | * @raw_data: The options passed into the kernel |
468 | */ | 477 | */ |
469 | static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags, | 478 | static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags, |
470 | const char *dev_name, void *raw_data) | 479 | const char *dev_name, void *raw_data) |
471 | { | 480 | { |
472 | struct super_block *s; | 481 | struct super_block *s; |
473 | struct ecryptfs_sb_info *sbi; | 482 | struct ecryptfs_sb_info *sbi; |
474 | struct ecryptfs_dentry_info *root_info; | 483 | struct ecryptfs_dentry_info *root_info; |
475 | const char *err = "Getting sb failed"; | 484 | const char *err = "Getting sb failed"; |
476 | struct inode *inode; | 485 | struct inode *inode; |
477 | struct path path; | 486 | struct path path; |
487 | uid_t check_ruid; | ||
478 | int rc; | 488 | int rc; |
479 | 489 | ||
480 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); | 490 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
481 | if (!sbi) { | 491 | if (!sbi) { |
482 | rc = -ENOMEM; | 492 | rc = -ENOMEM; |
483 | goto out; | 493 | goto out; |
484 | } | 494 | } |
485 | 495 | ||
486 | rc = ecryptfs_parse_options(sbi, raw_data); | 496 | rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); |
487 | if (rc) { | 497 | if (rc) { |
488 | err = "Error parsing options"; | 498 | err = "Error parsing options"; |
489 | goto out; | 499 | goto out; |
490 | } | 500 | } |
491 | 501 | ||
492 | s = sget(fs_type, NULL, set_anon_super, NULL); | 502 | s = sget(fs_type, NULL, set_anon_super, NULL); |
493 | if (IS_ERR(s)) { | 503 | if (IS_ERR(s)) { |
494 | rc = PTR_ERR(s); | 504 | rc = PTR_ERR(s); |
495 | goto out; | 505 | goto out; |
496 | } | 506 | } |
497 | 507 | ||
498 | s->s_flags = flags; | 508 | s->s_flags = flags; |
499 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | 509 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); |
500 | if (rc) | 510 | if (rc) |
501 | goto out1; | 511 | goto out1; |
502 | 512 | ||
503 | ecryptfs_set_superblock_private(s, sbi); | 513 | ecryptfs_set_superblock_private(s, sbi); |
504 | s->s_bdi = &sbi->bdi; | 514 | s->s_bdi = &sbi->bdi; |
505 | 515 | ||
506 | /* ->kill_sb() will take care of sbi after that point */ | 516 | /* ->kill_sb() will take care of sbi after that point */ |
507 | sbi = NULL; | 517 | sbi = NULL; |
508 | s->s_op = &ecryptfs_sops; | 518 | s->s_op = &ecryptfs_sops; |
509 | s->s_d_op = &ecryptfs_dops; | 519 | s->s_d_op = &ecryptfs_dops; |
510 | 520 | ||
511 | err = "Reading sb failed"; | 521 | err = "Reading sb failed"; |
512 | rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); | 522 | rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); |
513 | if (rc) { | 523 | if (rc) { |
514 | ecryptfs_printk(KERN_WARNING, "kern_path() failed\n"); | 524 | ecryptfs_printk(KERN_WARNING, "kern_path() failed\n"); |
515 | goto out1; | 525 | goto out1; |
516 | } | 526 | } |
517 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { | 527 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { |
518 | rc = -EINVAL; | 528 | rc = -EINVAL; |
519 | printk(KERN_ERR "Mount on filesystem of type " | 529 | printk(KERN_ERR "Mount on filesystem of type " |
520 | "eCryptfs explicitly disallowed due to " | 530 | "eCryptfs explicitly disallowed due to " |
521 | "known incompatibilities\n"); | 531 | "known incompatibilities\n"); |
522 | goto out_free; | 532 | goto out_free; |
523 | } | 533 | } |
534 | |||
535 | if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { | ||
536 | rc = -EPERM; | ||
537 | printk(KERN_ERR "Mount of device (uid: %d) not owned by " | ||
538 | "requested user (uid: %d)\n", | ||
539 | path.dentry->d_inode->i_uid, current_uid()); | ||
540 | goto out_free; | ||
541 | } | ||
542 | |||
524 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); | 543 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
525 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 544 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
526 | s->s_blocksize = path.dentry->d_sb->s_blocksize; | 545 | s->s_blocksize = path.dentry->d_sb->s_blocksize; |
527 | s->s_magic = ECRYPTFS_SUPER_MAGIC; | 546 | s->s_magic = ECRYPTFS_SUPER_MAGIC; |
528 | 547 | ||
529 | inode = ecryptfs_get_inode(path.dentry->d_inode, s); | 548 | inode = ecryptfs_get_inode(path.dentry->d_inode, s); |
530 | rc = PTR_ERR(inode); | 549 | rc = PTR_ERR(inode); |
531 | if (IS_ERR(inode)) | 550 | if (IS_ERR(inode)) |
532 | goto out_free; | 551 | goto out_free; |
533 | 552 | ||
534 | s->s_root = d_alloc_root(inode); | 553 | s->s_root = d_alloc_root(inode); |
535 | if (!s->s_root) { | 554 | if (!s->s_root) { |
536 | iput(inode); | 555 | iput(inode); |
537 | rc = -ENOMEM; | 556 | rc = -ENOMEM; |
538 | goto out_free; | 557 | goto out_free; |
539 | } | 558 | } |
540 | 559 | ||
541 | rc = -ENOMEM; | 560 | rc = -ENOMEM; |
542 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); | 561 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); |
543 | if (!root_info) | 562 | if (!root_info) |
544 | goto out_free; | 563 | goto out_free; |
545 | 564 | ||
546 | /* ->kill_sb() will take care of root_info */ | 565 | /* ->kill_sb() will take care of root_info */ |
547 | ecryptfs_set_dentry_private(s->s_root, root_info); | 566 | ecryptfs_set_dentry_private(s->s_root, root_info); |
548 | ecryptfs_set_dentry_lower(s->s_root, path.dentry); | 567 | ecryptfs_set_dentry_lower(s->s_root, path.dentry); |
549 | ecryptfs_set_dentry_lower_mnt(s->s_root, path.mnt); | 568 | ecryptfs_set_dentry_lower_mnt(s->s_root, path.mnt); |
550 | 569 | ||
551 | s->s_flags |= MS_ACTIVE; | 570 | s->s_flags |= MS_ACTIVE; |
552 | return dget(s->s_root); | 571 | return dget(s->s_root); |
553 | 572 | ||
554 | out_free: | 573 | out_free: |
555 | path_put(&path); | 574 | path_put(&path); |
556 | out1: | 575 | out1: |
557 | deactivate_locked_super(s); | 576 | deactivate_locked_super(s); |
558 | out: | 577 | out: |
559 | if (sbi) { | 578 | if (sbi) { |
560 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); | 579 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); |
561 | kmem_cache_free(ecryptfs_sb_info_cache, sbi); | 580 | kmem_cache_free(ecryptfs_sb_info_cache, sbi); |
562 | } | 581 | } |
563 | printk(KERN_ERR "%s; rc = [%d]\n", err, rc); | 582 | printk(KERN_ERR "%s; rc = [%d]\n", err, rc); |
564 | return ERR_PTR(rc); | 583 | return ERR_PTR(rc); |
565 | } | 584 | } |
566 | 585 | ||
567 | /** | 586 | /** |
568 | * ecryptfs_kill_block_super | 587 | * ecryptfs_kill_block_super |
569 | * @sb: The ecryptfs super block | 588 | * @sb: The ecryptfs super block |
570 | * | 589 | * |
571 | * Used to bring the superblock down and free the private data. | 590 | * Used to bring the superblock down and free the private data. |
572 | */ | 591 | */ |
573 | static void ecryptfs_kill_block_super(struct super_block *sb) | 592 | static void ecryptfs_kill_block_super(struct super_block *sb) |
574 | { | 593 | { |
575 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); | 594 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); |
576 | kill_anon_super(sb); | 595 | kill_anon_super(sb); |
577 | if (!sb_info) | 596 | if (!sb_info) |
578 | return; | 597 | return; |
579 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | 598 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); |
580 | bdi_destroy(&sb_info->bdi); | 599 | bdi_destroy(&sb_info->bdi); |
581 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | 600 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); |
582 | } | 601 | } |
583 | 602 | ||
584 | static struct file_system_type ecryptfs_fs_type = { | 603 | static struct file_system_type ecryptfs_fs_type = { |
585 | .owner = THIS_MODULE, | 604 | .owner = THIS_MODULE, |
586 | .name = "ecryptfs", | 605 | .name = "ecryptfs", |
587 | .mount = ecryptfs_mount, | 606 | .mount = ecryptfs_mount, |
588 | .kill_sb = ecryptfs_kill_block_super, | 607 | .kill_sb = ecryptfs_kill_block_super, |
589 | .fs_flags = 0 | 608 | .fs_flags = 0 |
590 | }; | 609 | }; |
591 | 610 | ||
592 | /** | 611 | /** |
593 | * inode_info_init_once | 612 | * inode_info_init_once |
594 | * | 613 | * |
595 | * Initializes the ecryptfs_inode_info_cache when it is created | 614 | * Initializes the ecryptfs_inode_info_cache when it is created |
596 | */ | 615 | */ |
597 | static void | 616 | static void |
598 | inode_info_init_once(void *vptr) | 617 | inode_info_init_once(void *vptr) |
599 | { | 618 | { |
600 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; | 619 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; |
601 | 620 | ||
602 | inode_init_once(&ei->vfs_inode); | 621 | inode_init_once(&ei->vfs_inode); |
603 | } | 622 | } |
604 | 623 | ||
605 | static struct ecryptfs_cache_info { | 624 | static struct ecryptfs_cache_info { |
606 | struct kmem_cache **cache; | 625 | struct kmem_cache **cache; |
607 | const char *name; | 626 | const char *name; |
608 | size_t size; | 627 | size_t size; |
609 | void (*ctor)(void *obj); | 628 | void (*ctor)(void *obj); |
610 | } ecryptfs_cache_infos[] = { | 629 | } ecryptfs_cache_infos[] = { |
611 | { | 630 | { |
612 | .cache = &ecryptfs_auth_tok_list_item_cache, | 631 | .cache = &ecryptfs_auth_tok_list_item_cache, |
613 | .name = "ecryptfs_auth_tok_list_item", | 632 | .name = "ecryptfs_auth_tok_list_item", |
614 | .size = sizeof(struct ecryptfs_auth_tok_list_item), | 633 | .size = sizeof(struct ecryptfs_auth_tok_list_item), |
615 | }, | 634 | }, |
616 | { | 635 | { |
617 | .cache = &ecryptfs_file_info_cache, | 636 | .cache = &ecryptfs_file_info_cache, |
618 | .name = "ecryptfs_file_cache", | 637 | .name = "ecryptfs_file_cache", |
619 | .size = sizeof(struct ecryptfs_file_info), | 638 | .size = sizeof(struct ecryptfs_file_info), |
620 | }, | 639 | }, |
621 | { | 640 | { |
622 | .cache = &ecryptfs_dentry_info_cache, | 641 | .cache = &ecryptfs_dentry_info_cache, |
623 | .name = "ecryptfs_dentry_info_cache", | 642 | .name = "ecryptfs_dentry_info_cache", |
624 | .size = sizeof(struct ecryptfs_dentry_info), | 643 | .size = sizeof(struct ecryptfs_dentry_info), |
625 | }, | 644 | }, |
626 | { | 645 | { |
627 | .cache = &ecryptfs_inode_info_cache, | 646 | .cache = &ecryptfs_inode_info_cache, |
628 | .name = "ecryptfs_inode_cache", | 647 | .name = "ecryptfs_inode_cache", |
629 | .size = sizeof(struct ecryptfs_inode_info), | 648 | .size = sizeof(struct ecryptfs_inode_info), |
630 | .ctor = inode_info_init_once, | 649 | .ctor = inode_info_init_once, |
631 | }, | 650 | }, |
632 | { | 651 | { |
633 | .cache = &ecryptfs_sb_info_cache, | 652 | .cache = &ecryptfs_sb_info_cache, |
634 | .name = "ecryptfs_sb_cache", | 653 | .name = "ecryptfs_sb_cache", |
635 | .size = sizeof(struct ecryptfs_sb_info), | 654 | .size = sizeof(struct ecryptfs_sb_info), |
636 | }, | 655 | }, |
637 | { | 656 | { |
638 | .cache = &ecryptfs_header_cache, | 657 | .cache = &ecryptfs_header_cache, |
639 | .name = "ecryptfs_headers", | 658 | .name = "ecryptfs_headers", |
640 | .size = PAGE_CACHE_SIZE, | 659 | .size = PAGE_CACHE_SIZE, |
641 | }, | 660 | }, |
642 | { | 661 | { |
643 | .cache = &ecryptfs_xattr_cache, | 662 | .cache = &ecryptfs_xattr_cache, |
644 | .name = "ecryptfs_xattr_cache", | 663 | .name = "ecryptfs_xattr_cache", |
645 | .size = PAGE_CACHE_SIZE, | 664 | .size = PAGE_CACHE_SIZE, |
646 | }, | 665 | }, |
647 | { | 666 | { |
648 | .cache = &ecryptfs_key_record_cache, | 667 | .cache = &ecryptfs_key_record_cache, |
649 | .name = "ecryptfs_key_record_cache", | 668 | .name = "ecryptfs_key_record_cache", |
650 | .size = sizeof(struct ecryptfs_key_record), | 669 | .size = sizeof(struct ecryptfs_key_record), |
651 | }, | 670 | }, |
652 | { | 671 | { |
653 | .cache = &ecryptfs_key_sig_cache, | 672 | .cache = &ecryptfs_key_sig_cache, |
654 | .name = "ecryptfs_key_sig_cache", | 673 | .name = "ecryptfs_key_sig_cache", |
655 | .size = sizeof(struct ecryptfs_key_sig), | 674 | .size = sizeof(struct ecryptfs_key_sig), |
656 | }, | 675 | }, |
657 | { | 676 | { |
658 | .cache = &ecryptfs_global_auth_tok_cache, | 677 | .cache = &ecryptfs_global_auth_tok_cache, |
659 | .name = "ecryptfs_global_auth_tok_cache", | 678 | .name = "ecryptfs_global_auth_tok_cache", |
660 | .size = sizeof(struct ecryptfs_global_auth_tok), | 679 | .size = sizeof(struct ecryptfs_global_auth_tok), |
661 | }, | 680 | }, |
662 | { | 681 | { |
663 | .cache = &ecryptfs_key_tfm_cache, | 682 | .cache = &ecryptfs_key_tfm_cache, |
664 | .name = "ecryptfs_key_tfm_cache", | 683 | .name = "ecryptfs_key_tfm_cache", |
665 | .size = sizeof(struct ecryptfs_key_tfm), | 684 | .size = sizeof(struct ecryptfs_key_tfm), |
666 | }, | 685 | }, |
667 | { | 686 | { |
668 | .cache = &ecryptfs_open_req_cache, | 687 | .cache = &ecryptfs_open_req_cache, |
669 | .name = "ecryptfs_open_req_cache", | 688 | .name = "ecryptfs_open_req_cache", |
670 | .size = sizeof(struct ecryptfs_open_req), | 689 | .size = sizeof(struct ecryptfs_open_req), |
671 | }, | 690 | }, |
672 | }; | 691 | }; |
673 | 692 | ||
674 | static void ecryptfs_free_kmem_caches(void) | 693 | static void ecryptfs_free_kmem_caches(void) |
675 | { | 694 | { |
676 | int i; | 695 | int i; |
677 | 696 | ||
678 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) { | 697 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) { |
679 | struct ecryptfs_cache_info *info; | 698 | struct ecryptfs_cache_info *info; |
680 | 699 | ||
681 | info = &ecryptfs_cache_infos[i]; | 700 | info = &ecryptfs_cache_infos[i]; |
682 | if (*(info->cache)) | 701 | if (*(info->cache)) |
683 | kmem_cache_destroy(*(info->cache)); | 702 | kmem_cache_destroy(*(info->cache)); |
684 | } | 703 | } |
685 | } | 704 | } |
686 | 705 | ||
687 | /** | 706 | /** |
688 | * ecryptfs_init_kmem_caches | 707 | * ecryptfs_init_kmem_caches |
689 | * | 708 | * |
690 | * Returns zero on success; non-zero otherwise | 709 | * Returns zero on success; non-zero otherwise |
691 | */ | 710 | */ |
692 | static int ecryptfs_init_kmem_caches(void) | 711 | static int ecryptfs_init_kmem_caches(void) |
693 | { | 712 | { |
694 | int i; | 713 | int i; |
695 | 714 | ||
696 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) { | 715 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) { |
697 | struct ecryptfs_cache_info *info; | 716 | struct ecryptfs_cache_info *info; |
698 | 717 | ||
699 | info = &ecryptfs_cache_infos[i]; | 718 | info = &ecryptfs_cache_infos[i]; |
700 | *(info->cache) = kmem_cache_create(info->name, info->size, | 719 | *(info->cache) = kmem_cache_create(info->name, info->size, |
701 | 0, SLAB_HWCACHE_ALIGN, info->ctor); | 720 | 0, SLAB_HWCACHE_ALIGN, info->ctor); |
702 | if (!*(info->cache)) { | 721 | if (!*(info->cache)) { |
703 | ecryptfs_free_kmem_caches(); | 722 | ecryptfs_free_kmem_caches(); |
704 | ecryptfs_printk(KERN_WARNING, "%s: " | 723 | ecryptfs_printk(KERN_WARNING, "%s: " |
705 | "kmem_cache_create failed\n", | 724 | "kmem_cache_create failed\n", |
706 | info->name); | 725 | info->name); |
707 | return -ENOMEM; | 726 | return -ENOMEM; |
708 | } | 727 | } |
709 | } | 728 | } |
710 | return 0; | 729 | return 0; |
711 | } | 730 | } |
712 | 731 | ||
713 | static struct kobject *ecryptfs_kobj; | 732 | static struct kobject *ecryptfs_kobj; |
714 | 733 | ||
715 | static ssize_t version_show(struct kobject *kobj, | 734 | static ssize_t version_show(struct kobject *kobj, |
716 | struct kobj_attribute *attr, char *buff) | 735 | struct kobj_attribute *attr, char *buff) |
717 | { | 736 | { |
718 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); | 737 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); |
719 | } | 738 | } |
720 | 739 | ||
721 | static struct kobj_attribute version_attr = __ATTR_RO(version); | 740 | static struct kobj_attribute version_attr = __ATTR_RO(version); |
722 | 741 | ||
723 | static struct attribute *attributes[] = { | 742 | static struct attribute *attributes[] = { |
724 | &version_attr.attr, | 743 | &version_attr.attr, |
725 | NULL, | 744 | NULL, |
726 | }; | 745 | }; |
727 | 746 | ||
728 | static struct attribute_group attr_group = { | 747 | static struct attribute_group attr_group = { |
729 | .attrs = attributes, | 748 | .attrs = attributes, |
730 | }; | 749 | }; |
731 | 750 | ||
732 | static int do_sysfs_registration(void) | 751 | static int do_sysfs_registration(void) |
733 | { | 752 | { |
734 | int rc; | 753 | int rc; |
735 | 754 | ||
736 | ecryptfs_kobj = kobject_create_and_add("ecryptfs", fs_kobj); | 755 | ecryptfs_kobj = kobject_create_and_add("ecryptfs", fs_kobj); |
737 | if (!ecryptfs_kobj) { | 756 | if (!ecryptfs_kobj) { |
738 | printk(KERN_ERR "Unable to create ecryptfs kset\n"); | 757 | printk(KERN_ERR "Unable to create ecryptfs kset\n"); |
739 | rc = -ENOMEM; | 758 | rc = -ENOMEM; |
740 | goto out; | 759 | goto out; |
741 | } | 760 | } |
742 | rc = sysfs_create_group(ecryptfs_kobj, &attr_group); | 761 | rc = sysfs_create_group(ecryptfs_kobj, &attr_group); |
743 | if (rc) { | 762 | if (rc) { |
744 | printk(KERN_ERR | 763 | printk(KERN_ERR |
745 | "Unable to create ecryptfs version attributes\n"); | 764 | "Unable to create ecryptfs version attributes\n"); |
746 | kobject_put(ecryptfs_kobj); | 765 | kobject_put(ecryptfs_kobj); |
747 | } | 766 | } |
748 | out: | 767 | out: |
749 | return rc; | 768 | return rc; |
750 | } | 769 | } |
751 | 770 | ||
752 | static void do_sysfs_unregistration(void) | 771 | static void do_sysfs_unregistration(void) |
753 | { | 772 | { |
754 | sysfs_remove_group(ecryptfs_kobj, &attr_group); | 773 | sysfs_remove_group(ecryptfs_kobj, &attr_group); |
755 | kobject_put(ecryptfs_kobj); | 774 | kobject_put(ecryptfs_kobj); |
756 | } | 775 | } |
757 | 776 | ||
758 | static int __init ecryptfs_init(void) | 777 | static int __init ecryptfs_init(void) |
759 | { | 778 | { |
760 | int rc; | 779 | int rc; |
761 | 780 | ||
762 | if (ECRYPTFS_DEFAULT_EXTENT_SIZE > PAGE_CACHE_SIZE) { | 781 | if (ECRYPTFS_DEFAULT_EXTENT_SIZE > PAGE_CACHE_SIZE) { |
763 | rc = -EINVAL; | 782 | rc = -EINVAL; |
764 | ecryptfs_printk(KERN_ERR, "The eCryptfs extent size is " | 783 | ecryptfs_printk(KERN_ERR, "The eCryptfs extent size is " |
765 | "larger than the host's page size, and so " | 784 | "larger than the host's page size, and so " |
766 | "eCryptfs cannot run on this system. The " | 785 | "eCryptfs cannot run on this system. The " |
767 | "default eCryptfs extent size is [%u] bytes; " | 786 | "default eCryptfs extent size is [%u] bytes; " |
768 | "the page size is [%lu] bytes.\n", | 787 | "the page size is [%lu] bytes.\n", |
769 | ECRYPTFS_DEFAULT_EXTENT_SIZE, | 788 | ECRYPTFS_DEFAULT_EXTENT_SIZE, |
770 | (unsigned long)PAGE_CACHE_SIZE); | 789 | (unsigned long)PAGE_CACHE_SIZE); |
771 | goto out; | 790 | goto out; |
772 | } | 791 | } |
773 | rc = ecryptfs_init_kmem_caches(); | 792 | rc = ecryptfs_init_kmem_caches(); |
774 | if (rc) { | 793 | if (rc) { |
775 | printk(KERN_ERR | 794 | printk(KERN_ERR |
776 | "Failed to allocate one or more kmem_cache objects\n"); | 795 | "Failed to allocate one or more kmem_cache objects\n"); |
777 | goto out; | 796 | goto out; |
778 | } | 797 | } |
779 | rc = register_filesystem(&ecryptfs_fs_type); | 798 | rc = register_filesystem(&ecryptfs_fs_type); |
780 | if (rc) { | 799 | if (rc) { |
781 | printk(KERN_ERR "Failed to register filesystem\n"); | 800 | printk(KERN_ERR "Failed to register filesystem\n"); |
782 | goto out_free_kmem_caches; | 801 | goto out_free_kmem_caches; |
783 | } | 802 | } |
784 | rc = do_sysfs_registration(); | 803 | rc = do_sysfs_registration(); |
785 | if (rc) { | 804 | if (rc) { |
786 | printk(KERN_ERR "sysfs registration failed\n"); | 805 | printk(KERN_ERR "sysfs registration failed\n"); |
787 | goto out_unregister_filesystem; | 806 | goto out_unregister_filesystem; |
788 | } | 807 | } |
789 | rc = ecryptfs_init_kthread(); | 808 | rc = ecryptfs_init_kthread(); |
790 | if (rc) { | 809 | if (rc) { |
791 | printk(KERN_ERR "%s: kthread initialization failed; " | 810 | printk(KERN_ERR "%s: kthread initialization failed; " |
792 | "rc = [%d]\n", __func__, rc); | 811 | "rc = [%d]\n", __func__, rc); |
793 | goto out_do_sysfs_unregistration; | 812 | goto out_do_sysfs_unregistration; |
794 | } | 813 | } |
795 | rc = ecryptfs_init_messaging(); | 814 | rc = ecryptfs_init_messaging(); |
796 | if (rc) { | 815 | if (rc) { |
797 | printk(KERN_ERR "Failure occurred while attempting to " | 816 | printk(KERN_ERR "Failure occurred while attempting to " |
798 | "initialize the communications channel to " | 817 | "initialize the communications channel to " |
799 | "ecryptfsd\n"); | 818 | "ecryptfsd\n"); |
800 | goto out_destroy_kthread; | 819 | goto out_destroy_kthread; |
801 | } | 820 | } |
802 | rc = ecryptfs_init_crypto(); | 821 | rc = ecryptfs_init_crypto(); |
803 | if (rc) { | 822 | if (rc) { |
804 | printk(KERN_ERR "Failure whilst attempting to init crypto; " | 823 | printk(KERN_ERR "Failure whilst attempting to init crypto; " |
805 | "rc = [%d]\n", rc); | 824 | "rc = [%d]\n", rc); |
806 | goto out_release_messaging; | 825 | goto out_release_messaging; |
807 | } | 826 | } |
808 | if (ecryptfs_verbosity > 0) | 827 | if (ecryptfs_verbosity > 0) |
809 | printk(KERN_CRIT "eCryptfs verbosity set to %d. Secret values " | 828 | printk(KERN_CRIT "eCryptfs verbosity set to %d. Secret values " |
810 | "will be written to the syslog!\n", ecryptfs_verbosity); | 829 | "will be written to the syslog!\n", ecryptfs_verbosity); |
811 | 830 | ||
812 | goto out; | 831 | goto out; |
813 | out_release_messaging: | 832 | out_release_messaging: |
814 | ecryptfs_release_messaging(); | 833 | ecryptfs_release_messaging(); |
815 | out_destroy_kthread: | 834 | out_destroy_kthread: |
816 | ecryptfs_destroy_kthread(); | 835 | ecryptfs_destroy_kthread(); |
817 | out_do_sysfs_unregistration: | 836 | out_do_sysfs_unregistration: |
818 | do_sysfs_unregistration(); | 837 | do_sysfs_unregistration(); |
819 | out_unregister_filesystem: | 838 | out_unregister_filesystem: |
820 | unregister_filesystem(&ecryptfs_fs_type); | 839 | unregister_filesystem(&ecryptfs_fs_type); |
821 | out_free_kmem_caches: | 840 | out_free_kmem_caches: |
822 | ecryptfs_free_kmem_caches(); | 841 | ecryptfs_free_kmem_caches(); |
823 | out: | 842 | out: |
824 | return rc; | 843 | return rc; |
825 | } | 844 | } |
826 | 845 | ||
827 | static void __exit ecryptfs_exit(void) | 846 | static void __exit ecryptfs_exit(void) |
828 | { | 847 | { |
829 | int rc; | 848 | int rc; |
830 | 849 | ||
831 | rc = ecryptfs_destroy_crypto(); | 850 | rc = ecryptfs_destroy_crypto(); |
832 | if (rc) | 851 | if (rc) |
833 | printk(KERN_ERR "Failure whilst attempting to destroy crypto; " | 852 | printk(KERN_ERR "Failure whilst attempting to destroy crypto; " |
834 | "rc = [%d]\n", rc); | 853 | "rc = [%d]\n", rc); |
835 | ecryptfs_release_messaging(); | 854 | ecryptfs_release_messaging(); |
836 | ecryptfs_destroy_kthread(); | 855 | ecryptfs_destroy_kthread(); |
837 | do_sysfs_unregistration(); | 856 | do_sysfs_unregistration(); |
838 | unregister_filesystem(&ecryptfs_fs_type); | 857 | unregister_filesystem(&ecryptfs_fs_type); |
839 | ecryptfs_free_kmem_caches(); | 858 | ecryptfs_free_kmem_caches(); |
840 | } | 859 | } |
841 | 860 | ||
842 | MODULE_AUTHOR("Michael A. Halcrow <mhalcrow@us.ibm.com>"); | 861 | MODULE_AUTHOR("Michael A. Halcrow <mhalcrow@us.ibm.com>"); |
843 | MODULE_DESCRIPTION("eCryptfs"); | 862 | MODULE_DESCRIPTION("eCryptfs"); |
844 | 863 | ||
845 | MODULE_LICENSE("GPL"); | 864 | MODULE_LICENSE("GPL"); |
846 | 865 | ||
847 | module_init(ecryptfs_init) | 866 | module_init(ecryptfs_init) |
848 | module_exit(ecryptfs_exit) | 867 | module_exit(ecryptfs_exit) |
849 | 868 |
fs/ecryptfs/read_write.c
1 | /** | 1 | /** |
2 | * eCryptfs: Linux filesystem encryption layer | 2 | * eCryptfs: Linux filesystem encryption layer |
3 | * | 3 | * |
4 | * Copyright (C) 2007 International Business Machines Corp. | 4 | * Copyright (C) 2007 International Business Machines Corp. |
5 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 5 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as | 8 | * modify it under the terms of the GNU General Public License as |
9 | * published by the Free Software Foundation; either version 2 of the | 9 | * published by the Free Software Foundation; either version 2 of the |
10 | * License, or (at your option) any later version. | 10 | * License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, but | 12 | * This program is distributed in the hope that it will be useful, but |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * General Public License for more details. | 15 | * General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
20 | * 02111-1307, USA. | 20 | * 02111-1307, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
25 | #include "ecryptfs_kernel.h" | 25 | #include "ecryptfs_kernel.h" |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * ecryptfs_write_lower | 28 | * ecryptfs_write_lower |
29 | * @ecryptfs_inode: The eCryptfs inode | 29 | * @ecryptfs_inode: The eCryptfs inode |
30 | * @data: Data to write | 30 | * @data: Data to write |
31 | * @offset: Byte offset in the lower file to which to write the data | 31 | * @offset: Byte offset in the lower file to which to write the data |
32 | * @size: Number of bytes from @data to write at @offset in the lower | 32 | * @size: Number of bytes from @data to write at @offset in the lower |
33 | * file | 33 | * file |
34 | * | 34 | * |
35 | * Write data to the lower file. | 35 | * Write data to the lower file. |
36 | * | 36 | * |
37 | * Returns bytes written on success; less than zero on error | 37 | * Returns bytes written on success; less than zero on error |
38 | */ | 38 | */ |
39 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | 39 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, |
40 | loff_t offset, size_t size) | 40 | loff_t offset, size_t size) |
41 | { | 41 | { |
42 | struct ecryptfs_inode_info *inode_info; | 42 | struct file *lower_file; |
43 | mm_segment_t fs_save; | 43 | mm_segment_t fs_save; |
44 | ssize_t rc; | 44 | ssize_t rc; |
45 | 45 | ||
46 | inode_info = ecryptfs_inode_to_private(ecryptfs_inode); | 46 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
47 | BUG_ON(!inode_info->lower_file); | 47 | if (!lower_file) |
48 | return -EIO; | ||
48 | fs_save = get_fs(); | 49 | fs_save = get_fs(); |
49 | set_fs(get_ds()); | 50 | set_fs(get_ds()); |
50 | rc = vfs_write(inode_info->lower_file, data, size, &offset); | 51 | rc = vfs_write(lower_file, data, size, &offset); |
51 | set_fs(fs_save); | 52 | set_fs(fs_save); |
52 | mark_inode_dirty_sync(ecryptfs_inode); | 53 | mark_inode_dirty_sync(ecryptfs_inode); |
53 | return rc; | 54 | return rc; |
54 | } | 55 | } |
55 | 56 | ||
56 | /** | 57 | /** |
57 | * ecryptfs_write_lower_page_segment | 58 | * ecryptfs_write_lower_page_segment |
58 | * @ecryptfs_inode: The eCryptfs inode | 59 | * @ecryptfs_inode: The eCryptfs inode |
59 | * @page_for_lower: The page containing the data to be written to the | 60 | * @page_for_lower: The page containing the data to be written to the |
60 | * lower file | 61 | * lower file |
61 | * @offset_in_page: The offset in the @page_for_lower from which to | 62 | * @offset_in_page: The offset in the @page_for_lower from which to |
62 | * start writing the data | 63 | * start writing the data |
63 | * @size: The amount of data from @page_for_lower to write to the | 64 | * @size: The amount of data from @page_for_lower to write to the |
64 | * lower file | 65 | * lower file |
65 | * | 66 | * |
66 | * Determines the byte offset in the file for the given page and | 67 | * Determines the byte offset in the file for the given page and |
67 | * offset within the page, maps the page, and makes the call to write | 68 | * offset within the page, maps the page, and makes the call to write |
68 | * the contents of @page_for_lower to the lower inode. | 69 | * the contents of @page_for_lower to the lower inode. |
69 | * | 70 | * |
70 | * Returns zero on success; non-zero otherwise | 71 | * Returns zero on success; non-zero otherwise |
71 | */ | 72 | */ |
72 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | 73 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, |
73 | struct page *page_for_lower, | 74 | struct page *page_for_lower, |
74 | size_t offset_in_page, size_t size) | 75 | size_t offset_in_page, size_t size) |
75 | { | 76 | { |
76 | char *virt; | 77 | char *virt; |
77 | loff_t offset; | 78 | loff_t offset; |
78 | int rc; | 79 | int rc; |
79 | 80 | ||
80 | offset = ((((loff_t)page_for_lower->index) << PAGE_CACHE_SHIFT) | 81 | offset = ((((loff_t)page_for_lower->index) << PAGE_CACHE_SHIFT) |
81 | + offset_in_page); | 82 | + offset_in_page); |
82 | virt = kmap(page_for_lower); | 83 | virt = kmap(page_for_lower); |
83 | rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); | 84 | rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); |
84 | if (rc > 0) | 85 | if (rc > 0) |
85 | rc = 0; | 86 | rc = 0; |
86 | kunmap(page_for_lower); | 87 | kunmap(page_for_lower); |
87 | return rc; | 88 | return rc; |
88 | } | 89 | } |
89 | 90 | ||
90 | /** | 91 | /** |
91 | * ecryptfs_write | 92 | * ecryptfs_write |
92 | * @ecryptfs_inode: The eCryptfs file into which to write | 93 | * @ecryptfs_inode: The eCryptfs file into which to write |
93 | * @data: Virtual address where data to write is located | 94 | * @data: Virtual address where data to write is located |
94 | * @offset: Offset in the eCryptfs file at which to begin writing the | 95 | * @offset: Offset in the eCryptfs file at which to begin writing the |
95 | * data from @data | 96 | * data from @data |
96 | * @size: The number of bytes to write from @data | 97 | * @size: The number of bytes to write from @data |
97 | * | 98 | * |
98 | * Write an arbitrary amount of data to an arbitrary location in the | 99 | * Write an arbitrary amount of data to an arbitrary location in the |
99 | * eCryptfs inode page cache. This is done on a page-by-page, and then | 100 | * eCryptfs inode page cache. This is done on a page-by-page, and then |
100 | * by an extent-by-extent, basis; individual extents are encrypted and | 101 | * by an extent-by-extent, basis; individual extents are encrypted and |
101 | * written to the lower page cache (via VFS writes). This function | 102 | * written to the lower page cache (via VFS writes). This function |
102 | * takes care of all the address translation to locations in the lower | 103 | * takes care of all the address translation to locations in the lower |
103 | * filesystem; it also handles truncate events, writing out zeros | 104 | * filesystem; it also handles truncate events, writing out zeros |
104 | * where necessary. | 105 | * where necessary. |
105 | * | 106 | * |
106 | * Returns zero on success; non-zero otherwise | 107 | * Returns zero on success; non-zero otherwise |
107 | */ | 108 | */ |
108 | int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, | 109 | int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, |
109 | size_t size) | 110 | size_t size) |
110 | { | 111 | { |
111 | struct page *ecryptfs_page; | 112 | struct page *ecryptfs_page; |
112 | struct ecryptfs_crypt_stat *crypt_stat; | 113 | struct ecryptfs_crypt_stat *crypt_stat; |
113 | char *ecryptfs_page_virt; | 114 | char *ecryptfs_page_virt; |
114 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); | 115 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
115 | loff_t data_offset = 0; | 116 | loff_t data_offset = 0; |
116 | loff_t pos; | 117 | loff_t pos; |
117 | int rc = 0; | 118 | int rc = 0; |
118 | 119 | ||
119 | crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 120 | crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
120 | /* | 121 | /* |
121 | * if we are writing beyond current size, then start pos | 122 | * if we are writing beyond current size, then start pos |
122 | * at the current size - we'll fill in zeros from there. | 123 | * at the current size - we'll fill in zeros from there. |
123 | */ | 124 | */ |
124 | if (offset > ecryptfs_file_size) | 125 | if (offset > ecryptfs_file_size) |
125 | pos = ecryptfs_file_size; | 126 | pos = ecryptfs_file_size; |
126 | else | 127 | else |
127 | pos = offset; | 128 | pos = offset; |
128 | while (pos < (offset + size)) { | 129 | while (pos < (offset + size)) { |
129 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); | 130 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); |
130 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); | 131 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); |
131 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); | 132 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); |
132 | size_t total_remaining_bytes = ((offset + size) - pos); | 133 | size_t total_remaining_bytes = ((offset + size) - pos); |
133 | 134 | ||
134 | if (num_bytes > total_remaining_bytes) | 135 | if (num_bytes > total_remaining_bytes) |
135 | num_bytes = total_remaining_bytes; | 136 | num_bytes = total_remaining_bytes; |
136 | if (pos < offset) { | 137 | if (pos < offset) { |
137 | /* remaining zeros to write, up to destination offset */ | 138 | /* remaining zeros to write, up to destination offset */ |
138 | size_t total_remaining_zeros = (offset - pos); | 139 | size_t total_remaining_zeros = (offset - pos); |
139 | 140 | ||
140 | if (num_bytes > total_remaining_zeros) | 141 | if (num_bytes > total_remaining_zeros) |
141 | num_bytes = total_remaining_zeros; | 142 | num_bytes = total_remaining_zeros; |
142 | } | 143 | } |
143 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, | 144 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, |
144 | ecryptfs_page_idx); | 145 | ecryptfs_page_idx); |
145 | if (IS_ERR(ecryptfs_page)) { | 146 | if (IS_ERR(ecryptfs_page)) { |
146 | rc = PTR_ERR(ecryptfs_page); | 147 | rc = PTR_ERR(ecryptfs_page); |
147 | printk(KERN_ERR "%s: Error getting page at " | 148 | printk(KERN_ERR "%s: Error getting page at " |
148 | "index [%ld] from eCryptfs inode " | 149 | "index [%ld] from eCryptfs inode " |
149 | "mapping; rc = [%d]\n", __func__, | 150 | "mapping; rc = [%d]\n", __func__, |
150 | ecryptfs_page_idx, rc); | 151 | ecryptfs_page_idx, rc); |
151 | goto out; | 152 | goto out; |
152 | } | 153 | } |
153 | ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); | 154 | ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); |
154 | 155 | ||
155 | /* | 156 | /* |
156 | * pos: where we're now writing, offset: where the request was | 157 | * pos: where we're now writing, offset: where the request was |
157 | * If current pos is before request, we are filling zeros | 158 | * If current pos is before request, we are filling zeros |
158 | * If we are at or beyond request, we are writing the *data* | 159 | * If we are at or beyond request, we are writing the *data* |
159 | * If we're in a fresh page beyond eof, zero it in either case | 160 | * If we're in a fresh page beyond eof, zero it in either case |
160 | */ | 161 | */ |
161 | if (pos < offset || !start_offset_in_page) { | 162 | if (pos < offset || !start_offset_in_page) { |
162 | /* We are extending past the previous end of the file. | 163 | /* We are extending past the previous end of the file. |
163 | * Fill in zero values to the end of the page */ | 164 | * Fill in zero values to the end of the page */ |
164 | memset(((char *)ecryptfs_page_virt | 165 | memset(((char *)ecryptfs_page_virt |
165 | + start_offset_in_page), 0, | 166 | + start_offset_in_page), 0, |
166 | PAGE_CACHE_SIZE - start_offset_in_page); | 167 | PAGE_CACHE_SIZE - start_offset_in_page); |
167 | } | 168 | } |
168 | 169 | ||
169 | /* pos >= offset, we are now writing the data request */ | 170 | /* pos >= offset, we are now writing the data request */ |
170 | if (pos >= offset) { | 171 | if (pos >= offset) { |
171 | memcpy(((char *)ecryptfs_page_virt | 172 | memcpy(((char *)ecryptfs_page_virt |
172 | + start_offset_in_page), | 173 | + start_offset_in_page), |
173 | (data + data_offset), num_bytes); | 174 | (data + data_offset), num_bytes); |
174 | data_offset += num_bytes; | 175 | data_offset += num_bytes; |
175 | } | 176 | } |
176 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); | 177 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); |
177 | flush_dcache_page(ecryptfs_page); | 178 | flush_dcache_page(ecryptfs_page); |
178 | SetPageUptodate(ecryptfs_page); | 179 | SetPageUptodate(ecryptfs_page); |
179 | unlock_page(ecryptfs_page); | 180 | unlock_page(ecryptfs_page); |
180 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) | 181 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
181 | rc = ecryptfs_encrypt_page(ecryptfs_page); | 182 | rc = ecryptfs_encrypt_page(ecryptfs_page); |
182 | else | 183 | else |
183 | rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, | 184 | rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, |
184 | ecryptfs_page, | 185 | ecryptfs_page, |
185 | start_offset_in_page, | 186 | start_offset_in_page, |
186 | data_offset); | 187 | data_offset); |
187 | page_cache_release(ecryptfs_page); | 188 | page_cache_release(ecryptfs_page); |
188 | if (rc) { | 189 | if (rc) { |
189 | printk(KERN_ERR "%s: Error encrypting " | 190 | printk(KERN_ERR "%s: Error encrypting " |
190 | "page; rc = [%d]\n", __func__, rc); | 191 | "page; rc = [%d]\n", __func__, rc); |
191 | goto out; | 192 | goto out; |
192 | } | 193 | } |
193 | pos += num_bytes; | 194 | pos += num_bytes; |
194 | } | 195 | } |
195 | if ((offset + size) > ecryptfs_file_size) { | 196 | if ((offset + size) > ecryptfs_file_size) { |
196 | i_size_write(ecryptfs_inode, (offset + size)); | 197 | i_size_write(ecryptfs_inode, (offset + size)); |
197 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { | 198 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { |
198 | rc = ecryptfs_write_inode_size_to_metadata( | 199 | rc = ecryptfs_write_inode_size_to_metadata( |
199 | ecryptfs_inode); | 200 | ecryptfs_inode); |
200 | if (rc) { | 201 | if (rc) { |
201 | printk(KERN_ERR "Problem with " | 202 | printk(KERN_ERR "Problem with " |
202 | "ecryptfs_write_inode_size_to_metadata; " | 203 | "ecryptfs_write_inode_size_to_metadata; " |
203 | "rc = [%d]\n", rc); | 204 | "rc = [%d]\n", rc); |
204 | goto out; | 205 | goto out; |
205 | } | 206 | } |
206 | } | 207 | } |
207 | } | 208 | } |
208 | out: | 209 | out: |
209 | return rc; | 210 | return rc; |
210 | } | 211 | } |
211 | 212 | ||
212 | /** | 213 | /** |
213 | * ecryptfs_read_lower | 214 | * ecryptfs_read_lower |
214 | * @data: The read data is stored here by this function | 215 | * @data: The read data is stored here by this function |
215 | * @offset: Byte offset in the lower file from which to read the data | 216 | * @offset: Byte offset in the lower file from which to read the data |
216 | * @size: Number of bytes to read from @offset of the lower file and | 217 | * @size: Number of bytes to read from @offset of the lower file and |
217 | * store into @data | 218 | * store into @data |
218 | * @ecryptfs_inode: The eCryptfs inode | 219 | * @ecryptfs_inode: The eCryptfs inode |
219 | * | 220 | * |
220 | * Read @size bytes of data at byte offset @offset from the lower | 221 | * Read @size bytes of data at byte offset @offset from the lower |
221 | * inode into memory location @data. | 222 | * inode into memory location @data. |
222 | * | 223 | * |
223 | * Returns bytes read on success; 0 on EOF; less than zero on error | 224 | * Returns bytes read on success; 0 on EOF; less than zero on error |
224 | */ | 225 | */ |
225 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | 226 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
226 | struct inode *ecryptfs_inode) | 227 | struct inode *ecryptfs_inode) |
227 | { | 228 | { |
228 | struct ecryptfs_inode_info *inode_info = | 229 | struct file *lower_file; |
229 | ecryptfs_inode_to_private(ecryptfs_inode); | ||
230 | mm_segment_t fs_save; | 230 | mm_segment_t fs_save; |
231 | ssize_t rc; | 231 | ssize_t rc; |
232 | 232 | ||
233 | BUG_ON(!inode_info->lower_file); | 233 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
234 | if (!lower_file) | ||
235 | return -EIO; | ||
234 | fs_save = get_fs(); | 236 | fs_save = get_fs(); |
235 | set_fs(get_ds()); | 237 | set_fs(get_ds()); |
236 | rc = vfs_read(inode_info->lower_file, data, size, &offset); | 238 | rc = vfs_read(lower_file, data, size, &offset); |
237 | set_fs(fs_save); | 239 | set_fs(fs_save); |
238 | return rc; | 240 | return rc; |
239 | } | 241 | } |
240 | 242 | ||
241 | /** | 243 | /** |
242 | * ecryptfs_read_lower_page_segment | 244 | * ecryptfs_read_lower_page_segment |
243 | * @page_for_ecryptfs: The page into which data for eCryptfs will be | 245 | * @page_for_ecryptfs: The page into which data for eCryptfs will be |
244 | * written | 246 | * written |
245 | * @offset_in_page: Offset in @page_for_ecryptfs from which to start | 247 | * @offset_in_page: Offset in @page_for_ecryptfs from which to start |
246 | * writing | 248 | * writing |
247 | * @size: The number of bytes to write into @page_for_ecryptfs | 249 | * @size: The number of bytes to write into @page_for_ecryptfs |
248 | * @ecryptfs_inode: The eCryptfs inode | 250 | * @ecryptfs_inode: The eCryptfs inode |
249 | * | 251 | * |
250 | * Determines the byte offset in the file for the given page and | 252 | * Determines the byte offset in the file for the given page and |
251 | * offset within the page, maps the page, and makes the call to read | 253 | * offset within the page, maps the page, and makes the call to read |
252 | * the contents of @page_for_ecryptfs from the lower inode. | 254 | * the contents of @page_for_ecryptfs from the lower inode. |
253 | * | 255 | * |
254 | * Returns zero on success; non-zero otherwise | 256 | * Returns zero on success; non-zero otherwise |
255 | */ | 257 | */ |
256 | int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | 258 | int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, |
257 | pgoff_t page_index, | 259 | pgoff_t page_index, |
258 | size_t offset_in_page, size_t size, | 260 | size_t offset_in_page, size_t size, |
259 | struct inode *ecryptfs_inode) | 261 | struct inode *ecryptfs_inode) |
260 | { | 262 | { |
261 | char *virt; | 263 | char *virt; |
262 | loff_t offset; | 264 | loff_t offset; |
263 | int rc; | 265 | int rc; |
264 | 266 | ||
265 | offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page); | 267 | offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page); |
266 | virt = kmap(page_for_ecryptfs); | 268 | virt = kmap(page_for_ecryptfs); |
267 | rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); | 269 | rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); |
268 | if (rc > 0) | 270 | if (rc > 0) |
269 | rc = 0; | 271 | rc = 0; |
270 | kunmap(page_for_ecryptfs); | 272 | kunmap(page_for_ecryptfs); |
271 | flush_dcache_page(page_for_ecryptfs); | 273 | flush_dcache_page(page_for_ecryptfs); |
272 | return rc; | 274 | return rc; |
273 | } | 275 | } |
274 | 276 | ||
275 | #if 0 | 277 | #if 0 |
276 | /** | 278 | /** |
277 | * ecryptfs_read | 279 | * ecryptfs_read |
278 | * @data: The virtual address into which to write the data read (and | 280 | * @data: The virtual address into which to write the data read (and |
279 | * possibly decrypted) from the lower file | 281 | * possibly decrypted) from the lower file |
280 | * @offset: The offset in the decrypted view of the file from which to | 282 | * @offset: The offset in the decrypted view of the file from which to |
281 | * read into @data | 283 | * read into @data |
282 | * @size: The number of bytes to read into @data | 284 | * @size: The number of bytes to read into @data |
283 | * @ecryptfs_file: The eCryptfs file from which to read | 285 | * @ecryptfs_file: The eCryptfs file from which to read |
284 | * | 286 | * |
285 | * Read an arbitrary amount of data from an arbitrary location in the | 287 | * Read an arbitrary amount of data from an arbitrary location in the |
286 | * eCryptfs page cache. This is done on an extent-by-extent basis; | 288 | * eCryptfs page cache. This is done on an extent-by-extent basis; |
287 | * individual extents are decrypted and read from the lower page | 289 | * individual extents are decrypted and read from the lower page |
288 | * cache (via VFS reads). This function takes care of all the | 290 | * cache (via VFS reads). This function takes care of all the |
289 | * address translation to locations in the lower filesystem. | 291 | * address translation to locations in the lower filesystem. |
290 | * | 292 | * |
291 | * Returns zero on success; non-zero otherwise | 293 | * Returns zero on success; non-zero otherwise |
292 | */ | 294 | */ |
293 | int ecryptfs_read(char *data, loff_t offset, size_t size, | 295 | int ecryptfs_read(char *data, loff_t offset, size_t size, |
294 | struct file *ecryptfs_file) | 296 | struct file *ecryptfs_file) |
295 | { | 297 | { |
296 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | 298 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; |
297 | struct page *ecryptfs_page; | 299 | struct page *ecryptfs_page; |
298 | char *ecryptfs_page_virt; | 300 | char *ecryptfs_page_virt; |
299 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); | 301 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
300 | loff_t data_offset = 0; | 302 | loff_t data_offset = 0; |
301 | loff_t pos; | 303 | loff_t pos; |
302 | int rc = 0; | 304 | int rc = 0; |
303 | 305 | ||
304 | if ((offset + size) > ecryptfs_file_size) { | 306 | if ((offset + size) > ecryptfs_file_size) { |
305 | rc = -EINVAL; | 307 | rc = -EINVAL; |
306 | printk(KERN_ERR "%s: Attempt to read data past the end of the " | 308 | printk(KERN_ERR "%s: Attempt to read data past the end of the " |
307 | "file; offset = [%lld]; size = [%td]; " | 309 | "file; offset = [%lld]; size = [%td]; " |
308 | "ecryptfs_file_size = [%lld]\n", | 310 | "ecryptfs_file_size = [%lld]\n", |
309 | __func__, offset, size, ecryptfs_file_size); | 311 | __func__, offset, size, ecryptfs_file_size); |
310 | goto out; | 312 | goto out; |
311 | } | 313 | } |
312 | pos = offset; | 314 | pos = offset; |
313 | while (pos < (offset + size)) { | 315 | while (pos < (offset + size)) { |
314 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); | 316 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); |
315 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); | 317 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); |
316 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); | 318 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); |
317 | size_t total_remaining_bytes = ((offset + size) - pos); | 319 | size_t total_remaining_bytes = ((offset + size) - pos); |
318 | 320 | ||
319 | if (num_bytes > total_remaining_bytes) | 321 | if (num_bytes > total_remaining_bytes) |
320 | num_bytes = total_remaining_bytes; | 322 | num_bytes = total_remaining_bytes; |
321 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, | 323 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, |
322 | ecryptfs_page_idx); | 324 | ecryptfs_page_idx); |
323 | if (IS_ERR(ecryptfs_page)) { | 325 | if (IS_ERR(ecryptfs_page)) { |
324 | rc = PTR_ERR(ecryptfs_page); | 326 | rc = PTR_ERR(ecryptfs_page); |
325 | printk(KERN_ERR "%s: Error getting page at " | 327 | printk(KERN_ERR "%s: Error getting page at " |
326 | "index [%ld] from eCryptfs inode " | 328 | "index [%ld] from eCryptfs inode " |
327 | "mapping; rc = [%d]\n", __func__, | 329 | "mapping; rc = [%d]\n", __func__, |
328 | ecryptfs_page_idx, rc); | 330 | ecryptfs_page_idx, rc); |
329 | goto out; | 331 | goto out; |
330 | } | 332 | } |
331 | ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); | 333 | ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); |
332 | memcpy((data + data_offset), | 334 | memcpy((data + data_offset), |
333 | ((char *)ecryptfs_page_virt + start_offset_in_page), | 335 | ((char *)ecryptfs_page_virt + start_offset_in_page), |
334 | num_bytes); | 336 | num_bytes); |
335 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); | 337 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); |
336 | flush_dcache_page(ecryptfs_page); | 338 | flush_dcache_page(ecryptfs_page); |
337 | SetPageUptodate(ecryptfs_page); | 339 | SetPageUptodate(ecryptfs_page); |
338 | unlock_page(ecryptfs_page); | 340 | unlock_page(ecryptfs_page); |
339 | page_cache_release(ecryptfs_page); | 341 | page_cache_release(ecryptfs_page); |
340 | pos += num_bytes; | 342 | pos += num_bytes; |
341 | data_offset += num_bytes; | 343 | data_offset += num_bytes; |
342 | } | 344 | } |
343 | out: | 345 | out: |
344 | return rc; | 346 | return rc; |
345 | } | 347 | } |
346 | #endif /* 0 */ | 348 | #endif /* 0 */ |