eCryptfs: Combine encrypt_scatterlist() and decrypt_scatterlist()
authorTyler Hicks <tyhicks@canonical.com>
Sat, 6 Apr 2013 06:26:22 +0000 (23:26 -0700)
committerTyler Hicks <tyhicks@canonical.com>
Sat, 8 Jun 2013 00:28:26 +0000 (17:28 -0700)
These two functions are identical except for a debug printk and whether
they call crypto_ablkcipher_encrypt() or crypto_ablkcipher_decrypt(), so
they can be safely merged if the caller can indicate if encryption or
decryption should occur.

The debug printk is useless so it is removed.

Two new #define's are created to indicate if an ENCRYPT or DECRYPT
operation is desired.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
fs/ecryptfs/crypto.c

index 35b409b..fb54a01 100644 (file)
@@ -37,6 +37,9 @@
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
+#define DECRYPT                0
+#define ENCRYPT                1
+
 static int
 ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
                             struct page *dst_page, struct page *src_page,
@@ -334,19 +337,20 @@ static void extent_crypt_complete(struct crypto_async_request *req, int rc)
 }
 
 /**
- * encrypt_scatterlist
+ * crypt_scatterlist
  * @crypt_stat: Pointer to the crypt_stat struct to initialize.
- * @dest_sg: Destination of encrypted data
- * @src_sg: Data to be encrypted
- * @size: Length of data to be encrypted
- * @iv: iv to use during encryption
+ * @dest_sg: Destination of the data after performing the crypto operation
+ * @src_sg: Data to be encrypted or decrypted
+ * @size: Length of data
+ * @iv: IV to use
+ * @op: ENCRYPT or DECRYPT to indicate the desired operation
  *
- * Returns the number of bytes encrypted; negative value on error
+ * Returns the number of bytes encrypted or decrypted; negative value on error
  */
-static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
-                              struct scatterlist *dest_sg,
-                              struct scatterlist *src_sg, int size,
-                              unsigned char *iv)
+static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
+                            struct scatterlist *dest_sg,
+                            struct scatterlist *src_sg, int size,
+                            unsigned char *iv, int op)
 {
        struct ablkcipher_request *req = NULL;
        struct extent_crypt_result ecr;
@@ -389,9 +393,9 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
                crypt_stat->flags |= ECRYPTFS_KEY_SET;
        }
        mutex_unlock(&crypt_stat->cs_tfm_mutex);
-       ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
        ablkcipher_request_set_crypt(req, src_sg, dest_sg, size, iv);
-       rc = crypto_ablkcipher_encrypt(req);
+       rc = op == ENCRYPT ? crypto_ablkcipher_encrypt(req) :
+                            crypto_ablkcipher_decrypt(req);
        if (rc == -EINPROGRESS || rc == -EBUSY) {
                struct extent_crypt_result *ecr = req->base.data;
 
@@ -623,78 +627,6 @@ out:
        return rc;
 }
 
-/**
- * decrypt_scatterlist
- * @crypt_stat: Cryptographic context
- * @dest_sg: The destination scatterlist to decrypt into
- * @src_sg: The source scatterlist to decrypt from
- * @size: The number of bytes to decrypt
- * @iv: The initialization vector to use for the decryption
- *
- * Returns the number of bytes decrypted; negative value on error
- */
-static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
-                              struct scatterlist *dest_sg,
-                              struct scatterlist *src_sg, int size,
-                              unsigned char *iv)
-{
-       struct ablkcipher_request *req = NULL;
-       struct extent_crypt_result ecr;
-       int rc = 0;
-
-       BUG_ON(!crypt_stat || !crypt_stat->tfm
-              || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
-       if (unlikely(ecryptfs_verbosity > 0)) {
-               ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",
-                               crypt_stat->key_size);
-               ecryptfs_dump_hex(crypt_stat->key,
-                                 crypt_stat->key_size);
-       }
-
-       init_completion(&ecr.completion);
-
-       mutex_lock(&crypt_stat->cs_tfm_mutex);
-       req = ablkcipher_request_alloc(crypt_stat->tfm, GFP_NOFS);
-       if (!req) {
-               mutex_unlock(&crypt_stat->cs_tfm_mutex);
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       ablkcipher_request_set_callback(req,
-                       CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-                       extent_crypt_complete, &ecr);
-       /* Consider doing this once, when the file is opened */
-       if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
-               rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
-                                             crypt_stat->key_size);
-               if (rc) {
-                       ecryptfs_printk(KERN_ERR,
-                                       "Error setting key; rc = [%d]\n",
-                                       rc);
-                       mutex_unlock(&crypt_stat->cs_tfm_mutex);
-                       rc = -EINVAL;
-                       goto out;
-               }
-               crypt_stat->flags |= ECRYPTFS_KEY_SET;
-       }
-       mutex_unlock(&crypt_stat->cs_tfm_mutex);
-       ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
-       ablkcipher_request_set_crypt(req, src_sg, dest_sg, size, iv);
-       rc = crypto_ablkcipher_decrypt(req);
-       if (rc == -EINPROGRESS || rc == -EBUSY) {
-               struct extent_crypt_result *ecr = req->base.data;
-
-               wait_for_completion(&ecr->completion);
-               rc = ecr->rc;
-               INIT_COMPLETION(ecr->completion);
-       }
-out:
-       ablkcipher_request_free(req);
-       return rc;
-
-}
-
 /**
  * ecryptfs_encrypt_page_offset
  * @crypt_stat: The cryptographic context
@@ -718,7 +650,8 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 
        sg_set_page(&src_sg, src_page, size, offset);
        sg_set_page(&dst_sg, dst_page, size, offset);
-       return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
+       return crypt_scatterlist(crypt_stat, &dst_sg, &src_sg,
+                                size, iv, ENCRYPT);
 }
 
 /**
@@ -745,7 +678,8 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
        sg_init_table(&dst_sg, 1);
        sg_set_page(&dst_sg, dst_page, size, offset);
 
-       return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
+       return crypt_scatterlist(crypt_stat, &dst_sg, &src_sg,
+                                size, iv, DECRYPT);
 }
 
 #define ECRYPTFS_MAX_SCATTERLIST_LEN 4