|
@@ -123,6 +123,28 @@ out:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
|
|
|
+ char *cipher_name,
|
|
|
+ char *chaining_modifier)
|
|
|
+{
|
|
|
+ int cipher_name_len = strlen(cipher_name);
|
|
|
+ int chaining_modifier_len = strlen(chaining_modifier);
|
|
|
+ int algified_name_len;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ algified_name_len = (chaining_modifier_len + cipher_name_len + 3);
|
|
|
+ (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL);
|
|
|
+ if (!(algified_name)) {
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ snprintf((*algified_name), algified_name_len, "%s(%s)",
|
|
|
+ chaining_modifier, cipher_name);
|
|
|
+ rc = 0;
|
|
|
+out:
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* ecryptfs_derive_iv
|
|
|
* @iv: destination for the derived iv vale
|
|
@@ -197,7 +219,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
|
|
|
void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
|
|
|
{
|
|
|
if (crypt_stat->tfm)
|
|
|
- crypto_free_tfm(crypt_stat->tfm);
|
|
|
+ crypto_free_blkcipher(crypt_stat->tfm);
|
|
|
if (crypt_stat->hash_tfm)
|
|
|
crypto_free_hash(crypt_stat->hash_tfm);
|
|
|
memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
|
|
@@ -209,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat(
|
|
|
if (mount_crypt_stat->global_auth_tok_key)
|
|
|
key_put(mount_crypt_stat->global_auth_tok_key);
|
|
|
if (mount_crypt_stat->global_key_tfm)
|
|
|
- crypto_free_tfm(mount_crypt_stat->global_key_tfm);
|
|
|
+ crypto_free_blkcipher(mount_crypt_stat->global_key_tfm);
|
|
|
memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
|
|
|
}
|
|
|
|
|
@@ -275,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|
|
struct scatterlist *src_sg, int size,
|
|
|
unsigned char *iv)
|
|
|
{
|
|
|
+ struct blkcipher_desc desc = {
|
|
|
+ .tfm = crypt_stat->tfm,
|
|
|
+ .info = iv,
|
|
|
+ .flags = CRYPTO_TFM_REQ_MAY_SLEEP
|
|
|
+ };
|
|
|
int rc = 0;
|
|
|
|
|
|
BUG_ON(!crypt_stat || !crypt_stat->tfm
|
|
@@ -288,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|
|
}
|
|
|
/* Consider doing this once, when the file is opened */
|
|
|
mutex_lock(&crypt_stat->cs_tfm_mutex);
|
|
|
- rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
|
|
|
- crypt_stat->key_size);
|
|
|
+ rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
|
|
|
+ crypt_stat->key_size);
|
|
|
if (rc) {
|
|
|
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
|
|
|
rc);
|
|
@@ -298,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|
|
goto out;
|
|
|
}
|
|
|
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
|
|
|
- crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
|
|
|
+ crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size);
|
|
|
mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
|
|
out:
|
|
|
return rc;
|
|
@@ -681,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|
|
struct scatterlist *src_sg, int size,
|
|
|
unsigned char *iv)
|
|
|
{
|
|
|
+ struct blkcipher_desc desc = {
|
|
|
+ .tfm = crypt_stat->tfm,
|
|
|
+ .info = iv,
|
|
|
+ .flags = CRYPTO_TFM_REQ_MAY_SLEEP
|
|
|
+ };
|
|
|
int rc = 0;
|
|
|
|
|
|
/* Consider doing this once, when the file is opened */
|
|
|
mutex_lock(&crypt_stat->cs_tfm_mutex);
|
|
|
- rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
|
|
|
- crypt_stat->key_size);
|
|
|
+ rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
|
|
|
+ crypt_stat->key_size);
|
|
|
if (rc) {
|
|
|
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
|
|
|
rc);
|
|
@@ -695,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
|
|
|
goto out;
|
|
|
}
|
|
|
ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
|
|
|
- rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
|
|
|
- iv);
|
|
|
+ rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size);
|
|
|
mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
|
|
if (rc) {
|
|
|
ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
|
|
@@ -765,6 +796,7 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
|
|
|
*/
|
|
|
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
|
|
|
{
|
|
|
+ char *full_alg_name;
|
|
|
int rc = -EINVAL;
|
|
|
|
|
|
if (!crypt_stat->cipher) {
|
|
@@ -781,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
|
|
|
goto out;
|
|
|
}
|
|
|
mutex_lock(&crypt_stat->cs_tfm_mutex);
|
|
|
- crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
|
|
|
- ECRYPTFS_DEFAULT_CHAINING_MODE
|
|
|
- | CRYPTO_TFM_REQ_WEAK_KEY);
|
|
|
- mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
|
|
+ rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
|
|
|
+ crypt_stat->cipher, "cbc");
|
|
|
+ if (rc)
|
|
|
+ goto out;
|
|
|
+ crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0,
|
|
|
+ CRYPTO_ALG_ASYNC);
|
|
|
+ kfree(full_alg_name);
|
|
|
if (!crypt_stat->tfm) {
|
|
|
ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
|
|
|
"Error initializing cipher [%s]\n",
|
|
|
crypt_stat->cipher);
|
|
|
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
|
|
goto out;
|
|
|
}
|
|
|
+ crypto_blkcipher_set_flags(crypt_stat->tfm,
|
|
|
+ (ECRYPTFS_DEFAULT_CHAINING_MODE
|
|
|
+ | CRYPTO_TFM_REQ_WEAK_KEY));
|
|
|
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
|
|
|
rc = 0;
|
|
|
out:
|
|
|
return rc;
|
|
@@ -1588,10 +1628,11 @@ out:
|
|
|
* event, regardless of whether this function succeeds for fails.
|
|
|
*/
|
|
|
int
|
|
|
-ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name,
|
|
|
+ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
|
|
|
size_t *key_size)
|
|
|
{
|
|
|
char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
|
|
|
+ char *full_alg_name;
|
|
|
int rc;
|
|
|
|
|
|
*key_tfm = NULL;
|
|
@@ -1601,17 +1642,26 @@ ecryptfs_process_cipher(struct crypto_tfm **key_tfm, char *cipher_name,
|
|
|
"allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES);
|
|
|
goto out;
|
|
|
}
|
|
|
- *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
|
|
|
- if (!(*key_tfm)) {
|
|
|
- rc = -EINVAL;
|
|
|
+ rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name,
|
|
|
+ "ecb");
|
|
|
+ if (rc)
|
|
|
+ goto out;
|
|
|
+ *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
|
|
|
+ kfree(full_alg_name);
|
|
|
+ if (IS_ERR(*key_tfm)) {
|
|
|
+ rc = PTR_ERR(*key_tfm);
|
|
|
printk(KERN_ERR "Unable to allocate crypto cipher with name "
|
|
|
- "[%s]\n", cipher_name);
|
|
|
+ "[%s]; rc = [%d]\n", cipher_name, rc);
|
|
|
goto out;
|
|
|
}
|
|
|
- if (*key_size == 0)
|
|
|
- *key_size = crypto_tfm_alg_max_keysize(*key_tfm);
|
|
|
+ crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
|
|
|
+ if (*key_size == 0) {
|
|
|
+ struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm);
|
|
|
+
|
|
|
+ *key_size = alg->max_keysize;
|
|
|
+ }
|
|
|
get_random_bytes(dummy_key, *key_size);
|
|
|
- rc = crypto_cipher_setkey(*key_tfm, dummy_key, *key_size);
|
|
|
+ rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size);
|
|
|
if (rc) {
|
|
|
printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
|
|
|
"cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc);
|