Commit 8bba066f authored by Michael Halcrow's avatar Michael Halcrow Committed by Linus Torvalds

[PATCH] eCryptfs: Cipher code to new crypto API

Update cipher block encryption code to the new crypto API.
Signed-off-by: default avatarMichael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 565d9724
...@@ -123,6 +123,28 @@ static int ecryptfs_calculate_md5(char *dst, ...@@ -123,6 +123,28 @@ static int ecryptfs_calculate_md5(char *dst,
return rc; 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 * ecryptfs_derive_iv
* @iv: destination for the derived iv vale * @iv: destination for the derived iv vale
...@@ -197,7 +219,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) ...@@ -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) void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
{ {
if (crypt_stat->tfm) if (crypt_stat->tfm)
crypto_free_tfm(crypt_stat->tfm); crypto_free_blkcipher(crypt_stat->tfm);
if (crypt_stat->hash_tfm) if (crypt_stat->hash_tfm)
crypto_free_hash(crypt_stat->hash_tfm); crypto_free_hash(crypt_stat->hash_tfm);
memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
...@@ -209,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat( ...@@ -209,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat(
if (mount_crypt_stat->global_auth_tok_key) if (mount_crypt_stat->global_auth_tok_key)
key_put(mount_crypt_stat->global_auth_tok_key); key_put(mount_crypt_stat->global_auth_tok_key);
if (mount_crypt_stat->global_key_tfm) 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)); memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
} }
...@@ -275,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -275,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *src_sg, int size, struct scatterlist *src_sg, int size,
unsigned char *iv) unsigned char *iv)
{ {
struct blkcipher_desc desc = {
.tfm = crypt_stat->tfm,
.info = iv,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0; int rc = 0;
BUG_ON(!crypt_stat || !crypt_stat->tfm BUG_ON(!crypt_stat || !crypt_stat->tfm
...@@ -288,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -288,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
} }
/* Consider doing this once, when the file is opened */ /* Consider doing this once, when the file is opened */
mutex_lock(&crypt_stat->cs_tfm_mutex); mutex_lock(&crypt_stat->cs_tfm_mutex);
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size); crypt_stat->key_size);
if (rc) { if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc); rc);
...@@ -298,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -298,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
goto out; goto out;
} }
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); 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); mutex_unlock(&crypt_stat->cs_tfm_mutex);
out: out:
return rc; return rc;
...@@ -681,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -681,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *src_sg, int size, struct scatterlist *src_sg, int size,
unsigned char *iv) unsigned char *iv)
{ {
struct blkcipher_desc desc = {
.tfm = crypt_stat->tfm,
.info = iv,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0; int rc = 0;
/* Consider doing this once, when the file is opened */ /* Consider doing this once, when the file is opened */
mutex_lock(&crypt_stat->cs_tfm_mutex); mutex_lock(&crypt_stat->cs_tfm_mutex);
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size); crypt_stat->key_size);
if (rc) { if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc); rc);
...@@ -695,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -695,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
goto out; goto out;
} }
ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size);
iv);
mutex_unlock(&crypt_stat->cs_tfm_mutex); mutex_unlock(&crypt_stat->cs_tfm_mutex);
if (rc) { if (rc) {
ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
...@@ -765,6 +796,7 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -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) int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
{ {
char *full_alg_name;
int rc = -EINVAL; int rc = -EINVAL;
if (!crypt_stat->cipher) { if (!crypt_stat->cipher) {
...@@ -781,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) ...@@ -781,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
goto out; goto out;
} }
mutex_lock(&crypt_stat->cs_tfm_mutex); mutex_lock(&crypt_stat->cs_tfm_mutex);
crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher, rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
ECRYPTFS_DEFAULT_CHAINING_MODE crypt_stat->cipher, "cbc");
| CRYPTO_TFM_REQ_WEAK_KEY); if (rc)
mutex_unlock(&crypt_stat->cs_tfm_mutex); goto out;
crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0,
CRYPTO_ALG_ASYNC);
kfree(full_alg_name);
if (!crypt_stat->tfm) { if (!crypt_stat->tfm) {
ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
"Error initializing cipher [%s]\n", "Error initializing cipher [%s]\n",
crypt_stat->cipher); crypt_stat->cipher);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
goto out; 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; rc = 0;
out: out:
return rc; return rc;
...@@ -1588,10 +1628,11 @@ ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -1588,10 +1628,11 @@ ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat,
* event, regardless of whether this function succeeds for fails. * event, regardless of whether this function succeeds for fails.
*/ */
int 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) size_t *key_size)
{ {
char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
char *full_alg_name;
int rc; int rc;
*key_tfm = NULL; *key_tfm = NULL;
...@@ -1601,17 +1642,26 @@ ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name, ...@@ -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); "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES);
goto out; goto out;
} }
*key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY); rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name,
if (!(*key_tfm)) { "ecb");
rc = -EINVAL; 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 " printk(KERN_ERR "Unable to allocate crypto cipher with name "
"[%s]\n", cipher_name); "[%s]; rc = [%d]\n", cipher_name, rc);
goto out; goto out;
} }
if (*key_size == 0) crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
*key_size = crypto_tfm_alg_max_keysize(*key_tfm); 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); 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) { if (rc) {
printk(KERN_ERR "Error attempting to set key of size [%Zd] for " 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);
......
...@@ -205,7 +205,7 @@ struct ecryptfs_crypt_stat { ...@@ -205,7 +205,7 @@ struct ecryptfs_crypt_stat {
size_t extent_shift; size_t extent_shift;
unsigned int extent_mask; unsigned int extent_mask;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 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 struct crypto_hash *hash_tfm; /* Crypto context for generating
* the initialization vectors */ * the initialization vectors */
unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
...@@ -245,7 +245,7 @@ struct ecryptfs_mount_crypt_stat { ...@@ -245,7 +245,7 @@ struct ecryptfs_mount_crypt_stat {
struct ecryptfs_auth_tok *global_auth_tok; struct ecryptfs_auth_tok *global_auth_tok;
struct key *global_auth_tok_key; struct key *global_auth_tok_key;
size_t global_default_cipher_key_size; 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; struct mutex global_key_tfm_mutex;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+ 1]; + 1];
...@@ -426,6 +426,9 @@ void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); ...@@ -426,6 +426,9 @@ void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
void ecryptfs_destruct_mount_crypt_stat( void ecryptfs_destruct_mount_crypt_stat(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat); struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *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, int ecryptfs_write_inode_size_to_header(struct file *lower_file,
struct inode *lower_inode, struct inode *lower_inode,
struct inode *inode); struct inode *inode);
...@@ -474,7 +477,7 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -474,7 +477,7 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
unsigned char *src, struct dentry *ecryptfs_dentry); unsigned char *src, struct dentry *ecryptfs_dentry);
int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
int 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); size_t *key_size);
int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
int ecryptfs_inode_set(struct inode *inode, void *lower_inode); int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
......
...@@ -458,14 +458,16 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, ...@@ -458,14 +458,16 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_crypt_stat *crypt_stat) struct ecryptfs_crypt_stat *crypt_stat)
{ {
int rc = 0;
struct ecryptfs_password *password_s_ptr; struct ecryptfs_password *password_s_ptr;
struct crypto_tfm *tfm = NULL;
struct scatterlist src_sg[2], dst_sg[2]; struct scatterlist src_sg[2], dst_sg[2];
struct mutex *tfm_mutex = NULL; struct mutex *tfm_mutex = NULL;
/* TODO: Use virt_to_scatterlist for these */ /* TODO: Use virt_to_scatterlist for these */
char *encrypted_session_key; char *encrypted_session_key;
char *session_key; char *session_key;
struct blkcipher_desc desc = {
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0;
password_s_ptr = &auth_tok->token.password; password_s_ptr = &auth_tok->token.password;
if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags,
...@@ -482,22 +484,32 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -482,22 +484,32 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
if (!strcmp(crypt_stat->cipher, if (!strcmp(crypt_stat->cipher,
crypt_stat->mount_crypt_stat->global_default_cipher_name) crypt_stat->mount_crypt_stat->global_default_cipher_name)
&& crypt_stat->mount_crypt_stat->global_key_tfm) { && crypt_stat->mount_crypt_stat->global_key_tfm) {
tfm = crypt_stat->mount_crypt_stat->global_key_tfm; desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
} else { } else {
tfm = crypto_alloc_tfm(crypt_stat->cipher, char *full_alg_name;
CRYPTO_TFM_REQ_WEAK_KEY);
if (!tfm) { rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
printk(KERN_ERR "Error allocating crypto context\n"); crypt_stat->cipher,
rc = -ENOMEM; "ecb");
if (rc)
goto out;
desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
CRYPTO_ALG_ASYNC);
kfree(full_alg_name);
if (IS_ERR(desc.tfm)) {
rc = PTR_ERR(desc.tfm);
printk(KERN_ERR "Error allocating crypto context; "
"rc = [%d]\n", rc);
goto out; goto out;
} }
crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
} }
if (tfm_mutex) if (tfm_mutex)
mutex_lock(tfm_mutex); mutex_lock(tfm_mutex);
rc = crypto_cipher_setkey(tfm, rc = crypto_blkcipher_setkey(desc.tfm,
password_s_ptr->session_key_encryption_key, password_s_ptr->session_key_encryption_key,
crypt_stat->key_size); crypt_stat->key_size);
if (rc < 0) { if (rc < 0) {
printk(KERN_ERR "Error setting key for crypto context\n"); printk(KERN_ERR "Error setting key for crypto context\n");
rc = -EINVAL; rc = -EINVAL;
...@@ -528,9 +540,12 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -528,9 +540,12 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
auth_tok->session_key.decrypted_key_size = auth_tok->session_key.decrypted_key_size =
auth_tok->session_key.encrypted_key_size; auth_tok->session_key.encrypted_key_size;
dst_sg[0].length = auth_tok->session_key.encrypted_key_size; dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
/* TODO: Handle error condition */ rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
crypto_cipher_decrypt(tfm, dst_sg, src_sg, auth_tok->session_key.encrypted_key_size);
auth_tok->session_key.encrypted_key_size); if (rc) {
printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc);
goto out_free_memory;
}
auth_tok->session_key.decrypted_key_size = auth_tok->session_key.decrypted_key_size =
auth_tok->session_key.encrypted_key_size; auth_tok->session_key.encrypted_key_size;
memcpy(auth_tok->session_key.decrypted_key, session_key, memcpy(auth_tok->session_key.decrypted_key, session_key,
...@@ -543,6 +558,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -543,6 +558,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
if (ecryptfs_verbosity > 0) if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex(crypt_stat->key, ecryptfs_dump_hex(crypt_stat->key,
crypt_stat->key_size); crypt_stat->key_size);
out_free_memory:
memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
free_page((unsigned long)encrypted_session_key); free_page((unsigned long)encrypted_session_key);
memset(session_key, 0, PAGE_CACHE_SIZE); memset(session_key, 0, PAGE_CACHE_SIZE);
...@@ -551,7 +567,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -551,7 +567,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
if (tfm_mutex) if (tfm_mutex)
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
else else
crypto_free_tfm(tfm); crypto_free_blkcipher(desc.tfm);
out: out:
return rc; return rc;
} }
...@@ -800,19 +816,21 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, ...@@ -800,19 +816,21 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_crypt_stat *crypt_stat, struct ecryptfs_crypt_stat *crypt_stat,
struct ecryptfs_key_record *key_rec, size_t *packet_size) struct ecryptfs_key_record *key_rec, size_t *packet_size)
{ {
int rc = 0;
size_t i; size_t i;
size_t signature_is_valid = 0; size_t signature_is_valid = 0;
size_t encrypted_session_key_valid = 0; size_t encrypted_session_key_valid = 0;
char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
struct scatterlist dest_sg[2]; struct scatterlist dest_sg[2];
struct scatterlist src_sg[2]; struct scatterlist src_sg[2];
struct crypto_tfm *tfm = NULL;
struct mutex *tfm_mutex = NULL; struct mutex *tfm_mutex = NULL;
size_t key_rec_size; size_t key_rec_size;
size_t packet_size_length; size_t packet_size_length;
size_t cipher_code; size_t cipher_code;
struct blkcipher_desc desc = {
.tfm = NULL,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0;
(*packet_size) = 0; (*packet_size) = 0;
/* Check for a valid signature on the auth_tok */ /* Check for a valid signature on the auth_tok */
...@@ -879,33 +897,48 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, ...@@ -879,33 +897,48 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
if (!strcmp(crypt_stat->cipher, if (!strcmp(crypt_stat->cipher,
crypt_stat->mount_crypt_stat->global_default_cipher_name) crypt_stat->mount_crypt_stat->global_default_cipher_name)
&& crypt_stat->mount_crypt_stat->global_key_tfm) { && crypt_stat->mount_crypt_stat->global_key_tfm) {
tfm = crypt_stat->mount_crypt_stat->global_key_tfm; desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
} else } else {
tfm = crypto_alloc_tfm(crypt_stat->cipher, 0); char *full_alg_name;
if (!tfm) {
ecryptfs_printk(KERN_ERR, "Could not initialize crypto " rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
"context for cipher [%s]\n", crypt_stat->cipher,
crypt_stat->cipher); "ecb");
rc = -EINVAL; if (rc)
goto out; goto out;
desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
CRYPTO_ALG_ASYNC);
kfree(full_alg_name);
if (IS_ERR(desc.tfm)) {
rc = PTR_ERR(desc.tfm);
ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
"context for cipher [%s]; rc = [%d]\n",
crypt_stat->cipher, rc);
goto out;
}
crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
} }
if (tfm_mutex) if (tfm_mutex)
mutex_lock(tfm_mutex); mutex_lock(tfm_mutex);
rc = crypto_cipher_setkey(tfm, session_key_encryption_key, rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,
crypt_stat->key_size); crypt_stat->key_size);
if (rc < 0) { if (rc < 0) {
if (tfm_mutex) if (tfm_mutex)
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_ERR, "Error setting key for crypto " ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
"context\n"); "context; rc = [%d]\n", rc);
goto out; goto out;
} }
rc = 0; rc = 0;
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
crypt_stat->key_size); crypt_stat->key_size);
crypto_cipher_encrypt(tfm, dest_sg, src_sg, rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg,
(*key_rec).enc_key_size); (*key_rec).enc_key_size);
if (rc) {
printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);
goto out;
}
if (tfm_mutex) if (tfm_mutex)
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
...@@ -968,8 +1001,8 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, ...@@ -968,8 +1001,8 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
(*key_rec).enc_key_size); (*key_rec).enc_key_size);
(*packet_size) += (*key_rec).enc_key_size; (*packet_size) += (*key_rec).enc_key_size;
out: out:
if (tfm && !tfm_mutex) if (desc.tfm && !tfm_mutex)
crypto_free_tfm(tfm); crypto_free_blkcipher(desc.tfm);
if (rc) if (rc)
(*packet_size) = 0; (*packet_size) = 0;
return rc; return rc;
......
...@@ -315,6 +315,8 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) ...@@ -315,6 +315,8 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
"with key size [%Zd] bytes; rc = [%d]\n", "with key size [%Zd] bytes; rc = [%d]\n",
mount_crypt_stat->global_default_cipher_name, mount_crypt_stat->global_default_cipher_name,
mount_crypt_stat->global_default_cipher_key_size, rc); mount_crypt_stat->global_default_cipher_key_size, rc);
mount_crypt_stat->global_key_tfm = NULL;
mount_crypt_stat->global_auth_tok_key = NULL;
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment