[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>
This commit is contained in:
parent
565d9724b8
commit
8bba066f4e
4 changed files with 146 additions and 58 deletions
|
@ -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)
|
||||||
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(
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
/* 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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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,
|
||||||
* 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,
|
||||||
"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 {
|
||||||
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 {
|
||||||
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);
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
(*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)
|
||||||
"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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue