[PATCH] eCryptfs: Clean up crypto initialization
Michael Halcrow [Tue, 31 Oct 2006 06:07:16 +0000 (22:07 -0800)]
Clean up the crypto initialization code; let the crypto API take care of the
key size checks.

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>

fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c

index ed35a97..82e7d02 100644 (file)
@@ -1573,35 +1573,26 @@ out:
 
 /**
  * ecryptfs_process_cipher - Perform cipher initialization.
- * @tfm: Crypto context set by this function
  * @key_tfm: Crypto context for key material, set by this function
- * @cipher_name: Name of the cipher.
- * @key_size: Size of the key in bytes.
+ * @cipher_name: Name of the cipher
+ * @key_size: Size of the key in bytes
  *
  * Returns zero on success. Any crypto_tfm structs allocated here
  * should be released by other functions, such as on a superblock put
  * event, regardless of whether this function succeeds for fails.
  */
 int
-ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
-                       char *cipher_name, size_t key_size)
+ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name,
+                       size_t *key_size)
 {
        char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
        int rc;
 
-       *tfm = *key_tfm = NULL;
-       if (key_size > ECRYPTFS_MAX_KEY_BYTES) {
+       *key_tfm = NULL;
+       if (*key_size > ECRYPTFS_MAX_KEY_BYTES) {
                rc = -EINVAL;
                printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum "
-                      "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES);
-               goto out;
-       }
-       *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE
-                                             | CRYPTO_TFM_REQ_WEAK_KEY));
-       if (!(*tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Unable to allocate crypto cipher with name "
-                      "[%s]\n", cipher_name);
+                     "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES);
                goto out;
        }
        *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
@@ -1611,46 +1602,13 @@ ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
                       "[%s]\n", cipher_name);
                goto out;
        }
-       if (key_size < crypto_tfm_alg_min_keysize(*tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*tfm));
-               goto out;
-       }
-       if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
-               goto out;
-       }
-       if (key_size > crypto_tfm_alg_max_keysize(*tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*tfm));
-               goto out;
-       }
-       if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
-               goto out;
-       }
-       get_random_bytes(dummy_key, key_size);
-       rc = crypto_cipher_setkey(*tfm, dummy_key, key_size);
-       if (rc) {
-               printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
-                      "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
-               rc = -EINVAL;
-               goto out;
-       }
-       rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size);
+       if (*key_size == 0)
+               *key_size = crypto_tfm_alg_max_keysize(*key_tfm);
+       get_random_bytes(dummy_key, *key_size);
+       rc = crypto_cipher_setkey(*key_tfm, dummy_key, *key_size);
        if (rc) {
                printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
-                      "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+                      "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc);
                rc = -EINVAL;
                goto out;
        }
index 872c995..4112df9 100644 (file)
@@ -473,8 +473,8 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
                          unsigned char *src, struct dentry *ecryptfs_dentry);
 int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
 int
-ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
-                       char *cipher_name, size_t key_size);
+ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name,
+                       size_t *key_size);
 int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
 int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
 void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
index ba45478..bc706d3 100644 (file)
@@ -493,19 +493,16 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
                        goto out;
                }
        }
-       if (password_s_ptr->session_key_encryption_key_bytes
-           < crypto_tfm_alg_min_keysize(tfm)) {
-               printk(KERN_WARNING "Session key encryption key is [%d] bytes; "
-                      "minimum keysize for selected cipher is [%d] bytes.\n",
-                      password_s_ptr->session_key_encryption_key_bytes,
-                      crypto_tfm_alg_min_keysize(tfm));
-               rc = -EINVAL;
-               goto out;
-       }
        if (tfm_mutex)
                mutex_lock(tfm_mutex);
-       crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
-                            crypt_stat->key_size);
+       rc = crypto_cipher_setkey(tfm,
+                                 password_s_ptr->session_key_encryption_key,
+                                 crypt_stat->key_size);
+       if (rc < 0) {
+               printk(KERN_ERR "Error setting key for crypto context\n");
+               rc = -EINVAL;
+               goto out_free_tfm;
+       }
        /* TODO: virt_to_scatterlist */
        encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
        if (!encrypted_session_key) {
index 5938a23..a65f486 100644 (file)
@@ -208,7 +208,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
        char *cipher_name_dst;
        char *cipher_name_src;
        char *cipher_key_bytes_src;
-       struct crypto_tfm *tmp_tfm;
        int cipher_name_len;
 
        if (!options) {
@@ -305,20 +304,12 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
                    = '\0';
        }
        if (!cipher_key_bytes_set) {
-               mount_crypt_stat->global_default_cipher_key_size =
-                       ECRYPTFS_DEFAULT_KEY_BYTES;
-               ecryptfs_printk(KERN_DEBUG, "Cipher key size was not "
-                               "specified.  Defaulting to [%d]\n",
-                               mount_crypt_stat->
-                               global_default_cipher_key_size);
+               mount_crypt_stat->global_default_cipher_key_size = 0;
        }
        rc = ecryptfs_process_cipher(
-               &tmp_tfm,
                &mount_crypt_stat->global_key_tfm,
                mount_crypt_stat->global_default_cipher_name,
-               mount_crypt_stat->global_default_cipher_key_size);
-       if (tmp_tfm)
-               crypto_free_tfm(tmp_tfm);
+               &mount_crypt_stat->global_default_cipher_key_size);
        if (rc) {
                printk(KERN_ERR "Error attempting to initialize cipher [%s] "
                       "with key size [%Zd] bytes; rc = [%d]\n",