diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2006-10-31 01:07:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-31 11:07:01 -0500 |
commit | 8bba066f4e3854755a303cee37ea37bd080a46b3 (patch) | |
tree | 3f8cf2df5da6459b0218b97b3799ceb896d4ba8a /fs/ecryptfs/crypto.c | |
parent | 565d9724b8ce49b530287de34aa17f45f21624d5 (diff) |
[PATCH] eCryptfs: Cipher code to new crypto API
Update cipher block encryption code to the new crypto API.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ecryptfs/crypto.c')
-rw-r--r-- | fs/ecryptfs/crypto.c | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f14c5a38215e..2a1b6aa1a4a1 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -123,6 +123,28 @@ out: | |||
123 | return rc; | 123 | return rc; |
124 | } | 124 | } |
125 | 125 | ||
126 | int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, | ||
127 | char *cipher_name, | ||
128 | char *chaining_modifier) | ||
129 | { | ||
130 | int cipher_name_len = strlen(cipher_name); | ||
131 | int chaining_modifier_len = strlen(chaining_modifier); | ||
132 | int algified_name_len; | ||
133 | int rc; | ||
134 | |||
135 | algified_name_len = (chaining_modifier_len + cipher_name_len + 3); | ||
136 | (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL); | ||
137 | if (!(algified_name)) { | ||
138 | rc = -ENOMEM; | ||
139 | goto out; | ||
140 | } | ||
141 | snprintf((*algified_name), algified_name_len, "%s(%s)", | ||
142 | chaining_modifier, cipher_name); | ||
143 | rc = 0; | ||
144 | out: | ||
145 | return rc; | ||
146 | } | ||
147 | |||
126 | /** | 148 | /** |
127 | * ecryptfs_derive_iv | 149 | * ecryptfs_derive_iv |
128 | * @iv: destination for the derived iv vale | 150 | * @iv: destination for the derived iv vale |
@@ -197,7 +219,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | |||
197 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | 219 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) |
198 | { | 220 | { |
199 | if (crypt_stat->tfm) | 221 | if (crypt_stat->tfm) |
200 | crypto_free_tfm(crypt_stat->tfm); | 222 | crypto_free_blkcipher(crypt_stat->tfm); |
201 | if (crypt_stat->hash_tfm) | 223 | if (crypt_stat->hash_tfm) |
202 | crypto_free_hash(crypt_stat->hash_tfm); | 224 | crypto_free_hash(crypt_stat->hash_tfm); |
203 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | 225 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); |
@@ -209,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat( | |||
209 | if (mount_crypt_stat->global_auth_tok_key) | 231 | if (mount_crypt_stat->global_auth_tok_key) |
210 | key_put(mount_crypt_stat->global_auth_tok_key); | 232 | key_put(mount_crypt_stat->global_auth_tok_key); |
211 | if (mount_crypt_stat->global_key_tfm) | 233 | if (mount_crypt_stat->global_key_tfm) |
212 | crypto_free_tfm(mount_crypt_stat->global_key_tfm); | 234 | crypto_free_blkcipher(mount_crypt_stat->global_key_tfm); |
213 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); | 235 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); |
214 | } | 236 | } |
215 | 237 | ||
@@ -275,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
275 | struct scatterlist *src_sg, int size, | 297 | struct scatterlist *src_sg, int size, |
276 | unsigned char *iv) | 298 | unsigned char *iv) |
277 | { | 299 | { |
300 | struct blkcipher_desc desc = { | ||
301 | .tfm = crypt_stat->tfm, | ||
302 | .info = iv, | ||
303 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
304 | }; | ||
278 | int rc = 0; | 305 | int rc = 0; |
279 | 306 | ||
280 | BUG_ON(!crypt_stat || !crypt_stat->tfm | 307 | BUG_ON(!crypt_stat || !crypt_stat->tfm |
@@ -288,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
288 | } | 315 | } |
289 | /* Consider doing this once, when the file is opened */ | 316 | /* Consider doing this once, when the file is opened */ |
290 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 317 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
291 | rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, | 318 | rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, |
292 | crypt_stat->key_size); | 319 | crypt_stat->key_size); |
293 | if (rc) { | 320 | if (rc) { |
294 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | 321 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", |
295 | rc); | 322 | rc); |
@@ -298,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
298 | goto out; | 325 | goto out; |
299 | } | 326 | } |
300 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); | 327 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); |
301 | crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv); | 328 | crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size); |
302 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 329 | mutex_unlock(&crypt_stat->cs_tfm_mutex); |
303 | out: | 330 | out: |
304 | return rc; | 331 | return rc; |
@@ -681,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
681 | struct scatterlist *src_sg, int size, | 708 | struct scatterlist *src_sg, int size, |
682 | unsigned char *iv) | 709 | unsigned char *iv) |
683 | { | 710 | { |
711 | struct blkcipher_desc desc = { | ||
712 | .tfm = crypt_stat->tfm, | ||
713 | .info = iv, | ||
714 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
715 | }; | ||
684 | int rc = 0; | 716 | int rc = 0; |
685 | 717 | ||
686 | /* Consider doing this once, when the file is opened */ | 718 | /* Consider doing this once, when the file is opened */ |
687 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 719 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
688 | rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, | 720 | rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, |
689 | crypt_stat->key_size); | 721 | crypt_stat->key_size); |
690 | if (rc) { | 722 | if (rc) { |
691 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | 723 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", |
692 | rc); | 724 | rc); |
@@ -695,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
695 | goto out; | 727 | goto out; |
696 | } | 728 | } |
697 | ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); | 729 | ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); |
698 | rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, | 730 | rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size); |
699 | iv); | ||
700 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 731 | mutex_unlock(&crypt_stat->cs_tfm_mutex); |
701 | if (rc) { | 732 | if (rc) { |
702 | ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", | 733 | ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", |
@@ -765,6 +796,7 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, | |||
765 | */ | 796 | */ |
766 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | 797 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) |
767 | { | 798 | { |
799 | char *full_alg_name; | ||
768 | int rc = -EINVAL; | 800 | int rc = -EINVAL; |
769 | 801 | ||
770 | if (!crypt_stat->cipher) { | 802 | if (!crypt_stat->cipher) { |
@@ -781,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | |||
781 | goto out; | 813 | goto out; |
782 | } | 814 | } |
783 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 815 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
784 | crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher, | 816 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, |
785 | ECRYPTFS_DEFAULT_CHAINING_MODE | 817 | crypt_stat->cipher, "cbc"); |
786 | | CRYPTO_TFM_REQ_WEAK_KEY); | 818 | if (rc) |
787 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 819 | goto out; |
820 | crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
821 | CRYPTO_ALG_ASYNC); | ||
822 | kfree(full_alg_name); | ||
788 | if (!crypt_stat->tfm) { | 823 | if (!crypt_stat->tfm) { |
789 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " | 824 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " |
790 | "Error initializing cipher [%s]\n", | 825 | "Error initializing cipher [%s]\n", |
791 | crypt_stat->cipher); | 826 | crypt_stat->cipher); |
827 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
792 | goto out; | 828 | goto out; |
793 | } | 829 | } |
830 | crypto_blkcipher_set_flags(crypt_stat->tfm, | ||
831 | (ECRYPTFS_DEFAULT_CHAINING_MODE | ||
832 | | CRYPTO_TFM_REQ_WEAK_KEY)); | ||
833 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
794 | rc = 0; | 834 | rc = 0; |
795 | out: | 835 | out: |
796 | return rc; | 836 | return rc; |
@@ -1588,10 +1628,11 @@ out: | |||
1588 | * event, regardless of whether this function succeeds for fails. | 1628 | * event, regardless of whether this function succeeds for fails. |
1589 | */ | 1629 | */ |
1590 | int | 1630 | int |
1591 | ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name, | 1631 | ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, |
1592 | size_t *key_size) | 1632 | size_t *key_size) |
1593 | { | 1633 | { |
1594 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; | 1634 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; |
1635 | char *full_alg_name; | ||
1595 | int rc; | 1636 | int rc; |
1596 | 1637 | ||
1597 | *key_tfm = NULL; | 1638 | *key_tfm = NULL; |
@@ -1601,17 +1642,26 @@ ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name, | |||
1601 | "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); | 1642 | "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); |
1602 | goto out; | 1643 | goto out; |
1603 | } | 1644 | } |
1604 | *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY); | 1645 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name, |
1605 | if (!(*key_tfm)) { | 1646 | "ecb"); |
1606 | rc = -EINVAL; | 1647 | if (rc) |
1648 | goto out; | ||
1649 | *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); | ||
1650 | kfree(full_alg_name); | ||
1651 | if (IS_ERR(*key_tfm)) { | ||
1652 | rc = PTR_ERR(*key_tfm); | ||
1607 | printk(KERN_ERR "Unable to allocate crypto cipher with name " | 1653 | printk(KERN_ERR "Unable to allocate crypto cipher with name " |
1608 | "[%s]\n", cipher_name); | 1654 | "[%s]; rc = [%d]\n", cipher_name, rc); |
1609 | goto out; | 1655 | goto out; |
1610 | } | 1656 | } |
1611 | if (*key_size == 0) | 1657 | crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
1612 | *key_size = crypto_tfm_alg_max_keysize(*key_tfm); | 1658 | if (*key_size == 0) { |
1659 | struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm); | ||
1660 | |||
1661 | *key_size = alg->max_keysize; | ||
1662 | } | ||
1613 | get_random_bytes(dummy_key, *key_size); | 1663 | get_random_bytes(dummy_key, *key_size); |
1614 | rc = crypto_cipher_setkey(*key_tfm, dummy_key, *key_size); | 1664 | rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); |
1615 | if (rc) { | 1665 | if (rc) { |
1616 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " | 1666 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " |
1617 | "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); | 1667 | "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); |