Skip to content

Commit

Permalink
[PATCH] eCryptfs: Cipher code to new crypto API
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Halcrow authored and Linus Torvalds committed Oct 31, 2006
1 parent 565d972 commit 8bba066
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 58 deletions.
92 changes: 71 additions & 21 deletions fs/ecryptfs/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,28 @@ static int ecryptfs_calculate_md5(char *dst,
return rc;
}

int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
char *cipher_name,
char *chaining_modifier)
{
int cipher_name_len = strlen(cipher_name);
int chaining_modifier_len = strlen(chaining_modifier);
int algified_name_len;
int rc;

algified_name_len = (chaining_modifier_len + cipher_name_len + 3);
(*algified_name) = kmalloc(algified_name_len, GFP_KERNEL);
if (!(algified_name)) {
rc = -ENOMEM;
goto out;
}
snprintf((*algified_name), algified_name_len, "%s(%s)",
chaining_modifier, cipher_name);
rc = 0;
out:
return rc;
}

/**
* ecryptfs_derive_iv
* @iv: destination for the derived iv vale
Expand Down Expand Up @@ -197,7 +219,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
{
if (crypt_stat->tfm)
crypto_free_tfm(crypt_stat->tfm);
crypto_free_blkcipher(crypt_stat->tfm);
if (crypt_stat->hash_tfm)
crypto_free_hash(crypt_stat->hash_tfm);
memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
Expand All @@ -209,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat(
if (mount_crypt_stat->global_auth_tok_key)
key_put(mount_crypt_stat->global_auth_tok_key);
if (mount_crypt_stat->global_key_tfm)
crypto_free_tfm(mount_crypt_stat->global_key_tfm);
crypto_free_blkcipher(mount_crypt_stat->global_key_tfm);
memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
}

Expand Down Expand Up @@ -275,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *src_sg, int size,
unsigned char *iv)
{
struct blkcipher_desc desc = {
.tfm = crypt_stat->tfm,
.info = iv,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0;

BUG_ON(!crypt_stat || !crypt_stat->tfm
Expand All @@ -288,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
}
/* Consider doing this once, when the file is opened */
mutex_lock(&crypt_stat->cs_tfm_mutex);
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc);
Expand All @@ -298,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
goto out;
}
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
out:
return rc;
Expand Down Expand Up @@ -681,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *src_sg, int size,
unsigned char *iv)
{
struct blkcipher_desc desc = {
.tfm = crypt_stat->tfm,
.info = iv,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0;

/* Consider doing this once, when the file is opened */
mutex_lock(&crypt_stat->cs_tfm_mutex);
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc);
Expand All @@ -695,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
goto out;
}
ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
iv);
rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
Expand Down Expand Up @@ -765,6 +796,7 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
*/
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
{
char *full_alg_name;
int rc = -EINVAL;

if (!crypt_stat->cipher) {
Expand All @@ -781,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
goto out;
}
mutex_lock(&crypt_stat->cs_tfm_mutex);
crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
ECRYPTFS_DEFAULT_CHAINING_MODE
| CRYPTO_TFM_REQ_WEAK_KEY);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
crypt_stat->cipher, "cbc");
if (rc)
goto out;
crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0,
CRYPTO_ALG_ASYNC);
kfree(full_alg_name);
if (!crypt_stat->tfm) {
ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
"Error initializing cipher [%s]\n",
crypt_stat->cipher);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
goto out;
}
crypto_blkcipher_set_flags(crypt_stat->tfm,
(ECRYPTFS_DEFAULT_CHAINING_MODE
| CRYPTO_TFM_REQ_WEAK_KEY));
mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = 0;
out:
return rc;
Expand Down Expand Up @@ -1588,10 +1628,11 @@ ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat,
* event, regardless of whether this function succeeds for fails.
*/
int
ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name,
ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
size_t *key_size)
{
char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
char *full_alg_name;
int rc;

*key_tfm = NULL;
Expand All @@ -1601,17 +1642,26 @@ ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *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);
if (!(*key_tfm)) {
rc = -EINVAL;
rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name,
"ecb");
if (rc)
goto out;
*key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
kfree(full_alg_name);
if (IS_ERR(*key_tfm)) {
rc = PTR_ERR(*key_tfm);
printk(KERN_ERR "Unable to allocate crypto cipher with name "
"[%s]\n", cipher_name);
"[%s]; rc = [%d]\n", cipher_name, rc);
goto out;
}
if (*key_size == 0)
*key_size = crypto_tfm_alg_max_keysize(*key_tfm);
crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
if (*key_size == 0) {
struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm);

*key_size = alg->max_keysize;
}
get_random_bytes(dummy_key, *key_size);
rc = crypto_cipher_setkey(*key_tfm, dummy_key, *key_size);
rc = crypto_blkcipher_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);
Expand Down
9 changes: 6 additions & 3 deletions fs/ecryptfs/ecryptfs_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ struct ecryptfs_crypt_stat {
size_t extent_shift;
unsigned int extent_mask;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
struct crypto_tfm *tfm;
struct crypto_blkcipher *tfm;
struct crypto_hash *hash_tfm; /* Crypto context for generating
* the initialization vectors */
unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
Expand Down Expand Up @@ -245,7 +245,7 @@ struct ecryptfs_mount_crypt_stat {
struct ecryptfs_auth_tok *global_auth_tok;
struct key *global_auth_tok_key;
size_t global_default_cipher_key_size;
struct crypto_tfm *global_key_tfm;
struct crypto_blkcipher *global_key_tfm;
struct mutex global_key_tfm_mutex;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+ 1];
Expand Down Expand Up @@ -426,6 +426,9 @@ void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
void ecryptfs_destruct_mount_crypt_stat(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
char *cipher_name,
char *chaining_modifier);
int ecryptfs_write_inode_size_to_header(struct file *lower_file,
struct inode *lower_inode,
struct inode *inode);
Expand Down Expand Up @@ -474,7 +477,7 @@ 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 **key_tfm, char *cipher_name,
ecryptfs_process_cipher(struct crypto_blkcipher **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);
Expand Down
Loading

0 comments on commit 8bba066

Please sign in to comment.