diff options
Diffstat (limited to 'fs/ecryptfs/keystore.c')
-rw-r--r-- | fs/ecryptfs/keystore.c | 802 |
1 files changed, 718 insertions, 84 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 745c0f1bfbbd..c209f67e7a26 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -7,6 +7,7 @@ | |||
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 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
12 | * 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 |
@@ -64,26 +65,6 @@ int process_request_key_err(long err_code) | |||
64 | return rc; | 65 | return rc; |
65 | } | 66 | } |
66 | 67 | ||
67 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
68 | { | ||
69 | struct list_head *walker; | ||
70 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
71 | |||
72 | walker = auth_tok_list_head->next; | ||
73 | while (walker != auth_tok_list_head) { | ||
74 | auth_tok_list_item = | ||
75 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
76 | list); | ||
77 | walker = auth_tok_list_item->list.next; | ||
78 | memset(auth_tok_list_item, 0, | ||
79 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
80 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
81 | auth_tok_list_item); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
86 | |||
87 | /** | 68 | /** |
88 | * parse_packet_length | 69 | * parse_packet_length |
89 | * @data: Pointer to memory containing length at offset | 70 | * @data: Pointer to memory containing length at offset |
@@ -102,12 +83,12 @@ static int parse_packet_length(unsigned char *data, size_t *size, | |||
102 | (*size) = 0; | 83 | (*size) = 0; |
103 | if (data[0] < 192) { | 84 | if (data[0] < 192) { |
104 | /* One-byte length */ | 85 | /* One-byte length */ |
105 | (*size) = data[0]; | 86 | (*size) = (unsigned char)data[0]; |
106 | (*length_size) = 1; | 87 | (*length_size) = 1; |
107 | } else if (data[0] < 224) { | 88 | } else if (data[0] < 224) { |
108 | /* Two-byte length */ | 89 | /* Two-byte length */ |
109 | (*size) = ((data[0] - 192) * 256); | 90 | (*size) = (((unsigned char)(data[0]) - 192) * 256); |
110 | (*size) += (data[1] + 192); | 91 | (*size) += ((unsigned char)(data[1]) + 192); |
111 | (*length_size) = 2; | 92 | (*length_size) = 2; |
112 | } else if (data[0] == 255) { | 93 | } else if (data[0] == 255) { |
113 | /* Five-byte length; we're not supposed to see this */ | 94 | /* Five-byte length; we're not supposed to see this */ |
@@ -154,6 +135,499 @@ static int write_packet_length(char *dest, size_t size, | |||
154 | return rc; | 135 | return rc; |
155 | } | 136 | } |
156 | 137 | ||
138 | static int | ||
139 | write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, | ||
140 | char **packet, size_t *packet_len) | ||
141 | { | ||
142 | size_t i = 0; | ||
143 | size_t data_len; | ||
144 | size_t packet_size_len; | ||
145 | char *message; | ||
146 | int rc; | ||
147 | |||
148 | /* | ||
149 | * ***** TAG 64 Packet Format ***** | ||
150 | * | Content Type | 1 byte | | ||
151 | * | Key Identifier Size | 1 or 2 bytes | | ||
152 | * | Key Identifier | arbitrary | | ||
153 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | ||
154 | * | Encrypted File Encryption Key | arbitrary | | ||
155 | */ | ||
156 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX | ||
157 | + session_key->encrypted_key_size); | ||
158 | *packet = kmalloc(data_len, GFP_KERNEL); | ||
159 | message = *packet; | ||
160 | if (!message) { | ||
161 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
162 | rc = -ENOMEM; | ||
163 | goto out; | ||
164 | } | ||
165 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; | ||
166 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | ||
167 | &packet_size_len); | ||
168 | if (rc) { | ||
169 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | ||
170 | "header; cannot generate packet length\n"); | ||
171 | goto out; | ||
172 | } | ||
173 | i += packet_size_len; | ||
174 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | ||
175 | i += ECRYPTFS_SIG_SIZE_HEX; | ||
176 | rc = write_packet_length(&message[i], session_key->encrypted_key_size, | ||
177 | &packet_size_len); | ||
178 | if (rc) { | ||
179 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | ||
180 | "header; cannot generate packet length\n"); | ||
181 | goto out; | ||
182 | } | ||
183 | i += packet_size_len; | ||
184 | memcpy(&message[i], session_key->encrypted_key, | ||
185 | session_key->encrypted_key_size); | ||
186 | i += session_key->encrypted_key_size; | ||
187 | *packet_len = i; | ||
188 | out: | ||
189 | return rc; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u16 *cipher_code, | ||
194 | struct ecryptfs_message *msg) | ||
195 | { | ||
196 | size_t i = 0; | ||
197 | char *data; | ||
198 | size_t data_len; | ||
199 | size_t m_size; | ||
200 | size_t message_len; | ||
201 | u16 checksum = 0; | ||
202 | u16 expected_checksum = 0; | ||
203 | int rc; | ||
204 | |||
205 | /* | ||
206 | * ***** TAG 65 Packet Format ***** | ||
207 | * | Content Type | 1 byte | | ||
208 | * | Status Indicator | 1 byte | | ||
209 | * | File Encryption Key Size | 1 or 2 bytes | | ||
210 | * | File Encryption Key | arbitrary | | ||
211 | */ | ||
212 | message_len = msg->data_len; | ||
213 | data = msg->data; | ||
214 | if (message_len < 4) { | ||
215 | rc = -EIO; | ||
216 | goto out; | ||
217 | } | ||
218 | if (data[i++] != ECRYPTFS_TAG_65_PACKET_TYPE) { | ||
219 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_65\n"); | ||
220 | rc = -EIO; | ||
221 | goto out; | ||
222 | } | ||
223 | if (data[i++]) { | ||
224 | ecryptfs_printk(KERN_ERR, "Status indicator has non-zero value " | ||
225 | "[%d]\n", data[i-1]); | ||
226 | rc = -EIO; | ||
227 | goto out; | ||
228 | } | ||
229 | rc = parse_packet_length(&data[i], &m_size, &data_len); | ||
230 | if (rc) { | ||
231 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
232 | "rc = [%d]\n", rc); | ||
233 | goto out; | ||
234 | } | ||
235 | i += data_len; | ||
236 | if (message_len < (i + m_size)) { | ||
237 | ecryptfs_printk(KERN_ERR, "The received netlink message is " | ||
238 | "shorter than expected\n"); | ||
239 | rc = -EIO; | ||
240 | goto out; | ||
241 | } | ||
242 | if (m_size < 3) { | ||
243 | ecryptfs_printk(KERN_ERR, | ||
244 | "The decrypted key is not long enough to " | ||
245 | "include a cipher code and checksum\n"); | ||
246 | rc = -EIO; | ||
247 | goto out; | ||
248 | } | ||
249 | *cipher_code = data[i++]; | ||
250 | /* The decrypted key includes 1 byte cipher code and 2 byte checksum */ | ||
251 | session_key->decrypted_key_size = m_size - 3; | ||
252 | if (session_key->decrypted_key_size > ECRYPTFS_MAX_KEY_BYTES) { | ||
253 | ecryptfs_printk(KERN_ERR, "key_size [%d] larger than " | ||
254 | "the maximum key size [%d]\n", | ||
255 | session_key->decrypted_key_size, | ||
256 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
257 | rc = -EIO; | ||
258 | goto out; | ||
259 | } | ||
260 | memcpy(session_key->decrypted_key, &data[i], | ||
261 | session_key->decrypted_key_size); | ||
262 | i += session_key->decrypted_key_size; | ||
263 | expected_checksum += (unsigned char)(data[i++]) << 8; | ||
264 | expected_checksum += (unsigned char)(data[i++]); | ||
265 | for (i = 0; i < session_key->decrypted_key_size; i++) | ||
266 | checksum += session_key->decrypted_key[i]; | ||
267 | if (expected_checksum != checksum) { | ||
268 | ecryptfs_printk(KERN_ERR, "Invalid checksum for file " | ||
269 | "encryption key; expected [%x]; calculated " | ||
270 | "[%x]\n", expected_checksum, checksum); | ||
271 | rc = -EIO; | ||
272 | } | ||
273 | out: | ||
274 | return rc; | ||
275 | } | ||
276 | |||
277 | |||
278 | static int | ||
279 | write_tag_66_packet(char *signature, size_t cipher_code, | ||
280 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, | ||
281 | size_t *packet_len) | ||
282 | { | ||
283 | size_t i = 0; | ||
284 | size_t j; | ||
285 | size_t data_len; | ||
286 | size_t checksum = 0; | ||
287 | size_t packet_size_len; | ||
288 | char *message; | ||
289 | int rc; | ||
290 | |||
291 | /* | ||
292 | * ***** TAG 66 Packet Format ***** | ||
293 | * | Content Type | 1 byte | | ||
294 | * | Key Identifier Size | 1 or 2 bytes | | ||
295 | * | Key Identifier | arbitrary | | ||
296 | * | File Encryption Key Size | 1 or 2 bytes | | ||
297 | * | File Encryption Key | arbitrary | | ||
298 | */ | ||
299 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size); | ||
300 | *packet = kmalloc(data_len, GFP_KERNEL); | ||
301 | message = *packet; | ||
302 | if (!message) { | ||
303 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
304 | rc = -ENOMEM; | ||
305 | goto out; | ||
306 | } | ||
307 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; | ||
308 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | ||
309 | &packet_size_len); | ||
310 | if (rc) { | ||
311 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | ||
312 | "header; cannot generate packet length\n"); | ||
313 | goto out; | ||
314 | } | ||
315 | i += packet_size_len; | ||
316 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | ||
317 | i += ECRYPTFS_SIG_SIZE_HEX; | ||
318 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ | ||
319 | rc = write_packet_length(&message[i], crypt_stat->key_size + 3, | ||
320 | &packet_size_len); | ||
321 | if (rc) { | ||
322 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | ||
323 | "header; cannot generate packet length\n"); | ||
324 | goto out; | ||
325 | } | ||
326 | i += packet_size_len; | ||
327 | message[i++] = cipher_code; | ||
328 | memcpy(&message[i], crypt_stat->key, crypt_stat->key_size); | ||
329 | i += crypt_stat->key_size; | ||
330 | for (j = 0; j < crypt_stat->key_size; j++) | ||
331 | checksum += crypt_stat->key[j]; | ||
332 | message[i++] = (checksum / 256) % 256; | ||
333 | message[i++] = (checksum % 256); | ||
334 | *packet_len = i; | ||
335 | out: | ||
336 | return rc; | ||
337 | } | ||
338 | |||
339 | static int | ||
340 | parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | ||
341 | struct ecryptfs_message *msg) | ||
342 | { | ||
343 | size_t i = 0; | ||
344 | char *data; | ||
345 | size_t data_len; | ||
346 | size_t message_len; | ||
347 | int rc; | ||
348 | |||
349 | /* | ||
350 | * ***** TAG 65 Packet Format ***** | ||
351 | * | Content Type | 1 byte | | ||
352 | * | Status Indicator | 1 byte | | ||
353 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | ||
354 | * | Encrypted File Encryption Key | arbitrary | | ||
355 | */ | ||
356 | message_len = msg->data_len; | ||
357 | data = msg->data; | ||
358 | /* verify that everything through the encrypted FEK size is present */ | ||
359 | if (message_len < 4) { | ||
360 | rc = -EIO; | ||
361 | goto out; | ||
362 | } | ||
363 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { | ||
364 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_67\n"); | ||
365 | rc = -EIO; | ||
366 | goto out; | ||
367 | } | ||
368 | if (data[i++]) { | ||
369 | ecryptfs_printk(KERN_ERR, "Status indicator has non zero value" | ||
370 | " [%d]\n", data[i-1]); | ||
371 | rc = -EIO; | ||
372 | goto out; | ||
373 | } | ||
374 | rc = parse_packet_length(&data[i], &key_rec->enc_key_size, &data_len); | ||
375 | if (rc) { | ||
376 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
377 | "rc = [%d]\n", rc); | ||
378 | goto out; | ||
379 | } | ||
380 | i += data_len; | ||
381 | if (message_len < (i + key_rec->enc_key_size)) { | ||
382 | ecryptfs_printk(KERN_ERR, "message_len [%d]; max len is [%d]\n", | ||
383 | message_len, (i + key_rec->enc_key_size)); | ||
384 | rc = -EIO; | ||
385 | goto out; | ||
386 | } | ||
387 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | ||
388 | ecryptfs_printk(KERN_ERR, "Encrypted key_size [%d] larger than " | ||
389 | "the maximum key size [%d]\n", | ||
390 | key_rec->enc_key_size, | ||
391 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
392 | rc = -EIO; | ||
393 | goto out; | ||
394 | } | ||
395 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); | ||
396 | out: | ||
397 | return rc; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * decrypt_pki_encrypted_session_key - Decrypt the session key with | ||
402 | * the given auth_tok. | ||
403 | * | ||
404 | * Returns Zero on success; non-zero error otherwise. | ||
405 | */ | ||
406 | static int decrypt_pki_encrypted_session_key( | ||
407 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
408 | struct ecryptfs_auth_tok *auth_tok, | ||
409 | struct ecryptfs_crypt_stat *crypt_stat) | ||
410 | { | ||
411 | u16 cipher_code = 0; | ||
412 | struct ecryptfs_msg_ctx *msg_ctx; | ||
413 | struct ecryptfs_message *msg = NULL; | ||
414 | char *netlink_message; | ||
415 | size_t netlink_message_length; | ||
416 | int rc; | ||
417 | |||
418 | rc = write_tag_64_packet(mount_crypt_stat->global_auth_tok_sig, | ||
419 | &(auth_tok->session_key), | ||
420 | &netlink_message, &netlink_message_length); | ||
421 | if (rc) { | ||
422 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); | ||
423 | goto out; | ||
424 | } | ||
425 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_message, | ||
426 | netlink_message_length, &msg_ctx); | ||
427 | if (rc) { | ||
428 | ecryptfs_printk(KERN_ERR, "Error sending netlink message\n"); | ||
429 | goto out; | ||
430 | } | ||
431 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | ||
432 | if (rc) { | ||
433 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 65 packet " | ||
434 | "from the user space daemon\n"); | ||
435 | rc = -EIO; | ||
436 | goto out; | ||
437 | } | ||
438 | rc = parse_tag_65_packet(&(auth_tok->session_key), | ||
439 | &cipher_code, msg); | ||
440 | if (rc) { | ||
441 | printk(KERN_ERR "Failed to parse tag 65 packet; rc = [%d]\n", | ||
442 | rc); | ||
443 | goto out; | ||
444 | } | ||
445 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
446 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | ||
447 | auth_tok->session_key.decrypted_key_size); | ||
448 | crypt_stat->key_size = auth_tok->session_key.decrypted_key_size; | ||
449 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, cipher_code); | ||
450 | if (rc) { | ||
451 | ecryptfs_printk(KERN_ERR, "Cipher code [%d] is invalid\n", | ||
452 | cipher_code) | ||
453 | goto out; | ||
454 | } | ||
455 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | ||
456 | if (ecryptfs_verbosity > 0) { | ||
457 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | ||
458 | ecryptfs_dump_hex(crypt_stat->key, | ||
459 | crypt_stat->key_size); | ||
460 | } | ||
461 | out: | ||
462 | if (msg) | ||
463 | kfree(msg); | ||
464 | return rc; | ||
465 | } | ||
466 | |||
467 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
468 | { | ||
469 | struct list_head *walker; | ||
470 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
471 | |||
472 | walker = auth_tok_list_head->next; | ||
473 | while (walker != auth_tok_list_head) { | ||
474 | auth_tok_list_item = | ||
475 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
476 | list); | ||
477 | walker = auth_tok_list_item->list.next; | ||
478 | memset(auth_tok_list_item, 0, | ||
479 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
480 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
481 | auth_tok_list_item); | ||
482 | } | ||
483 | auth_tok_list_head->next = NULL; | ||
484 | } | ||
485 | |||
486 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
487 | |||
488 | |||
489 | /** | ||
490 | * parse_tag_1_packet | ||
491 | * @crypt_stat: The cryptographic context to modify based on packet | ||
492 | * contents. | ||
493 | * @data: The raw bytes of the packet. | ||
494 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; | ||
495 | * a new authentication token will be placed at the end | ||
496 | * of this list for this packet. | ||
497 | * @new_auth_tok: Pointer to a pointer to memory that this function | ||
498 | * allocates; sets the memory address of the pointer to | ||
499 | * NULL on error. This object is added to the | ||
500 | * auth_tok_list. | ||
501 | * @packet_size: This function writes the size of the parsed packet | ||
502 | * into this memory location; zero on error. | ||
503 | * | ||
504 | * Returns zero on success; non-zero on error. | ||
505 | */ | ||
506 | static int | ||
507 | parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | ||
508 | unsigned char *data, struct list_head *auth_tok_list, | ||
509 | struct ecryptfs_auth_tok **new_auth_tok, | ||
510 | size_t *packet_size, size_t max_packet_size) | ||
511 | { | ||
512 | size_t body_size; | ||
513 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
514 | size_t length_size; | ||
515 | int rc = 0; | ||
516 | |||
517 | (*packet_size) = 0; | ||
518 | (*new_auth_tok) = NULL; | ||
519 | |||
520 | /* we check that: | ||
521 | * one byte for the Tag 1 ID flag | ||
522 | * two bytes for the body size | ||
523 | * do not exceed the maximum_packet_size | ||
524 | */ | ||
525 | if (unlikely((*packet_size) + 3 > max_packet_size)) { | ||
526 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
527 | rc = -EINVAL; | ||
528 | goto out; | ||
529 | } | ||
530 | /* check for Tag 1 identifier - one byte */ | ||
531 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { | ||
532 | ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", | ||
533 | ECRYPTFS_TAG_1_PACKET_TYPE); | ||
534 | rc = -EINVAL; | ||
535 | goto out; | ||
536 | } | ||
537 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | ||
538 | * at end of function upon failure */ | ||
539 | auth_tok_list_item = | ||
540 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, | ||
541 | GFP_KERNEL); | ||
542 | if (!auth_tok_list_item) { | ||
543 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
544 | rc = -ENOMEM; | ||
545 | goto out; | ||
546 | } | ||
547 | memset(auth_tok_list_item, 0, | ||
548 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
549 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | ||
550 | /* check for body size - one to two bytes | ||
551 | * | ||
552 | * ***** TAG 1 Packet Format ***** | ||
553 | * | version number | 1 byte | | ||
554 | * | key ID | 8 bytes | | ||
555 | * | public key algorithm | 1 byte | | ||
556 | * | encrypted session key | arbitrary | | ||
557 | */ | ||
558 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | ||
559 | &length_size); | ||
560 | if (rc) { | ||
561 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
562 | "rc = [%d]\n", rc); | ||
563 | goto out_free; | ||
564 | } | ||
565 | if (unlikely(body_size < (0x02 + ECRYPTFS_SIG_SIZE))) { | ||
566 | ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", | ||
567 | body_size); | ||
568 | rc = -EINVAL; | ||
569 | goto out_free; | ||
570 | } | ||
571 | (*packet_size) += length_size; | ||
572 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | ||
573 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
574 | rc = -EINVAL; | ||
575 | goto out_free; | ||
576 | } | ||
577 | /* Version 3 (from RFC2440) - one byte */ | ||
578 | if (unlikely(data[(*packet_size)++] != 0x03)) { | ||
579 | ecryptfs_printk(KERN_DEBUG, "Unknown version number " | ||
580 | "[%d]\n", data[(*packet_size) - 1]); | ||
581 | rc = -EINVAL; | ||
582 | goto out_free; | ||
583 | } | ||
584 | /* Read Signature */ | ||
585 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, | ||
586 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); | ||
587 | *packet_size += ECRYPTFS_SIG_SIZE; | ||
588 | /* This byte is skipped because the kernel does not need to | ||
589 | * know which public key encryption algorithm was used */ | ||
590 | (*packet_size)++; | ||
591 | (*new_auth_tok)->session_key.encrypted_key_size = | ||
592 | body_size - (0x02 + ECRYPTFS_SIG_SIZE); | ||
593 | if ((*new_auth_tok)->session_key.encrypted_key_size | ||
594 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | ||
595 | ecryptfs_printk(KERN_ERR, "Tag 1 packet contains key larger " | ||
596 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); | ||
597 | rc = -EINVAL; | ||
598 | goto out; | ||
599 | } | ||
600 | ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n", | ||
601 | (*new_auth_tok)->session_key.encrypted_key_size); | ||
602 | memcpy((*new_auth_tok)->session_key.encrypted_key, | ||
603 | &data[(*packet_size)], (body_size - 0x02 - ECRYPTFS_SIG_SIZE)); | ||
604 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; | ||
605 | (*new_auth_tok)->session_key.flags &= | ||
606 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
607 | (*new_auth_tok)->session_key.flags |= | ||
608 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | ||
609 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; | ||
610 | (*new_auth_tok)->flags |= ECRYPTFS_PRIVATE_KEY; | ||
611 | /* TODO: Why are we setting this flag here? Don't we want the | ||
612 | * userspace to decrypt the session key? */ | ||
613 | (*new_auth_tok)->session_key.flags &= | ||
614 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | ||
615 | (*new_auth_tok)->session_key.flags &= | ||
616 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | ||
617 | list_add(&auth_tok_list_item->list, auth_tok_list); | ||
618 | goto out; | ||
619 | out_free: | ||
620 | (*new_auth_tok) = NULL; | ||
621 | memset(auth_tok_list_item, 0, | ||
622 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
623 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
624 | auth_tok_list_item); | ||
625 | out: | ||
626 | if (rc) | ||
627 | (*packet_size) = 0; | ||
628 | return rc; | ||
629 | } | ||
630 | |||
157 | /** | 631 | /** |
158 | * parse_tag_3_packet | 632 | * parse_tag_3_packet |
159 | * @crypt_stat: The cryptographic context to modify based on packet | 633 | * @crypt_stat: The cryptographic context to modify based on packet |
@@ -178,10 +652,10 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
178 | struct ecryptfs_auth_tok **new_auth_tok, | 652 | struct ecryptfs_auth_tok **new_auth_tok, |
179 | size_t *packet_size, size_t max_packet_size) | 653 | size_t *packet_size, size_t max_packet_size) |
180 | { | 654 | { |
181 | int rc = 0; | ||
182 | size_t body_size; | 655 | size_t body_size; |
183 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 656 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
184 | size_t length_size; | 657 | size_t length_size; |
658 | int rc = 0; | ||
185 | 659 | ||
186 | (*packet_size) = 0; | 660 | (*packet_size) = 0; |
187 | (*new_auth_tok) = NULL; | 661 | (*new_auth_tok) = NULL; |
@@ -207,14 +681,12 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 681 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
208 | * at end of function upon failure */ | 682 | * at end of function upon failure */ |
209 | auth_tok_list_item = | 683 | auth_tok_list_item = |
210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); | 684 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); |
211 | if (!auth_tok_list_item) { | 685 | if (!auth_tok_list_item) { |
212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 686 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); |
213 | rc = -ENOMEM; | 687 | rc = -ENOMEM; |
214 | goto out; | 688 | goto out; |
215 | } | 689 | } |
216 | memset(auth_tok_list_item, 0, | ||
217 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
218 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 690 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
219 | 691 | ||
220 | /* check for body size - one to two bytes */ | 692 | /* check for body size - one to two bytes */ |
@@ -321,10 +793,10 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
321 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; | 793 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; |
322 | /* TODO: Parametarize; we might actually want userspace to | 794 | /* TODO: Parametarize; we might actually want userspace to |
323 | * decrypt the session key. */ | 795 | * decrypt the session key. */ |
324 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | 796 | (*new_auth_tok)->session_key.flags &= |
325 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | 797 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); |
326 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | 798 | (*new_auth_tok)->session_key.flags &= |
327 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | 799 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); |
328 | list_add(&auth_tok_list_item->list, auth_tok_list); | 800 | list_add(&auth_tok_list_item->list, auth_tok_list); |
329 | goto out; | 801 | goto out; |
330 | out_free: | 802 | out_free: |
@@ -360,9 +832,9 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, | |||
360 | size_t max_contents_bytes, size_t *tag_11_contents_size, | 832 | size_t max_contents_bytes, size_t *tag_11_contents_size, |
361 | size_t *packet_size, size_t max_packet_size) | 833 | size_t *packet_size, size_t max_packet_size) |
362 | { | 834 | { |
363 | int rc = 0; | ||
364 | size_t body_size; | 835 | size_t body_size; |
365 | size_t length_size; | 836 | size_t length_size; |
837 | int rc = 0; | ||
366 | 838 | ||
367 | (*packet_size) = 0; | 839 | (*packet_size) = 0; |
368 | (*tag_11_contents_size) = 0; | 840 | (*tag_11_contents_size) = 0; |
@@ -461,7 +933,6 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
461 | struct ecryptfs_password *password_s_ptr; | 933 | struct ecryptfs_password *password_s_ptr; |
462 | struct scatterlist src_sg[2], dst_sg[2]; | 934 | struct scatterlist src_sg[2], dst_sg[2]; |
463 | struct mutex *tfm_mutex = NULL; | 935 | struct mutex *tfm_mutex = NULL; |
464 | /* TODO: Use virt_to_scatterlist for these */ | ||
465 | char *encrypted_session_key; | 936 | char *encrypted_session_key; |
466 | char *session_key; | 937 | char *session_key; |
467 | struct blkcipher_desc desc = { | 938 | struct blkcipher_desc desc = { |
@@ -470,8 +941,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
470 | int rc = 0; | 941 | int rc = 0; |
471 | 942 | ||
472 | password_s_ptr = &auth_tok->token.password; | 943 | password_s_ptr = &auth_tok->token.password; |
473 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, | 944 | if (password_s_ptr->flags & ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) |
474 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) | ||
475 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key " | 945 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key " |
476 | "set; skipping key generation\n"); | 946 | "set; skipping key generation\n"); |
477 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" | 947 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" |
@@ -553,7 +1023,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
553 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1023 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
554 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | 1024 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, |
555 | auth_tok->session_key.decrypted_key_size); | 1025 | auth_tok->session_key.decrypted_key_size); |
556 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | 1026 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
557 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | 1027 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); |
558 | if (ecryptfs_verbosity > 0) | 1028 | if (ecryptfs_verbosity > 0) |
559 | ecryptfs_dump_hex(crypt_stat->key, | 1029 | ecryptfs_dump_hex(crypt_stat->key, |
@@ -589,7 +1059,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
589 | struct dentry *ecryptfs_dentry) | 1059 | struct dentry *ecryptfs_dentry) |
590 | { | 1060 | { |
591 | size_t i = 0; | 1061 | size_t i = 0; |
592 | int rc = 0; | ||
593 | size_t found_auth_tok = 0; | 1062 | size_t found_auth_tok = 0; |
594 | size_t next_packet_is_auth_tok_packet; | 1063 | size_t next_packet_is_auth_tok_packet; |
595 | char sig[ECRYPTFS_SIG_SIZE_HEX]; | 1064 | char sig[ECRYPTFS_SIG_SIZE_HEX]; |
@@ -605,6 +1074,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
605 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; | 1074 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; |
606 | size_t tag_11_contents_size; | 1075 | size_t tag_11_contents_size; |
607 | size_t tag_11_packet_size; | 1076 | size_t tag_11_packet_size; |
1077 | int rc = 0; | ||
608 | 1078 | ||
609 | INIT_LIST_HEAD(&auth_tok_list); | 1079 | INIT_LIST_HEAD(&auth_tok_list); |
610 | /* Parse the header to find as many packets as we can, these will be | 1080 | /* Parse the header to find as many packets as we can, these will be |
@@ -656,8 +1126,21 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
656 | sig_tmp_space, tag_11_contents_size); | 1126 | sig_tmp_space, tag_11_contents_size); |
657 | new_auth_tok->token.password.signature[ | 1127 | new_auth_tok->token.password.signature[ |
658 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; | 1128 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; |
659 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | 1129 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
660 | ECRYPTFS_ENCRYPTED); | 1130 | break; |
1131 | case ECRYPTFS_TAG_1_PACKET_TYPE: | ||
1132 | rc = parse_tag_1_packet(crypt_stat, | ||
1133 | (unsigned char *)&src[i], | ||
1134 | &auth_tok_list, &new_auth_tok, | ||
1135 | &packet_size, max_packet_size); | ||
1136 | if (rc) { | ||
1137 | ecryptfs_printk(KERN_ERR, "Error parsing " | ||
1138 | "tag 1 packet\n"); | ||
1139 | rc = -EIO; | ||
1140 | goto out_wipe_list; | ||
1141 | } | ||
1142 | i += packet_size; | ||
1143 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; | ||
661 | break; | 1144 | break; |
662 | case ECRYPTFS_TAG_11_PACKET_TYPE: | 1145 | case ECRYPTFS_TAG_11_PACKET_TYPE: |
663 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " | 1146 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " |
@@ -706,31 +1189,46 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
706 | goto leave_list; | 1189 | goto leave_list; |
707 | /* TODO: Transfer the common salt into the | 1190 | /* TODO: Transfer the common salt into the |
708 | * crypt_stat salt */ | 1191 | * crypt_stat salt */ |
1192 | } else if ((candidate_auth_tok->token_type | ||
1193 | == ECRYPTFS_PRIVATE_KEY) | ||
1194 | && !strncmp(candidate_auth_tok->token.private_key.signature, | ||
1195 | sig, ECRYPTFS_SIG_SIZE_HEX)) { | ||
1196 | found_auth_tok = 1; | ||
1197 | goto leave_list; | ||
709 | } | 1198 | } |
710 | } | 1199 | } |
711 | leave_list: | ||
712 | if (!found_auth_tok) { | 1200 | if (!found_auth_tok) { |
713 | ecryptfs_printk(KERN_ERR, "Could not find authentication " | 1201 | ecryptfs_printk(KERN_ERR, "Could not find authentication " |
714 | "token on temporary list for sig [%.*s]\n", | 1202 | "token on temporary list for sig [%.*s]\n", |
715 | ECRYPTFS_SIG_SIZE_HEX, sig); | 1203 | ECRYPTFS_SIG_SIZE_HEX, sig); |
716 | rc = -EIO; | 1204 | rc = -EIO; |
717 | goto out_wipe_list; | 1205 | goto out_wipe_list; |
718 | } else { | 1206 | } |
1207 | leave_list: | ||
1208 | rc = -ENOTSUPP; | ||
1209 | if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | ||
1210 | memcpy(&(candidate_auth_tok->token.private_key), | ||
1211 | &(chosen_auth_tok->token.private_key), | ||
1212 | sizeof(struct ecryptfs_private_key)); | ||
1213 | rc = decrypt_pki_encrypted_session_key(mount_crypt_stat, | ||
1214 | candidate_auth_tok, | ||
1215 | crypt_stat); | ||
1216 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { | ||
719 | memcpy(&(candidate_auth_tok->token.password), | 1217 | memcpy(&(candidate_auth_tok->token.password), |
720 | &(chosen_auth_tok->token.password), | 1218 | &(chosen_auth_tok->token.password), |
721 | sizeof(struct ecryptfs_password)); | 1219 | sizeof(struct ecryptfs_password)); |
722 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); | 1220 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); |
723 | if (rc) { | 1221 | } |
724 | ecryptfs_printk(KERN_ERR, "Error decrypting the " | 1222 | if (rc) { |
725 | "session key\n"); | 1223 | ecryptfs_printk(KERN_ERR, "Error decrypting the " |
726 | goto out_wipe_list; | 1224 | "session key; rc = [%d]\n", rc); |
727 | } | 1225 | goto out_wipe_list; |
728 | rc = ecryptfs_compute_root_iv(crypt_stat); | 1226 | } |
729 | if (rc) { | 1227 | rc = ecryptfs_compute_root_iv(crypt_stat); |
730 | ecryptfs_printk(KERN_ERR, "Error computing " | 1228 | if (rc) { |
731 | "the root IV\n"); | 1229 | ecryptfs_printk(KERN_ERR, "Error computing " |
732 | goto out_wipe_list; | 1230 | "the root IV\n"); |
733 | } | 1231 | goto out_wipe_list; |
734 | } | 1232 | } |
735 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | 1233 | rc = ecryptfs_init_crypt_ctx(crypt_stat); |
736 | if (rc) { | 1234 | if (rc) { |
@@ -743,6 +1241,145 @@ out_wipe_list: | |||
743 | out: | 1241 | out: |
744 | return rc; | 1242 | return rc; |
745 | } | 1243 | } |
1244 | static int | ||
1245 | pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | ||
1246 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1247 | struct ecryptfs_key_record *key_rec) | ||
1248 | { | ||
1249 | struct ecryptfs_msg_ctx *msg_ctx = NULL; | ||
1250 | char *netlink_payload; | ||
1251 | size_t netlink_payload_length; | ||
1252 | struct ecryptfs_message *msg; | ||
1253 | int rc; | ||
1254 | |||
1255 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, | ||
1256 | ecryptfs_code_for_cipher_string(crypt_stat), | ||
1257 | crypt_stat, &netlink_payload, | ||
1258 | &netlink_payload_length); | ||
1259 | if (rc) { | ||
1260 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); | ||
1261 | goto out; | ||
1262 | } | ||
1263 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_payload, | ||
1264 | netlink_payload_length, &msg_ctx); | ||
1265 | if (rc) { | ||
1266 | ecryptfs_printk(KERN_ERR, "Error sending netlink message\n"); | ||
1267 | goto out; | ||
1268 | } | ||
1269 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | ||
1270 | if (rc) { | ||
1271 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 67 packet " | ||
1272 | "from the user space daemon\n"); | ||
1273 | rc = -EIO; | ||
1274 | goto out; | ||
1275 | } | ||
1276 | rc = parse_tag_67_packet(key_rec, msg); | ||
1277 | if (rc) | ||
1278 | ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n"); | ||
1279 | kfree(msg); | ||
1280 | out: | ||
1281 | if (netlink_payload) | ||
1282 | kfree(netlink_payload); | ||
1283 | return rc; | ||
1284 | } | ||
1285 | /** | ||
1286 | * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet | ||
1287 | * @dest: Buffer into which to write the packet | ||
1288 | * @max: Maximum number of bytes that can be writtn | ||
1289 | * @packet_size: This function will write the number of bytes that end | ||
1290 | * up constituting the packet; set to zero on error | ||
1291 | * | ||
1292 | * Returns zero on success; non-zero on error. | ||
1293 | */ | ||
1294 | static int | ||
1295 | write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | ||
1296 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1297 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
1298 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | ||
1299 | { | ||
1300 | size_t i; | ||
1301 | size_t encrypted_session_key_valid = 0; | ||
1302 | size_t key_rec_size; | ||
1303 | size_t packet_size_length; | ||
1304 | int rc = 0; | ||
1305 | |||
1306 | (*packet_size) = 0; | ||
1307 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.private_key.signature, | ||
1308 | ECRYPTFS_SIG_SIZE); | ||
1309 | encrypted_session_key_valid = 0; | ||
1310 | for (i = 0; i < crypt_stat->key_size; i++) | ||
1311 | encrypted_session_key_valid |= | ||
1312 | auth_tok->session_key.encrypted_key[i]; | ||
1313 | if (encrypted_session_key_valid) { | ||
1314 | memcpy(key_rec->enc_key, | ||
1315 | auth_tok->session_key.encrypted_key, | ||
1316 | auth_tok->session_key.encrypted_key_size); | ||
1317 | goto encrypted_session_key_set; | ||
1318 | } | ||
1319 | if (auth_tok->session_key.encrypted_key_size == 0) | ||
1320 | auth_tok->session_key.encrypted_key_size = | ||
1321 | auth_tok->token.private_key.key_size; | ||
1322 | rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec); | ||
1323 | if (rc) { | ||
1324 | ecryptfs_printk(KERN_ERR, "Failed to encrypt session key " | ||
1325 | "via a pki"); | ||
1326 | goto out; | ||
1327 | } | ||
1328 | if (ecryptfs_verbosity > 0) { | ||
1329 | ecryptfs_printk(KERN_DEBUG, "Encrypted key:\n"); | ||
1330 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); | ||
1331 | } | ||
1332 | encrypted_session_key_set: | ||
1333 | /* Now we have a valid key_rec. Append it to the | ||
1334 | * key_rec set. */ | ||
1335 | key_rec_size = (sizeof(struct ecryptfs_key_record) | ||
1336 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | ||
1337 | + (key_rec->enc_key_size)); | ||
1338 | /* TODO: Include a packet size limit as a parameter to this | ||
1339 | * function once we have multi-packet headers (for versions | ||
1340 | * later than 0.1 */ | ||
1341 | if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { | ||
1342 | ecryptfs_printk(KERN_ERR, "Keyset too large\n"); | ||
1343 | rc = -EINVAL; | ||
1344 | goto out; | ||
1345 | } | ||
1346 | /* ***** TAG 1 Packet Format ***** | ||
1347 | * | version number | 1 byte | | ||
1348 | * | key ID | 8 bytes | | ||
1349 | * | public key algorithm | 1 byte | | ||
1350 | * | encrypted session key | arbitrary | | ||
1351 | */ | ||
1352 | if ((0x02 + ECRYPTFS_SIG_SIZE + key_rec->enc_key_size) >= max) { | ||
1353 | ecryptfs_printk(KERN_ERR, | ||
1354 | "Authentication token is too large\n"); | ||
1355 | rc = -EINVAL; | ||
1356 | goto out; | ||
1357 | } | ||
1358 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; | ||
1359 | /* This format is inspired by OpenPGP; see RFC 2440 | ||
1360 | * packet tag 1 */ | ||
1361 | rc = write_packet_length(&dest[(*packet_size)], | ||
1362 | (0x02 + ECRYPTFS_SIG_SIZE + | ||
1363 | key_rec->enc_key_size), | ||
1364 | &packet_size_length); | ||
1365 | if (rc) { | ||
1366 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " | ||
1367 | "header; cannot generate packet length\n"); | ||
1368 | goto out; | ||
1369 | } | ||
1370 | (*packet_size) += packet_size_length; | ||
1371 | dest[(*packet_size)++] = 0x03; /* version 3 */ | ||
1372 | memcpy(&dest[(*packet_size)], key_rec->sig, ECRYPTFS_SIG_SIZE); | ||
1373 | (*packet_size) += ECRYPTFS_SIG_SIZE; | ||
1374 | dest[(*packet_size)++] = RFC2440_CIPHER_RSA; | ||
1375 | memcpy(&dest[(*packet_size)], key_rec->enc_key, | ||
1376 | key_rec->enc_key_size); | ||
1377 | (*packet_size) += key_rec->enc_key_size; | ||
1378 | out: | ||
1379 | if (rc) | ||
1380 | (*packet_size) = 0; | ||
1381 | return rc; | ||
1382 | } | ||
746 | 1383 | ||
747 | /** | 1384 | /** |
748 | * write_tag_11_packet | 1385 | * write_tag_11_packet |
@@ -758,8 +1395,8 @@ static int | |||
758 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, | 1395 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, |
759 | size_t *packet_length) | 1396 | size_t *packet_length) |
760 | { | 1397 | { |
761 | int rc = 0; | ||
762 | size_t packet_size_length; | 1398 | size_t packet_size_length; |
1399 | int rc = 0; | ||
763 | 1400 | ||
764 | (*packet_length) = 0; | 1401 | (*packet_length) = 0; |
765 | if ((13 + contents_length) > max) { | 1402 | if ((13 + contents_length) > max) { |
@@ -817,7 +1454,6 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
817 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 1454 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
818 | { | 1455 | { |
819 | size_t i; | 1456 | size_t i; |
820 | size_t signature_is_valid = 0; | ||
821 | size_t encrypted_session_key_valid = 0; | 1457 | size_t encrypted_session_key_valid = 0; |
822 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 1458 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
823 | struct scatterlist dest_sg[2]; | 1459 | struct scatterlist dest_sg[2]; |
@@ -833,19 +1469,14 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
833 | int rc = 0; | 1469 | int rc = 0; |
834 | 1470 | ||
835 | (*packet_size) = 0; | 1471 | (*packet_size) = 0; |
836 | /* Check for a valid signature on the auth_tok */ | 1472 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, |
837 | for (i = 0; i < ECRYPTFS_SIG_SIZE_HEX; i++) | ||
838 | signature_is_valid |= auth_tok->token.password.signature[i]; | ||
839 | if (!signature_is_valid) | ||
840 | BUG(); | ||
841 | ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature, | ||
842 | ECRYPTFS_SIG_SIZE); | 1473 | ECRYPTFS_SIG_SIZE); |
843 | encrypted_session_key_valid = 0; | 1474 | encrypted_session_key_valid = 0; |
844 | for (i = 0; i < crypt_stat->key_size; i++) | 1475 | for (i = 0; i < crypt_stat->key_size; i++) |
845 | encrypted_session_key_valid |= | 1476 | encrypted_session_key_valid |= |
846 | auth_tok->session_key.encrypted_key[i]; | 1477 | auth_tok->session_key.encrypted_key[i]; |
847 | if (encrypted_session_key_valid) { | 1478 | if (encrypted_session_key_valid) { |
848 | memcpy((*key_rec).enc_key, | 1479 | memcpy(key_rec->enc_key, |
849 | auth_tok->session_key.encrypted_key, | 1480 | auth_tok->session_key.encrypted_key, |
850 | auth_tok->session_key.encrypted_key_size); | 1481 | auth_tok->session_key.encrypted_key_size); |
851 | goto encrypted_session_key_set; | 1482 | goto encrypted_session_key_set; |
@@ -858,10 +1489,10 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
858 | memset((crypt_stat->key + 24), 0, 8); | 1489 | memset((crypt_stat->key + 24), 0, 8); |
859 | auth_tok->session_key.encrypted_key_size = 32; | 1490 | auth_tok->session_key.encrypted_key_size = 32; |
860 | } | 1491 | } |
861 | (*key_rec).enc_key_size = | 1492 | key_rec->enc_key_size = |
862 | auth_tok->session_key.encrypted_key_size; | 1493 | auth_tok->session_key.encrypted_key_size; |
863 | if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags, | 1494 | if (auth_tok->token.password.flags & |
864 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) { | 1495 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { |
865 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " | 1496 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " |
866 | "session key encryption key of size [%d]\n", | 1497 | "session key encryption key of size [%d]\n", |
867 | auth_tok->token.password. | 1498 | auth_tok->token.password. |
@@ -879,15 +1510,15 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
879 | ecryptfs_dump_hex(session_key_encryption_key, 16); | 1510 | ecryptfs_dump_hex(session_key_encryption_key, 16); |
880 | } | 1511 | } |
881 | rc = virt_to_scatterlist(crypt_stat->key, | 1512 | rc = virt_to_scatterlist(crypt_stat->key, |
882 | (*key_rec).enc_key_size, src_sg, 2); | 1513 | key_rec->enc_key_size, src_sg, 2); |
883 | if (!rc) { | 1514 | if (!rc) { |
884 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1515 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
885 | "for crypt_stat session key\n"); | 1516 | "for crypt_stat session key\n"); |
886 | rc = -ENOMEM; | 1517 | rc = -ENOMEM; |
887 | goto out; | 1518 | goto out; |
888 | } | 1519 | } |
889 | rc = virt_to_scatterlist((*key_rec).enc_key, | 1520 | rc = virt_to_scatterlist(key_rec->enc_key, |
890 | (*key_rec).enc_key_size, dest_sg, 2); | 1521 | key_rec->enc_key_size, dest_sg, 2); |
891 | if (!rc) { | 1522 | if (!rc) { |
892 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1523 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
893 | "for crypt_stat encrypted session key\n"); | 1524 | "for crypt_stat encrypted session key\n"); |
@@ -943,14 +1574,14 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
943 | mutex_unlock(tfm_mutex); | 1574 | mutex_unlock(tfm_mutex); |
944 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 1575 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
945 | if (ecryptfs_verbosity > 0) | 1576 | if (ecryptfs_verbosity > 0) |
946 | ecryptfs_dump_hex((*key_rec).enc_key, | 1577 | ecryptfs_dump_hex(key_rec->enc_key, |
947 | (*key_rec).enc_key_size); | 1578 | key_rec->enc_key_size); |
948 | encrypted_session_key_set: | 1579 | encrypted_session_key_set: |
949 | /* Now we have a valid key_rec. Append it to the | 1580 | /* Now we have a valid key_rec. Append it to the |
950 | * key_rec set. */ | 1581 | * key_rec set. */ |
951 | key_rec_size = (sizeof(struct ecryptfs_key_record) | 1582 | key_rec_size = (sizeof(struct ecryptfs_key_record) |
952 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | 1583 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES |
953 | + ((*key_rec).enc_key_size)); | 1584 | + (key_rec->enc_key_size)); |
954 | /* TODO: Include a packet size limit as a parameter to this | 1585 | /* TODO: Include a packet size limit as a parameter to this |
955 | * function once we have multi-packet headers (for versions | 1586 | * function once we have multi-packet headers (for versions |
956 | * later than 0.1 */ | 1587 | * later than 0.1 */ |
@@ -962,7 +1593,7 @@ encrypted_session_key_set: | |||
962 | /* TODO: Packet size limit */ | 1593 | /* TODO: Packet size limit */ |
963 | /* We have 5 bytes of surrounding packet data */ | 1594 | /* We have 5 bytes of surrounding packet data */ |
964 | if ((0x05 + ECRYPTFS_SALT_SIZE | 1595 | if ((0x05 + ECRYPTFS_SALT_SIZE |
965 | + (*key_rec).enc_key_size) >= max) { | 1596 | + key_rec->enc_key_size) >= max) { |
966 | ecryptfs_printk(KERN_ERR, "Authentication token is too " | 1597 | ecryptfs_printk(KERN_ERR, "Authentication token is too " |
967 | "large\n"); | 1598 | "large\n"); |
968 | rc = -EINVAL; | 1599 | rc = -EINVAL; |
@@ -974,7 +1605,7 @@ encrypted_session_key_set: | |||
974 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ | 1605 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ |
975 | rc = write_packet_length(&dest[(*packet_size)], | 1606 | rc = write_packet_length(&dest[(*packet_size)], |
976 | (0x05 + ECRYPTFS_SALT_SIZE | 1607 | (0x05 + ECRYPTFS_SALT_SIZE |
977 | + (*key_rec).enc_key_size), | 1608 | + key_rec->enc_key_size), |
978 | &packet_size_length); | 1609 | &packet_size_length); |
979 | if (rc) { | 1610 | if (rc) { |
980 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " | 1611 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " |
@@ -997,9 +1628,9 @@ encrypted_session_key_set: | |||
997 | ECRYPTFS_SALT_SIZE); | 1628 | ECRYPTFS_SALT_SIZE); |
998 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ | 1629 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ |
999 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ | 1630 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ |
1000 | memcpy(&dest[(*packet_size)], (*key_rec).enc_key, | 1631 | memcpy(&dest[(*packet_size)], key_rec->enc_key, |
1001 | (*key_rec).enc_key_size); | 1632 | key_rec->enc_key_size); |
1002 | (*packet_size) += (*key_rec).enc_key_size; | 1633 | (*packet_size) += key_rec->enc_key_size; |
1003 | out: | 1634 | out: |
1004 | if (desc.tfm && !tfm_mutex) | 1635 | if (desc.tfm && !tfm_mutex) |
1005 | crypto_free_blkcipher(desc.tfm); | 1636 | crypto_free_blkcipher(desc.tfm); |
@@ -1029,13 +1660,13 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1029 | struct dentry *ecryptfs_dentry, size_t *len, | 1660 | struct dentry *ecryptfs_dentry, size_t *len, |
1030 | size_t max) | 1661 | size_t max) |
1031 | { | 1662 | { |
1032 | int rc = 0; | ||
1033 | struct ecryptfs_auth_tok *auth_tok; | 1663 | struct ecryptfs_auth_tok *auth_tok; |
1034 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1664 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
1035 | &ecryptfs_superblock_to_private( | 1665 | &ecryptfs_superblock_to_private( |
1036 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1666 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1037 | size_t written; | 1667 | size_t written; |
1038 | struct ecryptfs_key_record key_rec; | 1668 | struct ecryptfs_key_record key_rec; |
1669 | int rc = 0; | ||
1039 | 1670 | ||
1040 | (*len) = 0; | 1671 | (*len) = 0; |
1041 | if (mount_crypt_stat->global_auth_tok) { | 1672 | if (mount_crypt_stat->global_auth_tok) { |
@@ -1062,20 +1693,23 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1062 | goto out; | 1693 | goto out; |
1063 | } | 1694 | } |
1064 | (*len) += written; | 1695 | (*len) += written; |
1696 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | ||
1697 | rc = write_tag_1_packet(dest_base + (*len), | ||
1698 | max, auth_tok, | ||
1699 | crypt_stat,mount_crypt_stat, | ||
1700 | &key_rec, &written); | ||
1701 | if (rc) { | ||
1702 | ecryptfs_printk(KERN_WARNING, "Error " | ||
1703 | "writing tag 1 packet\n"); | ||
1704 | goto out; | ||
1705 | } | ||
1706 | (*len) += written; | ||
1065 | } else { | 1707 | } else { |
1066 | ecryptfs_printk(KERN_WARNING, "Unsupported " | 1708 | ecryptfs_printk(KERN_WARNING, "Unsupported " |
1067 | "authentication token type\n"); | 1709 | "authentication token type\n"); |
1068 | rc = -EINVAL; | 1710 | rc = -EINVAL; |
1069 | goto out; | 1711 | goto out; |
1070 | } | 1712 | } |
1071 | if (rc) { | ||
1072 | ecryptfs_printk(KERN_WARNING, "Error writing " | ||
1073 | "authentication token packet with sig " | ||
1074 | "= [%s]\n", | ||
1075 | mount_crypt_stat->global_auth_tok_sig); | ||
1076 | rc = -EIO; | ||
1077 | goto out; | ||
1078 | } | ||
1079 | } else | 1713 | } else |
1080 | BUG(); | 1714 | BUG(); |
1081 | if (likely((max - (*len)) > 0)) { | 1715 | if (likely((max - (*len)) > 0)) { |