Commit 3095e8e3 authored by Herbert Xu's avatar Herbert Xu

eCryptfs: Use skcipher and shash

This patch replaces uses of ablkcipher and blkcipher with skcipher,
and the long obsolete hash interface with shash.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent cf80e0e4
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
* 02111-1307, USA. * 02111-1307, USA.
*/ */
#include <crypto/hash.h>
#include <crypto/skcipher.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
...@@ -30,7 +32,6 @@ ...@@ -30,7 +32,6 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/key.h> #include <linux/key.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/crypto.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -74,6 +75,19 @@ void ecryptfs_from_hex(char *dst, char *src, int dst_size) ...@@ -74,6 +75,19 @@ void ecryptfs_from_hex(char *dst, char *src, int dst_size)
} }
} }
static int ecryptfs_hash_digest(struct crypto_shash *tfm,
char *src, int len, char *dst)
{
SHASH_DESC_ON_STACK(desc, tfm);
int err;
desc->tfm = tfm;
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
err = crypto_shash_digest(desc, src, len, dst);
shash_desc_zero(desc);
return err;
}
/** /**
* ecryptfs_calculate_md5 - calculates the md5 of @src * ecryptfs_calculate_md5 - calculates the md5 of @src
* @dst: Pointer to 16 bytes of allocated memory * @dst: Pointer to 16 bytes of allocated memory
...@@ -88,45 +102,26 @@ static int ecryptfs_calculate_md5(char *dst, ...@@ -88,45 +102,26 @@ static int ecryptfs_calculate_md5(char *dst,
struct ecryptfs_crypt_stat *crypt_stat, struct ecryptfs_crypt_stat *crypt_stat,
char *src, int len) char *src, int len)
{ {
struct scatterlist sg; struct crypto_shash *tfm;
struct hash_desc desc = {
.tfm = crypt_stat->hash_tfm,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0; int rc = 0;
mutex_lock(&crypt_stat->cs_hash_tfm_mutex); mutex_lock(&crypt_stat->cs_hash_tfm_mutex);
sg_init_one(&sg, (u8 *)src, len); tfm = crypt_stat->hash_tfm;
if (!desc.tfm) { if (!tfm) {
desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0, tfm = crypto_alloc_shash(ECRYPTFS_DEFAULT_HASH, 0, 0);
CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) {
if (IS_ERR(desc.tfm)) { rc = PTR_ERR(tfm);
rc = PTR_ERR(desc.tfm);
ecryptfs_printk(KERN_ERR, "Error attempting to " ecryptfs_printk(KERN_ERR, "Error attempting to "
"allocate crypto context; rc = [%d]\n", "allocate crypto context; rc = [%d]\n",
rc); rc);
goto out; goto out;
} }
crypt_stat->hash_tfm = desc.tfm; crypt_stat->hash_tfm = tfm;
}
rc = crypto_hash_init(&desc);
if (rc) {
printk(KERN_ERR
"%s: Error initializing crypto hash; rc = [%d]\n",
__func__, rc);
goto out;
} }
rc = crypto_hash_update(&desc, &sg, len); rc = ecryptfs_hash_digest(tfm, src, len, dst);
if (rc) { if (rc) {
printk(KERN_ERR printk(KERN_ERR
"%s: Error updating crypto hash; rc = [%d]\n", "%s: Error computing crypto hash; rc = [%d]\n",
__func__, rc);
goto out;
}
rc = crypto_hash_final(&desc, dst);
if (rc) {
printk(KERN_ERR
"%s: Error finalizing crypto hash; rc = [%d]\n",
__func__, rc); __func__, rc);
goto out; goto out;
} }
...@@ -234,10 +229,8 @@ void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) ...@@ -234,10 +229,8 @@ void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
{ {
struct ecryptfs_key_sig *key_sig, *key_sig_tmp; struct ecryptfs_key_sig *key_sig, *key_sig_tmp;
if (crypt_stat->tfm) crypto_free_skcipher(crypt_stat->tfm);
crypto_free_ablkcipher(crypt_stat->tfm); crypto_free_shash(crypt_stat->hash_tfm);
if (crypt_stat->hash_tfm)
crypto_free_hash(crypt_stat->hash_tfm);
list_for_each_entry_safe(key_sig, key_sig_tmp, list_for_each_entry_safe(key_sig, key_sig_tmp,
&crypt_stat->keysig_list, crypt_stat_list) { &crypt_stat->keysig_list, crypt_stat_list) {
list_del(&key_sig->crypt_stat_list); list_del(&key_sig->crypt_stat_list);
...@@ -342,7 +335,7 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -342,7 +335,7 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *src_sg, int size, struct scatterlist *src_sg, int size,
unsigned char *iv, int op) unsigned char *iv, int op)
{ {
struct ablkcipher_request *req = NULL; struct skcipher_request *req = NULL;
struct extent_crypt_result ecr; struct extent_crypt_result ecr;
int rc = 0; int rc = 0;
...@@ -358,20 +351,20 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -358,20 +351,20 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
init_completion(&ecr.completion); init_completion(&ecr.completion);
mutex_lock(&crypt_stat->cs_tfm_mutex); mutex_lock(&crypt_stat->cs_tfm_mutex);
req = ablkcipher_request_alloc(crypt_stat->tfm, GFP_NOFS); req = skcipher_request_alloc(crypt_stat->tfm, GFP_NOFS);
if (!req) { if (!req) {
mutex_unlock(&crypt_stat->cs_tfm_mutex); mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
ablkcipher_request_set_callback(req, skcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
extent_crypt_complete, &ecr); extent_crypt_complete, &ecr);
/* Consider doing this once, when the file is opened */ /* Consider doing this once, when the file is opened */
if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) { if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key, rc = crypto_skcipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size); crypt_stat->key_size);
if (rc) { if (rc) {
ecryptfs_printk(KERN_ERR, ecryptfs_printk(KERN_ERR,
"Error setting key; rc = [%d]\n", "Error setting key; rc = [%d]\n",
...@@ -383,9 +376,9 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -383,9 +376,9 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
crypt_stat->flags |= ECRYPTFS_KEY_SET; crypt_stat->flags |= ECRYPTFS_KEY_SET;
} }
mutex_unlock(&crypt_stat->cs_tfm_mutex); mutex_unlock(&crypt_stat->cs_tfm_mutex);
ablkcipher_request_set_crypt(req, src_sg, dst_sg, size, iv); skcipher_request_set_crypt(req, src_sg, dst_sg, size, iv);
rc = op == ENCRYPT ? crypto_ablkcipher_encrypt(req) : rc = op == ENCRYPT ? crypto_skcipher_encrypt(req) :
crypto_ablkcipher_decrypt(req); crypto_skcipher_decrypt(req);
if (rc == -EINPROGRESS || rc == -EBUSY) { if (rc == -EINPROGRESS || rc == -EBUSY) {
struct extent_crypt_result *ecr = req->base.data; struct extent_crypt_result *ecr = req->base.data;
...@@ -394,7 +387,7 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, ...@@ -394,7 +387,7 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
reinit_completion(&ecr->completion); reinit_completion(&ecr->completion);
} }
out: out:
ablkcipher_request_free(req); skcipher_request_free(req);
return rc; return rc;
} }
...@@ -622,7 +615,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) ...@@ -622,7 +615,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
crypt_stat->cipher, "cbc"); crypt_stat->cipher, "cbc");
if (rc) if (rc)
goto out_unlock; goto out_unlock;
crypt_stat->tfm = crypto_alloc_ablkcipher(full_alg_name, 0, 0); crypt_stat->tfm = crypto_alloc_skcipher(full_alg_name, 0, 0);
if (IS_ERR(crypt_stat->tfm)) { if (IS_ERR(crypt_stat->tfm)) {
rc = PTR_ERR(crypt_stat->tfm); rc = PTR_ERR(crypt_stat->tfm);
crypt_stat->tfm = NULL; crypt_stat->tfm = NULL;
...@@ -631,7 +624,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) ...@@ -631,7 +624,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
full_alg_name); full_alg_name);
goto out_free; goto out_free;
} }
crypto_ablkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); crypto_skcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
rc = 0; rc = 0;
out_free: out_free:
kfree(full_alg_name); kfree(full_alg_name);
...@@ -1591,7 +1584,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, ...@@ -1591,7 +1584,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size,
* event, regardless of whether this function succeeds for fails. * event, regardless of whether this function succeeds for fails.
*/ */
static int static int
ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, ecryptfs_process_key_cipher(struct crypto_skcipher **key_tfm,
char *cipher_name, size_t *key_size) char *cipher_name, size_t *key_size)
{ {
char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
...@@ -1609,21 +1602,18 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, ...@@ -1609,21 +1602,18 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
"ecb"); "ecb");
if (rc) if (rc)
goto out; goto out;
*key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); *key_tfm = crypto_alloc_skcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(*key_tfm)) { if (IS_ERR(*key_tfm)) {
rc = PTR_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]; rc = [%d]\n", full_alg_name, rc); "[%s]; rc = [%d]\n", full_alg_name, rc);
goto out; goto out;
} }
crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY); crypto_skcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
if (*key_size == 0) { if (*key_size == 0)
struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm); *key_size = crypto_skcipher_default_keysize(*key_tfm);
*key_size = alg->max_keysize;
}
get_random_bytes(dummy_key, *key_size); get_random_bytes(dummy_key, *key_size);
rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); rc = crypto_skcipher_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, full_alg_name, "cipher [%s]; rc = [%d]\n", *key_size, full_alg_name,
...@@ -1660,8 +1650,7 @@ int ecryptfs_destroy_crypto(void) ...@@ -1660,8 +1650,7 @@ int ecryptfs_destroy_crypto(void)
list_for_each_entry_safe(key_tfm, key_tfm_tmp, &key_tfm_list, list_for_each_entry_safe(key_tfm, key_tfm_tmp, &key_tfm_list,
key_tfm_list) { key_tfm_list) {
list_del(&key_tfm->key_tfm_list); list_del(&key_tfm->key_tfm_list);
if (key_tfm->key_tfm) crypto_free_skcipher(key_tfm->key_tfm);
crypto_free_blkcipher(key_tfm->key_tfm);
kmem_cache_free(ecryptfs_key_tfm_cache, key_tfm); kmem_cache_free(ecryptfs_key_tfm_cache, key_tfm);
} }
mutex_unlock(&key_tfm_list_mutex); mutex_unlock(&key_tfm_list_mutex);
...@@ -1747,7 +1736,7 @@ int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm) ...@@ -1747,7 +1736,7 @@ int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm)
* Searches for cached item first, and creates new if not found. * Searches for cached item first, and creates new if not found.
* Returns 0 on success, non-zero if adding new cipher failed * Returns 0 on success, non-zero if adding new cipher failed
*/ */
int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_skcipher **tfm,
struct mutex **tfm_mutex, struct mutex **tfm_mutex,
char *cipher_name) char *cipher_name)
{ {
...@@ -2120,7 +2109,7 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, ...@@ -2120,7 +2109,7 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
struct ecryptfs_mount_crypt_stat *mount_crypt_stat) struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{ {
struct blkcipher_desc desc; struct crypto_skcipher *tfm;
struct mutex *tfm_mutex; struct mutex *tfm_mutex;
size_t cipher_blocksize; size_t cipher_blocksize;
int rc; int rc;
...@@ -2130,7 +2119,7 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, ...@@ -2130,7 +2119,7 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
return 0; return 0;
} }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&tfm, &tfm_mutex,
mount_crypt_stat->global_default_fn_cipher_name); mount_crypt_stat->global_default_fn_cipher_name);
if (unlikely(rc)) { if (unlikely(rc)) {
(*namelen) = 0; (*namelen) = 0;
...@@ -2138,7 +2127,7 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, ...@@ -2138,7 +2127,7 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
} }
mutex_lock(tfm_mutex); mutex_lock(tfm_mutex);
cipher_blocksize = crypto_blkcipher_blocksize(desc.tfm); cipher_blocksize = crypto_skcipher_blocksize(tfm);
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
/* Return an exact amount for the common cases */ /* Return an exact amount for the common cases */
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#ifndef ECRYPTFS_KERNEL_H #ifndef ECRYPTFS_KERNEL_H
#define ECRYPTFS_KERNEL_H #define ECRYPTFS_KERNEL_H
#include <crypto/skcipher.h>
#include <keys/user-type.h> #include <keys/user-type.h>
#include <keys/encrypted-type.h> #include <keys/encrypted-type.h>
#include <linux/fs.h> #include <linux/fs.h>
...@@ -38,7 +39,6 @@ ...@@ -38,7 +39,6 @@
#include <linux/nsproxy.h> #include <linux/nsproxy.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/ecryptfs.h> #include <linux/ecryptfs.h>
#include <linux/crypto.h>
#define ECRYPTFS_DEFAULT_IV_BYTES 16 #define ECRYPTFS_DEFAULT_IV_BYTES 16
#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096 #define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
...@@ -233,9 +233,9 @@ struct ecryptfs_crypt_stat { ...@@ -233,9 +233,9 @@ 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_ablkcipher *tfm; struct crypto_skcipher *tfm;
struct crypto_hash *hash_tfm; /* Crypto context for generating struct crypto_shash *hash_tfm; /* Crypto context for generating
* the initialization vectors */ * the initialization vectors */
unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
...@@ -309,7 +309,7 @@ struct ecryptfs_global_auth_tok { ...@@ -309,7 +309,7 @@ struct ecryptfs_global_auth_tok {
* keeps a list of crypto API contexts around to use when needed. * keeps a list of crypto API contexts around to use when needed.
*/ */
struct ecryptfs_key_tfm { struct ecryptfs_key_tfm {
struct crypto_blkcipher *key_tfm; struct crypto_skcipher *key_tfm;
size_t key_size; size_t key_size;
struct mutex key_tfm_mutex; struct mutex key_tfm_mutex;
struct list_head key_tfm_list; struct list_head key_tfm_list;
...@@ -659,7 +659,7 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, ...@@ -659,7 +659,7 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
int ecryptfs_init_crypto(void); int ecryptfs_init_crypto(void);
int ecryptfs_destroy_crypto(void); int ecryptfs_destroy_crypto(void);
int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm); int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm);
int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_skcipher **tfm,
struct mutex **tfm_mutex, struct mutex **tfm_mutex,
char *cipher_name); char *cipher_name);
int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/crypto.h>
#include <linux/fs_stack.h> #include <linux/fs_stack.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/xattr.h> #include <linux/xattr.h>
......
...@@ -25,11 +25,12 @@ ...@@ -25,11 +25,12 @@
* 02111-1307, USA. * 02111-1307, USA.
*/ */
#include <crypto/hash.h>
#include <crypto/skcipher.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/key.h> #include <linux/key.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "ecryptfs_kernel.h" #include "ecryptfs_kernel.h"
...@@ -601,12 +602,13 @@ struct ecryptfs_write_tag_70_packet_silly_stack { ...@@ -601,12 +602,13 @@ struct ecryptfs_write_tag_70_packet_silly_stack {
struct ecryptfs_auth_tok *auth_tok; struct ecryptfs_auth_tok *auth_tok;
struct scatterlist src_sg[2]; struct scatterlist src_sg[2];
struct scatterlist dst_sg[2]; struct scatterlist dst_sg[2];
struct blkcipher_desc desc; struct crypto_skcipher *skcipher_tfm;
struct skcipher_request *skcipher_req;
char iv[ECRYPTFS_MAX_IV_BYTES]; char iv[ECRYPTFS_MAX_IV_BYTES];
char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; char hash[ECRYPTFS_TAG_70_DIGEST_SIZE];
char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE];
struct hash_desc hash_desc; struct crypto_shash *hash_tfm;
struct scatterlist hash_sg; struct shash_desc *hash_desc;
}; };
/** /**
...@@ -629,14 +631,13 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -629,14 +631,13 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
struct key *auth_tok_key = NULL; struct key *auth_tok_key = NULL;
int rc = 0; int rc = 0;
s = kmalloc(sizeof(*s), GFP_KERNEL); s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s) { if (!s) {
printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc "
"[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); "[%zd] bytes of kernel memory\n", __func__, sizeof(*s));
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
(*packet_size) = 0; (*packet_size) = 0;
rc = ecryptfs_find_auth_tok_for_sig( rc = ecryptfs_find_auth_tok_for_sig(
&auth_tok_key, &auth_tok_key,
...@@ -649,7 +650,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -649,7 +650,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
goto out; goto out;
} }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(
&s->desc.tfm, &s->skcipher_tfm,
&s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name);
if (unlikely(rc)) { if (unlikely(rc)) {
printk(KERN_ERR "Internal error whilst attempting to get " printk(KERN_ERR "Internal error whilst attempting to get "
...@@ -658,7 +659,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -658,7 +659,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
goto out; goto out;
} }
mutex_lock(s->tfm_mutex); mutex_lock(s->tfm_mutex);
s->block_size = crypto_blkcipher_blocksize(s->desc.tfm); s->block_size = crypto_skcipher_blocksize(s->skcipher_tfm);
/* Plus one for the \0 separator between the random prefix /* Plus one for the \0 separator between the random prefix
* and the plaintext filename */ * and the plaintext filename */
s->num_rand_bytes = (ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + 1); s->num_rand_bytes = (ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + 1);
...@@ -691,6 +692,19 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -691,6 +692,19 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
rc = -EINVAL; rc = -EINVAL;
goto out_unlock; goto out_unlock;
} }
s->skcipher_req = skcipher_request_alloc(s->skcipher_tfm, GFP_KERNEL);
if (!s->skcipher_req) {
printk(KERN_ERR "%s: Out of kernel memory whilst attempting to "
"skcipher_request_alloc for %s\n", __func__,
crypto_skcipher_driver_name(s->skcipher_tfm));
rc = -ENOMEM;
goto out_unlock;
}
skcipher_request_set_callback(s->skcipher_req,
CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
s->block_aligned_filename = kzalloc(s->block_aligned_filename_size, s->block_aligned_filename = kzalloc(s->block_aligned_filename_size,
GFP_KERNEL); GFP_KERNEL);
if (!s->block_aligned_filename) { if (!s->block_aligned_filename) {
...@@ -700,7 +714,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -700,7 +714,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
rc = -ENOMEM; rc = -ENOMEM;
goto out_unlock; goto out_unlock;
} }
s->i = 0;
dest[s->i++] = ECRYPTFS_TAG_70_PACKET_TYPE; dest[s->i++] = ECRYPTFS_TAG_70_PACKET_TYPE;
rc = ecryptfs_write_packet_length(&dest[s->i], rc = ecryptfs_write_packet_length(&dest[s->i],
(ECRYPTFS_SIG_SIZE (ECRYPTFS_SIG_SIZE
...@@ -738,40 +751,36 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -738,40 +751,36 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
"password tokens\n", __func__); "password tokens\n", __func__);
goto out_free_unlock; goto out_free_unlock;
} }
sg_init_one( s->hash_tfm = crypto_alloc_shash(ECRYPTFS_TAG_70_DIGEST, 0, 0);
&s->hash_sg, if (IS_ERR(s->hash_tfm)) {
(u8 *)s->auth_tok->token.password.session_key_encryption_key, rc = PTR_ERR(s->hash_tfm);
s->auth_tok->token.password.session_key_encryption_key_bytes);
s->hash_desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
s->hash_desc.tfm = crypto_alloc_hash(ECRYPTFS_TAG_70_DIGEST, 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(s->hash_desc.tfm)) {
rc = PTR_ERR(s->hash_desc.tfm);
printk(KERN_ERR "%s: Error attempting to " printk(KERN_ERR "%s: Error attempting to "
"allocate hash crypto context; rc = [%d]\n", "allocate hash crypto context; rc = [%d]\n",
__func__, rc); __func__, rc);
goto out_free_unlock; goto out_free_unlock;
} }
rc = crypto_hash_init(&s->hash_desc);
if (rc) { s->hash_desc = kmalloc(sizeof(*s->hash_desc) +
printk(KERN_ERR crypto_shash_descsize(s->hash_tfm), GFP_KERNEL);
"%s: Error initializing crypto hash; rc = [%d]\n", if (!s->hash_desc) {
__func__, rc); printk(KERN_ERR "%s: Out of kernel memory whilst attempting to "
goto out_release_free_unlock; "kmalloc [%zd] bytes\n", __func__,
} sizeof(*s->hash_desc) +
rc = crypto_hash_update( crypto_shash_descsize(s->hash_tfm));
&s->hash_desc, &s->hash_sg, rc = -ENOMEM;
s->auth_tok->token.password.session_key_encryption_key_bytes);
if (rc) {
printk(KERN_ERR
"%s: Error updating crypto hash; rc = [%d]\n",
__func__, rc);
goto out_release_free_unlock; goto out_release_free_unlock;
} }
rc = crypto_hash_final(&s->hash_desc, s->hash);
s->hash_desc->tfm = s->hash_tfm;
s->hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
rc = crypto_shash_digest(s->hash_desc,
(u8 *)s->auth_tok->token.password.session_key_encryption_key,
s->auth_tok->token.password.session_key_encryption_key_bytes,
s->hash);
if (rc) { if (rc) {
printk(KERN_ERR printk(KERN_ERR
"%s: Error finalizing crypto hash; rc = [%d]\n", "%s: Error computing crypto hash; rc = [%d]\n",
__func__, rc); __func__, rc);
goto out_release_free_unlock; goto out_release_free_unlock;
} }
...@@ -780,27 +789,12 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -780,27 +789,12 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)]; s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)];
if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE) if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)
== (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) { == (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) {
sg_init_one(&s->hash_sg, (u8 *)s->hash, rc = crypto_shash_digest(s->hash_desc, (u8 *)s->hash,
ECRYPTFS_TAG_70_DIGEST_SIZE); ECRYPTFS_TAG_70_DIGEST_SIZE,
rc = crypto_hash_init(&s->hash_desc); s->tmp_hash);
if (rc) {
printk(KERN_ERR
"%s: Error initializing crypto hash; "
"rc = [%d]\n", __func__, rc);
goto out_release_free_unlock;
}
rc = crypto_hash_update(&s->hash_desc, &s->hash_sg,
ECRYPTFS_TAG_70_DIGEST_SIZE);
if (rc) { if (rc) {
printk(KERN_ERR printk(KERN_ERR
"%s: Error updating crypto hash; " "%s: Error computing crypto hash; "
"rc = [%d]\n", __func__, rc);
goto out_release_free_unlock;
}
rc = crypto_hash_final(&s->hash_desc, s->tmp_hash);
if (rc) {
printk(KERN_ERR
"%s: Error finalizing crypto hash; "
"rc = [%d]\n", __func__, rc); "rc = [%d]\n", __func__, rc);
goto out_release_free_unlock; goto out_release_free_unlock;
} }
...@@ -834,10 +828,8 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -834,10 +828,8 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
* of the IV here, so we just use 0's for the IV. Note the * of the IV here, so we just use 0's for the IV. Note the
* constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES
* >= ECRYPTFS_MAX_IV_BYTES. */ * >= ECRYPTFS_MAX_IV_BYTES. */
memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); rc = crypto_skcipher_setkey(
s->desc.info = s->iv; s->skcipher_tfm,
rc = crypto_blkcipher_setkey(
s->desc.tfm,
s->auth_tok->token.password.session_key_encryption_key, s->auth_tok->token.password.session_key_encryption_key,
mount_crypt_stat->global_default_fn_cipher_key_bytes); mount_crypt_stat->global_default_fn_cipher_key_bytes);
if (rc < 0) { if (rc < 0) {
...@@ -850,8 +842,9 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -850,8 +842,9 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
mount_crypt_stat->global_default_fn_cipher_key_bytes); mount_crypt_stat->global_default_fn_cipher_key_bytes);
goto out_release_free_unlock; goto out_release_free_unlock;
} }
rc = crypto_blkcipher_encrypt_iv(&s->desc, s->dst_sg, s->src_sg, skcipher_request_set_crypt(s->skcipher_req, s->src_sg, s->dst_sg,
s->block_aligned_filename_size); s->block_aligned_filename_size, s->iv);
rc = crypto_skcipher_encrypt(s->skcipher_req);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error attempting to encrypt filename; " printk(KERN_ERR "%s: Error attempting to encrypt filename; "
"rc = [%d]\n", __func__, rc); "rc = [%d]\n", __func__, rc);
...@@ -861,7 +854,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -861,7 +854,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
(*packet_size) = s->i; (*packet_size) = s->i;
(*remaining_bytes) -= (*packet_size); (*remaining_bytes) -= (*packet_size);
out_release_free_unlock: out_release_free_unlock:
crypto_free_hash(s->hash_desc.tfm); crypto_free_shash(s->hash_tfm);
out_free_unlock: out_free_unlock:
kzfree(s->block_aligned_filename); kzfree(s->block_aligned_filename);
out_unlock: out_unlock:
...@@ -871,6 +864,8 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, ...@@ -871,6 +864,8 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
up_write(&(auth_tok_key->sem)); up_write(&(auth_tok_key->sem));
key_put(auth_tok_key); key_put(auth_tok_key);
} }
skcipher_request_free(s->skcipher_req);
kzfree(s->hash_desc);
kfree(s); kfree(s);
return rc; return rc;
} }
...@@ -888,7 +883,8 @@ struct ecryptfs_parse_tag_70_packet_silly_stack { ...@@ -888,7 +883,8 @@ struct ecryptfs_parse_tag_70_packet_silly_stack {
struct ecryptfs_auth_tok *auth_tok; struct ecryptfs_auth_tok *auth_tok;
struct scatterlist src_sg[2]; struct scatterlist src_sg[2];
struct scatterlist dst_sg[2]; struct scatterlist dst_sg[2];
struct blkcipher_desc desc; struct crypto_skcipher *skcipher_tfm;
struct skcipher_request *skcipher_req;
char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1];
char iv[ECRYPTFS_MAX_IV_BYTES]; char iv[ECRYPTFS_MAX_IV_BYTES];
char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
...@@ -922,14 +918,13 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, ...@@ -922,14 +918,13 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
(*packet_size) = 0; (*packet_size) = 0;
(*filename_size) = 0; (*filename_size) = 0;
(*filename) = NULL; (*filename) = NULL;
s = kmalloc(sizeof(*s), GFP_KERNEL); s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s) { if (!s) {
printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc "
"[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); "[%zd] bytes of kernel memory\n", __func__, sizeof(*s));
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
if (max_packet_size < ECRYPTFS_TAG_70_MIN_METADATA_SIZE) { if (max_packet_size < ECRYPTFS_TAG_70_MIN_METADATA_SIZE) {
printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be "
"at least [%d]\n", __func__, max_packet_size, "at least [%d]\n", __func__, max_packet_size,
...@@ -992,7 +987,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, ...@@ -992,7 +987,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
rc); rc);
goto out; goto out;
} }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->skcipher_tfm,
&s->tfm_mutex, &s->tfm_mutex,
s->cipher_string); s->cipher_string);
if (unlikely(rc)) { if (unlikely(rc)) {
...@@ -1030,12 +1025,23 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, ...@@ -1030,12 +1025,23 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
__func__, rc, s->block_aligned_filename_size); __func__, rc, s->block_aligned_filename_size);
goto out_free_unlock; goto out_free_unlock;
} }
s->skcipher_req = skcipher_request_alloc(s->skcipher_tfm, GFP_KERNEL);
if (!s->skcipher_req) {
printk(KERN_ERR "%s: Out of kernel memory whilst attempting to "
"skcipher_request_alloc for %s\n", __func__,
crypto_skcipher_driver_name(s->skcipher_tfm));
rc = -ENOMEM;
goto out_free_unlock;
}
skcipher_request_set_callback(s->skcipher_req,
CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
/* The characters in the first block effectively do the job of /* The characters in the first block effectively do the job of
* the IV here, so we just use 0's for the IV. Note the * the IV here, so we just use 0's for the IV. Note the
* constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES
* >= ECRYPTFS_MAX_IV_BYTES. */ * >= ECRYPTFS_MAX_IV_BYTES. */
memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES);
s->desc.info = s->iv;
/* TODO: Support other key modules than passphrase for /* TODO: Support other key modules than passphrase for
* filename encryption */ * filename encryption */
if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
...@@ -1044,8 +1050,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, ...@@ -1044,8 +1050,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
"password tokens\n", __func__); "password tokens\n", __func__);
goto out_free_unlock; goto out_free_unlock;
} }
rc = crypto_blkcipher_setkey( rc = crypto_skcipher_setkey(
s->desc.tfm, s->skcipher_tfm,
s->auth_tok->token.password.session_key_encryption_key, s->auth_tok->token.password.session_key_encryption_key,
mount_crypt_stat->global_default_fn_cipher_key_bytes); mount_crypt_stat->global_default_fn_cipher_key_bytes);
if (rc < 0) { if (rc < 0) {
...@@ -1058,14 +1064,14 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, ...@@ -1058,14 +1064,14 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
mount_crypt_stat->global_default_fn_cipher_key_bytes); mount_crypt_stat->global_default_fn_cipher_key_bytes);
goto out_free_unlock; goto out_free_unlock;
} }
rc = crypto_blkcipher_decrypt_iv(&s->desc, s->dst_sg, s->src_sg, skcipher_request_set_crypt(s->skcipher_req, s->src_sg, s->dst_sg,
s->block_aligned_filename_size); s->block_aligned_filename_size, s->iv);
rc = crypto_skcipher_decrypt(s->skcipher_req);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error attempting to decrypt filename; " printk(KERN_ERR "%s: Error attempting to decrypt filename; "
"rc = [%d]\n", __func__, rc); "rc = [%d]\n", __func__, rc);
goto out_free_unlock; goto out_free_unlock;
} }
s->i = 0;
while (s->decrypted_filename[s->i] != '\0' while (s->decrypted_filename[s->i] != '\0'
&& s->i < s->block_aligned_filename_size) && s->i < s->block_aligned_filename_size)
s->i++; s->i++;
...@@ -1108,6 +1114,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, ...@@ -1108,6 +1114,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
up_write(&(auth_tok_key->sem)); up_write(&(auth_tok_key->sem));
key_put(auth_tok_key); key_put(auth_tok_key);
} }
skcipher_request_free(s->skcipher_req);
kfree(s); kfree(s);
return rc; return rc;
} }
...@@ -1667,9 +1674,8 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -1667,9 +1674,8 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
struct scatterlist dst_sg[2]; struct scatterlist dst_sg[2];
struct scatterlist src_sg[2]; struct scatterlist src_sg[2];
struct mutex *tfm_mutex; struct mutex *tfm_mutex;
struct blkcipher_desc desc = { struct crypto_skcipher *tfm;
.flags = CRYPTO_TFM_REQ_MAY_SLEEP struct skcipher_request *req = NULL;
};
int rc = 0; int rc = 0;
if (unlikely(ecryptfs_verbosity > 0)) { if (unlikely(ecryptfs_verbosity > 0)) {
...@@ -1680,7 +1686,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -1680,7 +1686,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
auth_tok->token.password.session_key_encryption_key, auth_tok->token.password.session_key_encryption_key,
auth_tok->token.password.session_key_encryption_key_bytes); auth_tok->token.password.session_key_encryption_key_bytes);
} }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&tfm, &tfm_mutex,
crypt_stat->cipher); crypt_stat->cipher);
if (unlikely(rc)) { if (unlikely(rc)) {
printk(KERN_ERR "Internal error whilst attempting to get " printk(KERN_ERR "Internal error whilst attempting to get "
...@@ -1711,8 +1717,20 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -1711,8 +1717,20 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
goto out; goto out;
} }
mutex_lock(tfm_mutex); mutex_lock(tfm_mutex);
rc = crypto_blkcipher_setkey( req = skcipher_request_alloc(tfm, GFP_KERNEL);
desc.tfm, auth_tok->token.password.session_key_encryption_key, if (!req) {
mutex_unlock(tfm_mutex);
printk(KERN_ERR "%s: Out of kernel memory whilst attempting to "
"skcipher_request_alloc for %s\n", __func__,
crypto_skcipher_driver_name(tfm));
rc = -ENOMEM;
goto out;
}
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
NULL, NULL);
rc = crypto_skcipher_setkey(
tfm, auth_tok->token.password.session_key_encryption_key,
crypt_stat->key_size); crypt_stat->key_size);
if (unlikely(rc < 0)) { if (unlikely(rc < 0)) {
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
...@@ -1720,8 +1738,10 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -1720,8 +1738,10 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }
rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, skcipher_request_set_crypt(req, src_sg, dst_sg,
auth_tok->session_key.encrypted_key_size); auth_tok->session_key.encrypted_key_size,
NULL);
rc = crypto_skcipher_decrypt(req);
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
if (unlikely(rc)) { if (unlikely(rc)) {
printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc);
...@@ -1738,6 +1758,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, ...@@ -1738,6 +1758,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
crypt_stat->key_size); crypt_stat->key_size);
} }
out: out:
skcipher_request_free(req);
return rc; return rc;
} }
...@@ -2191,16 +2212,14 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes, ...@@ -2191,16 +2212,14 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
size_t max_packet_size; size_t max_packet_size;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat = struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
crypt_stat->mount_crypt_stat; crypt_stat->mount_crypt_stat;
struct blkcipher_desc desc = { struct crypto_skcipher *tfm;
.tfm = NULL, struct skcipher_request *req;
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0; int rc = 0;
(*packet_size) = 0; (*packet_size) = 0;
ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature,
ECRYPTFS_SIG_SIZE); ECRYPTFS_SIG_SIZE);
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&tfm, &tfm_mutex,
crypt_stat->cipher); crypt_stat->cipher);
if (unlikely(rc)) { if (unlikely(rc)) {
printk(KERN_ERR "Internal error whilst attempting to get " printk(KERN_ERR "Internal error whilst attempting to get "
...@@ -2209,12 +2228,11 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes, ...@@ -2209,12 +2228,11 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
goto out; goto out;
} }
if (mount_crypt_stat->global_default_cipher_key_size == 0) { if (mount_crypt_stat->global_default_cipher_key_size == 0) {
struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm);
printk(KERN_WARNING "No key size specified at mount; " printk(KERN_WARNING "No key size specified at mount; "
"defaulting to [%d]\n", alg->max_keysize); "defaulting to [%d]\n",
crypto_skcipher_default_keysize(tfm));
mount_crypt_stat->global_default_cipher_key_size = mount_crypt_stat->global_default_cipher_key_size =
alg->max_keysize; crypto_skcipher_default_keysize(tfm);
} }
if (crypt_stat->key_size == 0) if (crypt_stat->key_size == 0)
crypt_stat->key_size = crypt_stat->key_size =
...@@ -2284,20 +2302,36 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes, ...@@ -2284,20 +2302,36 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
goto out; goto out;
} }
mutex_lock(tfm_mutex); mutex_lock(tfm_mutex);
rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, rc = crypto_skcipher_setkey(tfm, session_key_encryption_key,
crypt_stat->key_size); crypt_stat->key_size);
if (rc < 0) { if (rc < 0) {
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; rc = [%d]\n", rc); "context; rc = [%d]\n", rc);
goto out; goto out;
} }
req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_ERR, "Out of kernel memory whilst "
"attempting to skcipher_request_alloc for "
"%s\n", crypto_skcipher_driver_name(tfm));
rc = -ENOMEM;
goto out;
}
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
NULL, NULL);
rc = 0; rc = 0;
ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the key\n", ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the key\n",
crypt_stat->key_size); crypt_stat->key_size);
rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg, skcipher_request_set_crypt(req, src_sg, dst_sg,
(*key_rec).enc_key_size); (*key_rec).enc_key_size, NULL);
rc = crypto_skcipher_encrypt(req);
mutex_unlock(tfm_mutex); mutex_unlock(tfm_mutex);
skcipher_request_free(req);
if (rc) { if (rc) {
printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);
goto out; goto out;
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/crypto.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/key.h> #include <linux/key.h>
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <linux/page-flags.h> #include <linux/page-flags.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/crypto.h>
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/magic.h> #include <linux/magic.h>
#include "ecryptfs_kernel.h" #include "ecryptfs_kernel.h"
......
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