aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ecryptfs/crypto.c141
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h3
2 files changed, 103 insertions, 41 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index d5c25db4398f..f71ec125290d 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -243,7 +243,7 @@ void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
243 struct ecryptfs_key_sig *key_sig, *key_sig_tmp; 243 struct ecryptfs_key_sig *key_sig, *key_sig_tmp;
244 244
245 if (crypt_stat->tfm) 245 if (crypt_stat->tfm)
246 crypto_free_blkcipher(crypt_stat->tfm); 246 crypto_free_ablkcipher(crypt_stat->tfm);
247 if (crypt_stat->hash_tfm) 247 if (crypt_stat->hash_tfm)
248 crypto_free_hash(crypt_stat->hash_tfm); 248 crypto_free_hash(crypt_stat->hash_tfm);
249 list_for_each_entry_safe(key_sig, key_sig_tmp, 249 list_for_each_entry_safe(key_sig, key_sig_tmp,
@@ -319,6 +319,22 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
319 return i; 319 return i;
320} 320}
321 321
322struct extent_crypt_result {
323 struct completion completion;
324 int rc;
325};
326
327static void extent_crypt_complete(struct crypto_async_request *req, int rc)
328{
329 struct extent_crypt_result *ecr = req->data;
330
331 if (rc == -EINPROGRESS)
332 return;
333
334 ecr->rc = rc;
335 complete(&ecr->completion);
336}
337
322/** 338/**
323 * encrypt_scatterlist 339 * encrypt_scatterlist
324 * @crypt_stat: Pointer to the crypt_stat struct to initialize. 340 * @crypt_stat: Pointer to the crypt_stat struct to initialize.
@@ -334,11 +350,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
334 struct scatterlist *src_sg, int size, 350 struct scatterlist *src_sg, int size,
335 unsigned char *iv) 351 unsigned char *iv)
336{ 352{
337 struct blkcipher_desc desc = { 353 struct ablkcipher_request *req = NULL;
338 .tfm = crypt_stat->tfm, 354 struct extent_crypt_result ecr;
339 .info = iv,
340 .flags = CRYPTO_TFM_REQ_MAY_SLEEP
341 };
342 int rc = 0; 355 int rc = 0;
343 356
344 BUG_ON(!crypt_stat || !crypt_stat->tfm 357 BUG_ON(!crypt_stat || !crypt_stat->tfm
@@ -349,24 +362,47 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
349 ecryptfs_dump_hex(crypt_stat->key, 362 ecryptfs_dump_hex(crypt_stat->key,
350 crypt_stat->key_size); 363 crypt_stat->key_size);
351 } 364 }
352 /* Consider doing this once, when the file is opened */ 365
366 init_completion(&ecr.completion);
367
353 mutex_lock(&crypt_stat->cs_tfm_mutex); 368 mutex_lock(&crypt_stat->cs_tfm_mutex);
354 if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) { 369 req = ablkcipher_request_alloc(crypt_stat->tfm, GFP_NOFS);
355 rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, 370 if (!req) {
356 crypt_stat->key_size);
357 crypt_stat->flags |= ECRYPTFS_KEY_SET;
358 }
359 if (rc) {
360 ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
361 rc);
362 mutex_unlock(&crypt_stat->cs_tfm_mutex); 371 mutex_unlock(&crypt_stat->cs_tfm_mutex);
363 rc = -EINVAL; 372 rc = -ENOMEM;
364 goto out; 373 goto out;
365 } 374 }
366 ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); 375
367 crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size); 376 ablkcipher_request_set_callback(req,
377 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
378 extent_crypt_complete, &ecr);
379 /* Consider doing this once, when the file is opened */
380 if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
381 rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
382 crypt_stat->key_size);
383 if (rc) {
384 ecryptfs_printk(KERN_ERR,
385 "Error setting key; rc = [%d]\n",
386 rc);
387 mutex_unlock(&crypt_stat->cs_tfm_mutex);
388 rc = -EINVAL;
389 goto out;
390 }
391 crypt_stat->flags |= ECRYPTFS_KEY_SET;
392 }
368 mutex_unlock(&crypt_stat->cs_tfm_mutex); 393 mutex_unlock(&crypt_stat->cs_tfm_mutex);
394 ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
395 ablkcipher_request_set_crypt(req, src_sg, dest_sg, size, iv);
396 rc = crypto_ablkcipher_encrypt(req);
397 if (rc == -EINPROGRESS || rc == -EBUSY) {
398 struct extent_crypt_result *ecr = req->base.data;
399
400 wait_for_completion(&ecr->completion);
401 rc = ecr->rc;
402 INIT_COMPLETION(ecr->completion);
403 }
369out: 404out:
405 ablkcipher_request_free(req);
370 return rc; 406 return rc;
371} 407}
372 408
@@ -624,35 +660,61 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
624 struct scatterlist *src_sg, int size, 660 struct scatterlist *src_sg, int size,
625 unsigned char *iv) 661 unsigned char *iv)
626{ 662{
627 struct blkcipher_desc desc = { 663 struct ablkcipher_request *req = NULL;
628 .tfm = crypt_stat->tfm, 664 struct extent_crypt_result ecr;
629 .info = iv,
630 .flags = CRYPTO_TFM_REQ_MAY_SLEEP
631 };
632 int rc = 0; 665 int rc = 0;
633 666
634 /* Consider doing this once, when the file is opened */ 667 BUG_ON(!crypt_stat || !crypt_stat->tfm
668 || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
669 if (unlikely(ecryptfs_verbosity > 0)) {
670 ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",
671 crypt_stat->key_size);
672 ecryptfs_dump_hex(crypt_stat->key,
673 crypt_stat->key_size);
674 }
675
676 init_completion(&ecr.completion);
677
635 mutex_lock(&crypt_stat->cs_tfm_mutex); 678 mutex_lock(&crypt_stat->cs_tfm_mutex);
636 rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, 679 req = ablkcipher_request_alloc(crypt_stat->tfm, GFP_NOFS);
637 crypt_stat->key_size); 680 if (!req) {
638 if (rc) {
639 ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
640 rc);
641 mutex_unlock(&crypt_stat->cs_tfm_mutex); 681 mutex_unlock(&crypt_stat->cs_tfm_mutex);
642 rc = -EINVAL; 682 rc = -ENOMEM;
643 goto out; 683 goto out;
644 } 684 }
645 ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); 685
646 rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size); 686 ablkcipher_request_set_callback(req,
687 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
688 extent_crypt_complete, &ecr);
689 /* Consider doing this once, when the file is opened */
690 if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
691 rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
692 crypt_stat->key_size);
693 if (rc) {
694 ecryptfs_printk(KERN_ERR,
695 "Error setting key; rc = [%d]\n",
696 rc);
697 mutex_unlock(&crypt_stat->cs_tfm_mutex);
698 rc = -EINVAL;
699 goto out;
700 }
701 crypt_stat->flags |= ECRYPTFS_KEY_SET;
702 }
647 mutex_unlock(&crypt_stat->cs_tfm_mutex); 703 mutex_unlock(&crypt_stat->cs_tfm_mutex);
648 if (rc) { 704 ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
649 ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", 705 ablkcipher_request_set_crypt(req, src_sg, dest_sg, size, iv);
650 rc); 706 rc = crypto_ablkcipher_decrypt(req);
651 goto out; 707 if (rc == -EINPROGRESS || rc == -EBUSY) {
708 struct extent_crypt_result *ecr = req->base.data;
709
710 wait_for_completion(&ecr->completion);
711 rc = ecr->rc;
712 INIT_COMPLETION(ecr->completion);
652 } 713 }
653 rc = size;
654out: 714out:
715 ablkcipher_request_free(req);
655 return rc; 716 return rc;
717
656} 718}
657 719
658/** 720/**
@@ -746,8 +808,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
746 crypt_stat->cipher, "cbc"); 808 crypt_stat->cipher, "cbc");
747 if (rc) 809 if (rc)
748 goto out_unlock; 810 goto out_unlock;
749 crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, 811 crypt_stat->tfm = crypto_alloc_ablkcipher(full_alg_name, 0, 0);
750 CRYPTO_ALG_ASYNC);
751 kfree(full_alg_name); 812 kfree(full_alg_name);
752 if (IS_ERR(crypt_stat->tfm)) { 813 if (IS_ERR(crypt_stat->tfm)) {
753 rc = PTR_ERR(crypt_stat->tfm); 814 rc = PTR_ERR(crypt_stat->tfm);
@@ -757,7 +818,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
757 crypt_stat->cipher); 818 crypt_stat->cipher);
758 goto out_unlock; 819 goto out_unlock;
759 } 820 }
760 crypto_blkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); 821 crypto_ablkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
761 rc = 0; 822 rc = 0;
762out_unlock: 823out_unlock:
763 mutex_unlock(&crypt_stat->cs_tfm_mutex); 824 mutex_unlock(&crypt_stat->cs_tfm_mutex);
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index dd299b389d4e..f622a733f7ad 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -38,6 +38,7 @@
38#include <linux/nsproxy.h> 38#include <linux/nsproxy.h>
39#include <linux/backing-dev.h> 39#include <linux/backing-dev.h>
40#include <linux/ecryptfs.h> 40#include <linux/ecryptfs.h>
41#include <linux/crypto.h>
41 42
42#define ECRYPTFS_DEFAULT_IV_BYTES 16 43#define ECRYPTFS_DEFAULT_IV_BYTES 16
43#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096 44#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
@@ -233,7 +234,7 @@ struct ecryptfs_crypt_stat {
233 size_t extent_shift; 234 size_t extent_shift;
234 unsigned int extent_mask; 235 unsigned int extent_mask;
235 struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 236 struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
236 struct crypto_blkcipher *tfm; 237 struct crypto_ablkcipher *tfm;
237 struct crypto_hash *hash_tfm; /* Crypto context for generating 238 struct crypto_hash *hash_tfm; /* Crypto context for generating
238 * the initialization vectors */ 239 * the initialization vectors */
239 unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; 240 unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];