mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 06:32:08 +00:00
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: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
cf80e0e47e
commit
3095e8e366
7 changed files with 180 additions and 161 deletions
|
@ -23,6 +23,8 @@
|
|||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
@ -30,7 +32,6 @@
|
|||
#include <linux/compiler.h>
|
||||
#include <linux/key.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -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
|
||||
* @dst: Pointer to 16 bytes of allocated memory
|
||||
|
@ -88,45 +102,26 @@ static int ecryptfs_calculate_md5(char *dst,
|
|||
struct ecryptfs_crypt_stat *crypt_stat,
|
||||
char *src, int len)
|
||||
{
|
||||
struct scatterlist sg;
|
||||
struct hash_desc desc = {
|
||||
.tfm = crypt_stat->hash_tfm,
|
||||
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
|
||||
};
|
||||
struct crypto_shash *tfm;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&crypt_stat->cs_hash_tfm_mutex);
|
||||
sg_init_one(&sg, (u8 *)src, len);
|
||||
if (!desc.tfm) {
|
||||
desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0,
|
||||
CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(desc.tfm)) {
|
||||
rc = PTR_ERR(desc.tfm);
|
||||
tfm = crypt_stat->hash_tfm;
|
||||
if (!tfm) {
|
||||
tfm = crypto_alloc_shash(ECRYPTFS_DEFAULT_HASH, 0, 0);
|
||||
if (IS_ERR(tfm)) {
|
||||
rc = PTR_ERR(tfm);
|
||||
ecryptfs_printk(KERN_ERR, "Error attempting to "
|
||||
"allocate crypto context; rc = [%d]\n",
|
||||
rc);
|
||||
goto out;
|
||||
}
|
||||
crypt_stat->hash_tfm = desc.tfm;
|
||||
crypt_stat->hash_tfm = tfm;
|
||||
}
|
||||
rc = crypto_hash_init(&desc);
|
||||
rc = ecryptfs_hash_digest(tfm, src, len, dst);
|
||||
if (rc) {
|
||||
printk(KERN_ERR
|
||||
"%s: Error initializing crypto hash; rc = [%d]\n",
|
||||
__func__, rc);
|
||||
goto out;
|
||||
}
|
||||
rc = crypto_hash_update(&desc, &sg, len);
|
||||
if (rc) {
|
||||
printk(KERN_ERR
|
||||
"%s: Error updating 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",
|
||||
"%s: Error computing crypto hash; rc = [%d]\n",
|
||||
__func__, rc);
|
||||
goto out;
|
||||
}
|
||||
|
@ -234,10 +229,8 @@ void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
|
|||
{
|
||||
struct ecryptfs_key_sig *key_sig, *key_sig_tmp;
|
||||
|
||||
if (crypt_stat->tfm)
|
||||
crypto_free_ablkcipher(crypt_stat->tfm);
|
||||
if (crypt_stat->hash_tfm)
|
||||
crypto_free_hash(crypt_stat->hash_tfm);
|
||||
crypto_free_skcipher(crypt_stat->tfm);
|
||||
crypto_free_shash(crypt_stat->hash_tfm);
|
||||
list_for_each_entry_safe(key_sig, key_sig_tmp,
|
||||
&crypt_stat->keysig_list, crypt_stat_list) {
|
||||
list_del(&key_sig->crypt_stat_list);
|
||||
|
@ -342,7 +335,7 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|||
struct scatterlist *src_sg, int size,
|
||||
unsigned char *iv, int op)
|
||||
{
|
||||
struct ablkcipher_request *req = NULL;
|
||||
struct skcipher_request *req = NULL;
|
||||
struct extent_crypt_result ecr;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -358,20 +351,20 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|||
init_completion(&ecr.completion);
|
||||
|
||||
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) {
|
||||
mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ablkcipher_request_set_callback(req,
|
||||
skcipher_request_set_callback(req,
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
extent_crypt_complete, &ecr);
|
||||
/* Consider doing this once, when the file is opened */
|
||||
if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
|
||||
rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
|
||||
crypt_stat->key_size);
|
||||
rc = crypto_skcipher_setkey(crypt_stat->tfm, crypt_stat->key,
|
||||
crypt_stat->key_size);
|
||||
if (rc) {
|
||||
ecryptfs_printk(KERN_ERR,
|
||||
"Error setting key; rc = [%d]\n",
|
||||
|
@ -383,9 +376,9 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|||
crypt_stat->flags |= ECRYPTFS_KEY_SET;
|
||||
}
|
||||
mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
||||
ablkcipher_request_set_crypt(req, src_sg, dst_sg, size, iv);
|
||||
rc = op == ENCRYPT ? crypto_ablkcipher_encrypt(req) :
|
||||
crypto_ablkcipher_decrypt(req);
|
||||
skcipher_request_set_crypt(req, src_sg, dst_sg, size, iv);
|
||||
rc = op == ENCRYPT ? crypto_skcipher_encrypt(req) :
|
||||
crypto_skcipher_decrypt(req);
|
||||
if (rc == -EINPROGRESS || rc == -EBUSY) {
|
||||
struct extent_crypt_result *ecr = req->base.data;
|
||||
|
||||
|
@ -394,7 +387,7 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|||
reinit_completion(&ecr->completion);
|
||||
}
|
||||
out:
|
||||
ablkcipher_request_free(req);
|
||||
skcipher_request_free(req);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -622,7 +615,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
|
|||
crypt_stat->cipher, "cbc");
|
||||
if (rc)
|
||||
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)) {
|
||||
rc = PTR_ERR(crypt_stat->tfm);
|
||||
crypt_stat->tfm = NULL;
|
||||
|
@ -631,7 +624,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
|
|||
full_alg_name);
|
||||
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;
|
||||
out_free:
|
||||
kfree(full_alg_name);
|
||||
|
@ -1591,7 +1584,7 @@ out:
|
|||
* event, regardless of whether this function succeeds for fails.
|
||||
*/
|
||||
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 dummy_key[ECRYPTFS_MAX_KEY_BYTES];
|
||||
|
@ -1609,21 +1602,18 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
|
|||
"ecb");
|
||||
if (rc)
|
||||
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)) {
|
||||
rc = PTR_ERR(*key_tfm);
|
||||
printk(KERN_ERR "Unable to allocate crypto cipher with name "
|
||||
"[%s]; rc = [%d]\n", full_alg_name, rc);
|
||||
goto out;
|
||||
}
|
||||
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;
|
||||
}
|
||||
crypto_skcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
|
||||
if (*key_size == 0)
|
||||
*key_size = crypto_skcipher_default_keysize(*key_tfm);
|
||||
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) {
|
||||
printk(KERN_ERR "Error attempting to set key of size [%zd] for "
|
||||
"cipher [%s]; rc = [%d]\n", *key_size, full_alg_name,
|
||||
|
@ -1660,8 +1650,7 @@ int ecryptfs_destroy_crypto(void)
|
|||
list_for_each_entry_safe(key_tfm, key_tfm_tmp, &key_tfm_list,
|
||||
key_tfm_list) {
|
||||
list_del(&key_tfm->key_tfm_list);
|
||||
if (key_tfm->key_tfm)
|
||||
crypto_free_blkcipher(key_tfm->key_tfm);
|
||||
crypto_free_skcipher(key_tfm->key_tfm);
|
||||
kmem_cache_free(ecryptfs_key_tfm_cache, key_tfm);
|
||||
}
|
||||
mutex_unlock(&key_tfm_list_mutex);
|
||||
|
@ -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.
|
||||
* 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,
|
||||
char *cipher_name)
|
||||
{
|
||||
|
@ -2120,7 +2109,7 @@ out:
|
|||
int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
|
||||
struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
|
||||
{
|
||||
struct blkcipher_desc desc;
|
||||
struct crypto_skcipher *tfm;
|
||||
struct mutex *tfm_mutex;
|
||||
size_t cipher_blocksize;
|
||||
int rc;
|
||||
|
@ -2130,7 +2119,7 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
|
|||
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);
|
||||
if (unlikely(rc)) {
|
||||
(*namelen) = 0;
|
||||
|
@ -2138,7 +2127,7 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
|
|||
}
|
||||
|
||||
mutex_lock(tfm_mutex);
|
||||
cipher_blocksize = crypto_blkcipher_blocksize(desc.tfm);
|
||||
cipher_blocksize = crypto_skcipher_blocksize(tfm);
|
||||
mutex_unlock(tfm_mutex);
|
||||
|
||||
/* Return an exact amount for the common cases */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue