diff options
| -rw-r--r-- | fs/ecryptfs/crypto.c | 141 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 3 |
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 | ||
| 322 | struct extent_crypt_result { | ||
| 323 | struct completion completion; | ||
| 324 | int rc; | ||
| 325 | }; | ||
| 326 | |||
| 327 | static 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 | } | ||
| 369 | out: | 404 | out: |
| 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; | ||
| 654 | out: | 714 | out: |
| 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; |
| 762 | out_unlock: | 823 | out_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]; |
