2015-04-12 00:55:06 -04:00
|
|
|
/*
|
|
|
|
* linux/fs/ext4/crypto_key.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2015, Google, Inc.
|
|
|
|
*
|
|
|
|
* This contains encryption key functions for ext4
|
|
|
|
*
|
|
|
|
* Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <keys/encrypted-type.h>
|
|
|
|
#include <keys/user-type.h>
|
|
|
|
#include <linux/random.h>
|
|
|
|
#include <linux/scatterlist.h>
|
|
|
|
#include <uapi/linux/keyctl.h>
|
|
|
|
|
|
|
|
#include "ext4.h"
|
2016-09-13 18:45:47 +03:00
|
|
|
#include "ext4_ice.h"
|
2015-04-12 00:55:06 -04:00
|
|
|
#include "xattr.h"
|
|
|
|
|
|
|
|
static void derive_crypt_complete(struct crypto_async_request *req, int rc)
|
|
|
|
{
|
|
|
|
struct ext4_completion_result *ecr = req->data;
|
|
|
|
|
|
|
|
if (rc == -EINPROGRESS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ecr->res = rc;
|
|
|
|
complete(&ecr->completion);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
ANDROID: ext4: add a non-reversible key derivation method
Add a new per-file key derivation method to ext4 encryption defined as:
derived_key[0:127] = AES-256-ENCRYPT(master_key[0:255], nonce)
derived_key[128:255] = AES-256-ENCRYPT(master_key[0:255], nonce ^ 0x01)
derived_key[256:383] = AES-256-ENCRYPT(master_key[256:511], nonce)
derived_key[384:511] = AES-256-ENCRYPT(master_key[256:511], nonce ^ 0x01)
... where the derived key and master key are both 512 bits, the nonce is
128 bits, AES-256-ENCRYPT takes the arguments (key, plaintext), and
'nonce ^ 0x01' denotes flipping the low order bit of the last byte.
The existing key derivation method is
'derived_key = AES-128-ECB-ENCRYPT(key=nonce, plaintext=master_key)'.
We want to make this change because currently, given a derived key you
can easily compute the master key by computing
'AES-128-ECB-DECRYPT(key=nonce, ciphertext=derived_key)'.
This was formerly OK because the previous threat model assumed that the
master key and derived keys are equally hard to obtain by an attacker.
However, we are looking to move the master key into secure hardware in
some cases, so we want to make sure that an attacker with access to a
derived key cannot compute the master key.
We are doing this instead of increasing the nonce to 512 bits because
it's important that the per-file xattr fit in the inode itself. By
default, inodes are 256 bytes, and on Android we're already pretty close
to that limit. If we increase the nonce size, we end up allocating a new
filesystem block for each and every encrypted file, which has a
substantial performance and disk utilization impact.
Another option considered was to use the HMAC-SHA512 of the nonce, keyed
by the master key. However this would be a little less performant,
would be less extensible to other key sizes and MAC algorithms, and
would pull in a dependency (security-wise and code-wise) on SHA-512.
Due to the use of "aes" rather than "ecb(aes)" in the implementation,
the new key derivation method is actually about twice as fast as the old
one, though the old one could be optimized similarly as well.
This patch makes the new key derivation method be used whenever HEH is
used to encrypt filenames. Although these two features are logically
independent, it was decided to bundle them together for now. Note that
neither feature is upstream yet, and it cannot be guaranteed that the
on-disk format won't change if/when these features are upstreamed. For
this reason, and as noted in the previous patch, the features are both
behind a special mode number for now.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Change-Id: Iee4113f57e59dc8c0b7dc5238d7003c83defb986
2017-01-10 17:02:40 -08:00
|
|
|
* ext4_derive_key_v1() - Derive a key using AES-128-ECB
|
2015-07-22 00:09:45 -04:00
|
|
|
* @deriving_key: Encryption key used for derivation.
|
2015-04-12 00:55:06 -04:00
|
|
|
* @source_key: Source key to which to apply derivation.
|
|
|
|
* @derived_key: Derived key.
|
|
|
|
*
|
ANDROID: ext4: add a non-reversible key derivation method
Add a new per-file key derivation method to ext4 encryption defined as:
derived_key[0:127] = AES-256-ENCRYPT(master_key[0:255], nonce)
derived_key[128:255] = AES-256-ENCRYPT(master_key[0:255], nonce ^ 0x01)
derived_key[256:383] = AES-256-ENCRYPT(master_key[256:511], nonce)
derived_key[384:511] = AES-256-ENCRYPT(master_key[256:511], nonce ^ 0x01)
... where the derived key and master key are both 512 bits, the nonce is
128 bits, AES-256-ENCRYPT takes the arguments (key, plaintext), and
'nonce ^ 0x01' denotes flipping the low order bit of the last byte.
The existing key derivation method is
'derived_key = AES-128-ECB-ENCRYPT(key=nonce, plaintext=master_key)'.
We want to make this change because currently, given a derived key you
can easily compute the master key by computing
'AES-128-ECB-DECRYPT(key=nonce, ciphertext=derived_key)'.
This was formerly OK because the previous threat model assumed that the
master key and derived keys are equally hard to obtain by an attacker.
However, we are looking to move the master key into secure hardware in
some cases, so we want to make sure that an attacker with access to a
derived key cannot compute the master key.
We are doing this instead of increasing the nonce to 512 bits because
it's important that the per-file xattr fit in the inode itself. By
default, inodes are 256 bytes, and on Android we're already pretty close
to that limit. If we increase the nonce size, we end up allocating a new
filesystem block for each and every encrypted file, which has a
substantial performance and disk utilization impact.
Another option considered was to use the HMAC-SHA512 of the nonce, keyed
by the master key. However this would be a little less performant,
would be less extensible to other key sizes and MAC algorithms, and
would pull in a dependency (security-wise and code-wise) on SHA-512.
Due to the use of "aes" rather than "ecb(aes)" in the implementation,
the new key derivation method is actually about twice as fast as the old
one, though the old one could be optimized similarly as well.
This patch makes the new key derivation method be used whenever HEH is
used to encrypt filenames. Although these two features are logically
independent, it was decided to bundle them together for now. Note that
neither feature is upstream yet, and it cannot be guaranteed that the
on-disk format won't change if/when these features are upstreamed. For
this reason, and as noted in the previous patch, the features are both
behind a special mode number for now.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Change-Id: Iee4113f57e59dc8c0b7dc5238d7003c83defb986
2017-01-10 17:02:40 -08:00
|
|
|
* Return: 0 on success, -errno on failure
|
2015-04-12 00:55:06 -04:00
|
|
|
*/
|
ANDROID: ext4: add a non-reversible key derivation method
Add a new per-file key derivation method to ext4 encryption defined as:
derived_key[0:127] = AES-256-ENCRYPT(master_key[0:255], nonce)
derived_key[128:255] = AES-256-ENCRYPT(master_key[0:255], nonce ^ 0x01)
derived_key[256:383] = AES-256-ENCRYPT(master_key[256:511], nonce)
derived_key[384:511] = AES-256-ENCRYPT(master_key[256:511], nonce ^ 0x01)
... where the derived key and master key are both 512 bits, the nonce is
128 bits, AES-256-ENCRYPT takes the arguments (key, plaintext), and
'nonce ^ 0x01' denotes flipping the low order bit of the last byte.
The existing key derivation method is
'derived_key = AES-128-ECB-ENCRYPT(key=nonce, plaintext=master_key)'.
We want to make this change because currently, given a derived key you
can easily compute the master key by computing
'AES-128-ECB-DECRYPT(key=nonce, ciphertext=derived_key)'.
This was formerly OK because the previous threat model assumed that the
master key and derived keys are equally hard to obtain by an attacker.
However, we are looking to move the master key into secure hardware in
some cases, so we want to make sure that an attacker with access to a
derived key cannot compute the master key.
We are doing this instead of increasing the nonce to 512 bits because
it's important that the per-file xattr fit in the inode itself. By
default, inodes are 256 bytes, and on Android we're already pretty close
to that limit. If we increase the nonce size, we end up allocating a new
filesystem block for each and every encrypted file, which has a
substantial performance and disk utilization impact.
Another option considered was to use the HMAC-SHA512 of the nonce, keyed
by the master key. However this would be a little less performant,
would be less extensible to other key sizes and MAC algorithms, and
would pull in a dependency (security-wise and code-wise) on SHA-512.
Due to the use of "aes" rather than "ecb(aes)" in the implementation,
the new key derivation method is actually about twice as fast as the old
one, though the old one could be optimized similarly as well.
This patch makes the new key derivation method be used whenever HEH is
used to encrypt filenames. Although these two features are logically
independent, it was decided to bundle them together for now. Note that
neither feature is upstream yet, and it cannot be guaranteed that the
on-disk format won't change if/when these features are upstreamed. For
this reason, and as noted in the previous patch, the features are both
behind a special mode number for now.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Change-Id: Iee4113f57e59dc8c0b7dc5238d7003c83defb986
2017-01-10 17:02:40 -08:00
|
|
|
static int ext4_derive_key_v1(const char deriving_key[EXT4_AES_128_ECB_KEY_SIZE],
|
|
|
|
const char source_key[EXT4_AES_256_XTS_KEY_SIZE],
|
|
|
|
char derived_key[EXT4_AES_256_XTS_KEY_SIZE])
|
2015-04-12 00:55:06 -04:00
|
|
|
{
|
|
|
|
int res = 0;
|
|
|
|
struct ablkcipher_request *req = NULL;
|
|
|
|
DECLARE_EXT4_COMPLETION_RESULT(ecr);
|
|
|
|
struct scatterlist src_sg, dst_sg;
|
|
|
|
struct crypto_ablkcipher *tfm = crypto_alloc_ablkcipher("ecb(aes)", 0,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (IS_ERR(tfm)) {
|
|
|
|
res = PTR_ERR(tfm);
|
|
|
|
tfm = NULL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
|
|
|
|
req = ablkcipher_request_alloc(tfm, GFP_NOFS);
|
|
|
|
if (!req) {
|
|
|
|
res = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ablkcipher_request_set_callback(req,
|
|
|
|
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
|
|
|
|
derive_crypt_complete, &ecr);
|
|
|
|
res = crypto_ablkcipher_setkey(tfm, deriving_key,
|
|
|
|
EXT4_AES_128_ECB_KEY_SIZE);
|
|
|
|
if (res < 0)
|
|
|
|
goto out;
|
|
|
|
sg_init_one(&src_sg, source_key, EXT4_AES_256_XTS_KEY_SIZE);
|
|
|
|
sg_init_one(&dst_sg, derived_key, EXT4_AES_256_XTS_KEY_SIZE);
|
|
|
|
ablkcipher_request_set_crypt(req, &src_sg, &dst_sg,
|
|
|
|
EXT4_AES_256_XTS_KEY_SIZE, NULL);
|
|
|
|
res = crypto_ablkcipher_encrypt(req);
|
|
|
|
if (res == -EINPROGRESS || res == -EBUSY) {
|
|
|
|
wait_for_completion(&ecr.completion);
|
|
|
|
res = ecr.res;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (req)
|
|
|
|
ablkcipher_request_free(req);
|
|
|
|
if (tfm)
|
|
|
|
crypto_free_ablkcipher(tfm);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
ANDROID: ext4: add a non-reversible key derivation method
Add a new per-file key derivation method to ext4 encryption defined as:
derived_key[0:127] = AES-256-ENCRYPT(master_key[0:255], nonce)
derived_key[128:255] = AES-256-ENCRYPT(master_key[0:255], nonce ^ 0x01)
derived_key[256:383] = AES-256-ENCRYPT(master_key[256:511], nonce)
derived_key[384:511] = AES-256-ENCRYPT(master_key[256:511], nonce ^ 0x01)
... where the derived key and master key are both 512 bits, the nonce is
128 bits, AES-256-ENCRYPT takes the arguments (key, plaintext), and
'nonce ^ 0x01' denotes flipping the low order bit of the last byte.
The existing key derivation method is
'derived_key = AES-128-ECB-ENCRYPT(key=nonce, plaintext=master_key)'.
We want to make this change because currently, given a derived key you
can easily compute the master key by computing
'AES-128-ECB-DECRYPT(key=nonce, ciphertext=derived_key)'.
This was formerly OK because the previous threat model assumed that the
master key and derived keys are equally hard to obtain by an attacker.
However, we are looking to move the master key into secure hardware in
some cases, so we want to make sure that an attacker with access to a
derived key cannot compute the master key.
We are doing this instead of increasing the nonce to 512 bits because
it's important that the per-file xattr fit in the inode itself. By
default, inodes are 256 bytes, and on Android we're already pretty close
to that limit. If we increase the nonce size, we end up allocating a new
filesystem block for each and every encrypted file, which has a
substantial performance and disk utilization impact.
Another option considered was to use the HMAC-SHA512 of the nonce, keyed
by the master key. However this would be a little less performant,
would be less extensible to other key sizes and MAC algorithms, and
would pull in a dependency (security-wise and code-wise) on SHA-512.
Due to the use of "aes" rather than "ecb(aes)" in the implementation,
the new key derivation method is actually about twice as fast as the old
one, though the old one could be optimized similarly as well.
This patch makes the new key derivation method be used whenever HEH is
used to encrypt filenames. Although these two features are logically
independent, it was decided to bundle them together for now. Note that
neither feature is upstream yet, and it cannot be guaranteed that the
on-disk format won't change if/when these features are upstreamed. For
this reason, and as noted in the previous patch, the features are both
behind a special mode number for now.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Change-Id: Iee4113f57e59dc8c0b7dc5238d7003c83defb986
2017-01-10 17:02:40 -08:00
|
|
|
/**
|
|
|
|
* ext4_derive_key_v2() - Derive a key non-reversibly
|
|
|
|
* @nonce: the nonce associated with the file
|
|
|
|
* @master_key: the master key referenced by the file
|
|
|
|
* @derived_key: (output) the resulting derived key
|
|
|
|
*
|
|
|
|
* This function computes the following:
|
|
|
|
* derived_key[0:127] = AES-256-ENCRYPT(master_key[0:255], nonce)
|
|
|
|
* derived_key[128:255] = AES-256-ENCRYPT(master_key[0:255], nonce ^ 0x01)
|
|
|
|
* derived_key[256:383] = AES-256-ENCRYPT(master_key[256:511], nonce)
|
|
|
|
* derived_key[384:511] = AES-256-ENCRYPT(master_key[256:511], nonce ^ 0x01)
|
|
|
|
*
|
|
|
|
* 'nonce ^ 0x01' denotes flipping the low order bit of the last byte.
|
|
|
|
*
|
|
|
|
* Unlike the v1 algorithm, the v2 algorithm is "non-reversible", meaning that
|
|
|
|
* compromising a derived key does not also compromise the master key.
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno on failure
|
|
|
|
*/
|
|
|
|
static int ext4_derive_key_v2(const char nonce[EXT4_KEY_DERIVATION_NONCE_SIZE],
|
|
|
|
const char master_key[EXT4_MAX_KEY_SIZE],
|
|
|
|
char derived_key[EXT4_MAX_KEY_SIZE])
|
|
|
|
{
|
|
|
|
const int noncelen = EXT4_KEY_DERIVATION_NONCE_SIZE;
|
|
|
|
struct crypto_cipher *tfm;
|
|
|
|
int err;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Since we only use each transform for a small number of encryptions,
|
|
|
|
* requesting just "aes" turns out to be significantly faster than
|
|
|
|
* "ecb(aes)", by about a factor of two.
|
|
|
|
*/
|
|
|
|
tfm = crypto_alloc_cipher("aes", 0, 0);
|
|
|
|
if (IS_ERR(tfm))
|
|
|
|
return PTR_ERR(tfm);
|
|
|
|
|
|
|
|
BUILD_BUG_ON(4 * EXT4_KEY_DERIVATION_NONCE_SIZE != EXT4_MAX_KEY_SIZE);
|
|
|
|
BUILD_BUG_ON(2 * EXT4_AES_256_ECB_KEY_SIZE != EXT4_MAX_KEY_SIZE);
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
memcpy(derived_key, nonce, noncelen);
|
|
|
|
memcpy(derived_key + noncelen, nonce, noncelen);
|
|
|
|
derived_key[2 * noncelen - 1] ^= 0x01;
|
|
|
|
err = crypto_cipher_setkey(tfm, master_key,
|
|
|
|
EXT4_AES_256_ECB_KEY_SIZE);
|
|
|
|
if (err)
|
|
|
|
break;
|
|
|
|
crypto_cipher_encrypt_one(tfm, derived_key, derived_key);
|
|
|
|
crypto_cipher_encrypt_one(tfm, derived_key + noncelen,
|
|
|
|
derived_key + noncelen);
|
|
|
|
master_key += EXT4_AES_256_ECB_KEY_SIZE;
|
|
|
|
derived_key += 2 * noncelen;
|
|
|
|
}
|
|
|
|
crypto_free_cipher(tfm);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ext4_derive_key() - Derive a per-file key from a nonce and master key
|
|
|
|
* @ctx: the encryption context associated with the file
|
|
|
|
* @master_key: the master key referenced by the file
|
|
|
|
* @derived_key: (output) the resulting derived key
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno on failure
|
|
|
|
*/
|
|
|
|
static int ext4_derive_key(const struct ext4_encryption_context *ctx,
|
|
|
|
const char master_key[EXT4_MAX_KEY_SIZE],
|
|
|
|
char derived_key[EXT4_MAX_KEY_SIZE])
|
|
|
|
{
|
|
|
|
BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE != EXT4_KEY_DERIVATION_NONCE_SIZE);
|
|
|
|
BUILD_BUG_ON(EXT4_AES_256_XTS_KEY_SIZE != EXT4_MAX_KEY_SIZE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Although the key derivation algorithm is logically independent of the
|
|
|
|
* choice of encryption modes, in this kernel it is bundled with HEH
|
|
|
|
* encryption of filenames, which is another crypto improvement that
|
|
|
|
* requires an on-disk format change and requires userspace to specify
|
|
|
|
* different encryption policies.
|
|
|
|
*/
|
|
|
|
if (ctx->filenames_encryption_mode == EXT4_ENCRYPTION_MODE_AES_256_HEH)
|
|
|
|
return ext4_derive_key_v2(ctx->nonce, master_key, derived_key);
|
|
|
|
else
|
|
|
|
return ext4_derive_key_v1(ctx->nonce, master_key, derived_key);
|
|
|
|
}
|
|
|
|
|
2015-05-31 13:34:22 -04:00
|
|
|
void ext4_free_crypt_info(struct ext4_crypt_info *ci)
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
{
|
|
|
|
if (!ci)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ci->ci_keyring_key)
|
|
|
|
key_put(ci->ci_keyring_key);
|
|
|
|
crypto_free_ablkcipher(ci->ci_ctfm);
|
2015-05-18 13:19:47 -04:00
|
|
|
kmem_cache_free(ext4_crypt_info_cachep, ci);
|
2015-05-31 13:34:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void ext4_free_encryption_info(struct inode *inode,
|
|
|
|
struct ext4_crypt_info *ci)
|
|
|
|
{
|
|
|
|
struct ext4_inode_info *ei = EXT4_I(inode);
|
|
|
|
struct ext4_crypt_info *prev;
|
|
|
|
|
|
|
|
if (ci == NULL)
|
|
|
|
ci = ACCESS_ONCE(ei->i_crypt_info);
|
|
|
|
if (ci == NULL)
|
|
|
|
return;
|
|
|
|
prev = cmpxchg(&ei->i_crypt_info, ci, NULL);
|
|
|
|
if (prev != ci)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ext4_free_crypt_info(ci);
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
}
|
|
|
|
|
2016-09-13 18:45:47 +03:00
|
|
|
static int ext4_default_data_encryption_mode(void)
|
|
|
|
{
|
|
|
|
return ext4_is_ice_enabled() ? EXT4_ENCRYPTION_MODE_PRIVATE :
|
|
|
|
EXT4_ENCRYPTION_MODE_AES_256_XTS;
|
|
|
|
}
|
|
|
|
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
int _ext4_get_encryption_info(struct inode *inode)
|
2015-04-12 00:55:06 -04:00
|
|
|
{
|
|
|
|
struct ext4_inode_info *ei = EXT4_I(inode);
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
struct ext4_crypt_info *crypt_info;
|
2015-04-12 00:55:06 -04:00
|
|
|
char full_key_descriptor[EXT4_KEY_DESC_PREFIX_SIZE +
|
|
|
|
(EXT4_KEY_DESCRIPTOR_SIZE * 2) + 1];
|
|
|
|
struct key *keyring_key = NULL;
|
|
|
|
struct ext4_encryption_key *master_key;
|
|
|
|
struct ext4_encryption_context ctx;
|
2015-10-21 14:04:48 +01:00
|
|
|
const struct user_key_payload *ukp;
|
2015-04-16 01:56:00 -04:00
|
|
|
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
2015-05-31 13:34:22 -04:00
|
|
|
struct crypto_ablkcipher *ctfm;
|
|
|
|
const char *cipher_str;
|
2016-09-13 18:45:47 +03:00
|
|
|
int for_fname = 0;
|
|
|
|
int mode;
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
int res;
|
2015-04-12 00:55:06 -04:00
|
|
|
|
2017-10-29 06:30:19 -04:00
|
|
|
res = ext4_init_crypto();
|
|
|
|
if (res)
|
|
|
|
return res;
|
2015-05-18 13:19:47 -04:00
|
|
|
|
2015-05-31 13:34:22 -04:00
|
|
|
retry:
|
|
|
|
crypt_info = ACCESS_ONCE(ei->i_crypt_info);
|
|
|
|
if (crypt_info) {
|
|
|
|
if (!crypt_info->ci_keyring_key ||
|
|
|
|
key_validate(crypt_info->ci_keyring_key) == 0)
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
return 0;
|
2015-05-31 13:34:22 -04:00
|
|
|
ext4_free_encryption_info(inode, crypt_info);
|
|
|
|
goto retry;
|
2015-04-12 00:55:06 -04:00
|
|
|
}
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
|
|
|
|
res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
|
|
|
|
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
|
|
|
|
&ctx, sizeof(ctx));
|
|
|
|
if (res < 0) {
|
|
|
|
if (!DUMMY_ENCRYPTION_ENABLED(sbi))
|
|
|
|
return res;
|
2016-09-13 18:45:47 +03:00
|
|
|
ctx.contents_encryption_mode =
|
|
|
|
ext4_default_data_encryption_mode();
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
ctx.filenames_encryption_mode =
|
|
|
|
EXT4_ENCRYPTION_MODE_AES_256_CTS;
|
|
|
|
ctx.flags = 0;
|
|
|
|
} else if (res != sizeof(ctx))
|
|
|
|
return -EINVAL;
|
2015-04-12 00:55:06 -04:00
|
|
|
res = 0;
|
|
|
|
|
2015-05-18 13:19:47 -04:00
|
|
|
crypt_info = kmem_cache_alloc(ext4_crypt_info_cachep, GFP_KERNEL);
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
if (!crypt_info)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
crypt_info->ci_flags = ctx.flags;
|
|
|
|
crypt_info->ci_data_mode = ctx.contents_encryption_mode;
|
|
|
|
crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
|
|
|
|
crypt_info->ci_ctfm = NULL;
|
2015-05-31 13:34:22 -04:00
|
|
|
crypt_info->ci_keyring_key = NULL;
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
|
|
|
|
sizeof(crypt_info->ci_master_key));
|
2016-09-13 18:45:47 +03:00
|
|
|
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
|
|
|
|
for_fname = 1;
|
|
|
|
else if (!S_ISREG(inode->i_mode))
|
2015-04-16 01:56:00 -04:00
|
|
|
BUG();
|
2016-09-13 18:45:47 +03:00
|
|
|
mode = for_fname ? crypt_info->ci_filename_mode :
|
|
|
|
crypt_info->ci_data_mode;
|
2015-05-31 13:34:22 -04:00
|
|
|
switch (mode) {
|
|
|
|
case EXT4_ENCRYPTION_MODE_AES_256_XTS:
|
|
|
|
cipher_str = "xts(aes)";
|
|
|
|
break;
|
|
|
|
case EXT4_ENCRYPTION_MODE_AES_256_CTS:
|
|
|
|
cipher_str = "cts(cbc(aes))";
|
|
|
|
break;
|
2016-09-13 18:45:47 +03:00
|
|
|
case EXT4_ENCRYPTION_MODE_PRIVATE:
|
|
|
|
cipher_str = "bugon";
|
2017-01-10 17:02:39 -08:00
|
|
|
case EXT4_ENCRYPTION_MODE_AES_256_HEH:
|
|
|
|
cipher_str = "heh(aes)";
|
2016-09-13 18:45:47 +03:00
|
|
|
break;
|
BACKPORT, FROMLIST: fscrypt: add Speck128/256 support
fscrypt currently only supports AES encryption. However, many low-end
mobile devices have older CPUs that don't have AES instructions, e.g.
the ARMv8 Cryptography Extensions. Currently, user data on such devices
is not encrypted at rest because AES is too slow, even when the NEON
bit-sliced implementation of AES is used. Unfortunately, it is
infeasible to encrypt these devices at all when AES is the only option.
Therefore, this patch updates fscrypt to support the Speck block cipher,
which was recently added to the crypto API. The C implementation of
Speck is not especially fast, but Speck can be implemented very
efficiently with general-purpose vector instructions, e.g. ARM NEON.
For example, on an ARMv7 processor, we measured the NEON-accelerated
Speck128/256-XTS at 69 MB/s for both encryption and decryption, while
AES-256-XTS with the NEON bit-sliced implementation was only 22 MB/s
encryption and 19 MB/s decryption.
There are multiple variants of Speck. This patch only adds support for
Speck128/256, which is the variant with a 128-bit block size and 256-bit
key size -- the same as AES-256. This is believed to be the most secure
variant of Speck, and it's only about 6% slower than Speck128/128.
Speck64/128 would be at least 20% faster because it has 20% rounds, and
it can be even faster on CPUs that can't efficiently do the 64-bit
operations needed for Speck128. However, Speck64's 64-bit block size is
not preferred security-wise. ARM NEON also supports the needed 64-bit
operations even on 32-bit CPUs, resulting in Speck128 being fast enough
for our targeted use cases so far.
The chosen modes of operation are XTS for contents and CTS-CBC for
filenames. These are the same modes of operation that fscrypt defaults
to for AES. Note that as with the other fscrypt modes, Speck will not
be used unless userspace chooses to use it. Nor are any of the existing
modes (which are all AES-based) being removed, of course.
We intentionally don't make CONFIG_FS_ENCRYPTION select
CONFIG_CRYPTO_SPECK, so people will have to enable Speck support
themselves if they need it. This is because we shouldn't bloat the
FS_ENCRYPTION dependencies with every new cipher, especially ones that
aren't recommended for most users. Moreover, CRYPTO_SPECK is just the
generic implementation, which won't be fast enough for many users; in
practice, they'll need to enable CRYPTO_SPECK_NEON to get acceptable
performance.
More details about our choice of Speck can be found in our patches that
added Speck to the crypto API, and the follow-on discussion threads.
We're planning a publication that explains the choice in more detail.
But briefly, we can't use ChaCha20 as we previously proposed, since it
would be insecure to use a stream cipher in this context, with potential
IV reuse during writes on f2fs and/or on wear-leveling flash storage.
We also evaluated many other lightweight and/or ARX-based block ciphers
such as Chaskey-LTS, RC5, LEA, CHAM, Threefish, RC6, NOEKEON, SPARX, and
XTEA. However, all had disadvantages vs. Speck, such as insufficient
performance with NEON, much less published cryptanalysis, or an
insufficient security level. Various design choices in Speck make it
perform better with NEON than competing ciphers while still having a
security margin similar to AES, and in the case of Speck128 also the
same available security levels. Unfortunately, Speck does have some
political baggage attached -- it's an NSA designed cipher, and was
rejected from an ISO standard (though for context, as far as I know none
of the above-mentioned alternatives are ISO standards either).
Nevertheless, we believe it is a good solution to the problem from a
technical perspective.
Certain algorithms constructed from ChaCha or the ChaCha permutation,
such as MEM (Masked Even-Mansour) or HPolyC, may also meet our
performance requirements. However, these are new constructions that
need more time to receive the cryptographic review and acceptance needed
to be confident in their security. HPolyC hasn't been published yet,
and we are concerned that MEM makes stronger assumptions about the
underlying permutation than the ChaCha stream cipher does. In contrast,
the XTS mode of operation is relatively well accepted, and Speck has
over 70 cryptanalysis papers. Of course, these ChaCha-based algorithms
can still be added later if they become ready.
The best known attack on Speck128/256 is a differential cryptanalysis
attack on 25 of 34 rounds with 2^253 time complexity and 2^125 chosen
plaintexts, i.e. only marginally faster than brute force. There is no
known attack on the full 34 rounds.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
(cherry-picked from commit 12d28f79558f2e987c5f3817f89e1ccc0f11a7b5
https://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt.git master)
(dropped Documentation/filesystems/fscrypt.rst change)
(fixed merge conflict in fs/crypto/keyinfo.c)
(also ported change to fs/ext4/, which isn't using fs/crypto/ in this
kernel version)
Change-Id: I62c632044dfd06a2c5b74c2fb058f9c3b8af0add
Signed-off-by: Eric Biggers <ebiggers@google.com>
2018-05-07 17:22:08 -07:00
|
|
|
case EXT4_ENCRYPTION_MODE_SPECK128_256_XTS:
|
|
|
|
cipher_str = "xts(speck128)";
|
|
|
|
break;
|
|
|
|
case EXT4_ENCRYPTION_MODE_SPECK128_256_CTS:
|
|
|
|
cipher_str = "cts(cbc(speck128))";
|
|
|
|
break;
|
2015-05-31 13:34:22 -04:00
|
|
|
default:
|
|
|
|
printk_once(KERN_WARNING
|
|
|
|
"ext4: unsupported key mode %d (ino %u)\n",
|
|
|
|
mode, (unsigned) inode->i_ino);
|
|
|
|
res = -ENOKEY;
|
2015-04-16 01:56:00 -04:00
|
|
|
goto out;
|
|
|
|
}
|
2015-05-31 13:34:22 -04:00
|
|
|
if (DUMMY_ENCRYPTION_ENABLED(sbi)) {
|
2016-09-13 18:45:47 +03:00
|
|
|
memset(crypt_info->ci_raw_key, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
|
2015-05-31 13:34:22 -04:00
|
|
|
goto got_key;
|
|
|
|
}
|
2015-04-12 00:55:06 -04:00
|
|
|
memcpy(full_key_descriptor, EXT4_KEY_DESC_PREFIX,
|
|
|
|
EXT4_KEY_DESC_PREFIX_SIZE);
|
|
|
|
sprintf(full_key_descriptor + EXT4_KEY_DESC_PREFIX_SIZE,
|
|
|
|
"%*phN", EXT4_KEY_DESCRIPTOR_SIZE,
|
|
|
|
ctx.master_key_descriptor);
|
|
|
|
full_key_descriptor[EXT4_KEY_DESC_PREFIX_SIZE +
|
|
|
|
(2 * EXT4_KEY_DESCRIPTOR_SIZE)] = '\0';
|
|
|
|
keyring_key = request_key(&key_type_logon, full_key_descriptor, NULL);
|
|
|
|
if (IS_ERR(keyring_key)) {
|
|
|
|
res = PTR_ERR(keyring_key);
|
|
|
|
keyring_key = NULL;
|
|
|
|
goto out;
|
|
|
|
}
|
2015-05-31 13:34:22 -04:00
|
|
|
crypt_info->ci_keyring_key = keyring_key;
|
2015-10-03 10:49:27 -04:00
|
|
|
if (keyring_key->type != &key_type_logon) {
|
|
|
|
printk_once(KERN_WARNING
|
|
|
|
"ext4: key type must be logon\n");
|
|
|
|
res = -ENOKEY;
|
|
|
|
goto out;
|
|
|
|
}
|
2015-12-10 00:57:58 -05:00
|
|
|
down_read(&keyring_key->sem);
|
2015-10-21 14:04:48 +01:00
|
|
|
ukp = user_key_payload(keyring_key);
|
2017-10-09 12:46:18 -07:00
|
|
|
if (!ukp) {
|
|
|
|
/* key was revoked before we acquired its semaphore */
|
|
|
|
res = -EKEYREVOKED;
|
|
|
|
up_read(&keyring_key->sem);
|
|
|
|
goto out;
|
|
|
|
}
|
2015-04-12 00:55:06 -04:00
|
|
|
if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
|
|
|
|
res = -EINVAL;
|
2015-12-10 00:57:58 -05:00
|
|
|
up_read(&keyring_key->sem);
|
2015-04-12 00:55:06 -04:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
master_key = (struct ext4_encryption_key *)ukp->data;
|
|
|
|
BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE !=
|
|
|
|
EXT4_KEY_DERIVATION_NONCE_SIZE);
|
2015-10-03 10:49:27 -04:00
|
|
|
if (master_key->size != EXT4_AES_256_XTS_KEY_SIZE) {
|
|
|
|
printk_once(KERN_WARNING
|
|
|
|
"ext4: key size incorrect: %d\n",
|
|
|
|
master_key->size);
|
|
|
|
res = -ENOKEY;
|
2015-12-10 00:57:58 -05:00
|
|
|
up_read(&keyring_key->sem);
|
2015-10-03 10:49:27 -04:00
|
|
|
goto out;
|
|
|
|
}
|
Merge branch 'android-4.4@c71ad0f' into branch 'msm-4.4'
* refs/heads/tmp-c71ad0f:
BACKPORT: arm64: dts: juno: fix cluster sleep state entry latency on all SoC versions
staging: android: ashmem: lseek failed due to no FMODE_LSEEK.
ANDROID: sdcardfs: update module info
ANDROID: sdcardfs: use d_splice_alias
ANDROID: sdcardfs: add read_iter/write_iter opeations
ANDROID: sdcardfs: fix ->llseek to update upper and lower offset
ANDROID: sdcardfs: copy lower inode attributes in ->ioctl
ANDROID: sdcardfs: remove unnecessary call to do_munmap
Merge 4.4.59 into android-4.4
UPSTREAM: ipv6 addrconf: implement RFC7559 router solicitation backoff
android: base-cfg: enable CONFIG_INET_DIAG_DESTROY
ANDROID: android-base.cfg: add CONFIG_MODULES option
ANDROID: android-base.cfg: add CONFIG_IKCONFIG option
ANDROID: android-base.cfg: properly sort the file
ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES.
ANDROID: sort android-recommended.cfg
UPSTREAM: config/android: Remove CONFIG_IPV6_PRIVACY
UPSTREAM: config: android: set SELinux as default security mode
config: android: move device mapper options to recommended
ANDROID: ARM64: Allow to choose appended kernel image
UPSTREAM: arm64: vdso: constify vm_special_mapping used for aarch32 vectors page
UPSTREAM: arm64: vdso: add __init section marker to alloc_vectors_page
UPSTREAM: ARM: 8597/1: VDSO: put RO and RO after init objects into proper sections
UPSTREAM: arm64: Add support for CLOCK_MONOTONIC_RAW in clock_gettime() vDSO
UPSTREAM: arm64: Refactor vDSO time functions
UPSTREAM: arm64: fix vdso-offsets.h dependency
UPSTREAM: kbuild: drop FORCE from PHONY targets
UPSTREAM: mm: add PHYS_PFN, use it in __phys_to_pfn()
UPSTREAM: ARM: 8476/1: VDSO: use PTR_ERR_OR_ZERO for vma check
Linux 4.4.58
crypto: algif_hash - avoid zero-sized array
fbcon: Fix vc attr at deinit
serial: 8250_pci: Detach low-level driver during PCI error recovery
ACPI / blacklist: Make Dell Latitude 3350 ethernet work
ACPI / blacklist: add _REV quirks for Dell Precision 5520 and 3520
uvcvideo: uvc_scan_fallback() for webcams with broken chain
s390/zcrypt: Introduce CEX6 toleration
block: allow WRITE_SAME commands with the SG_IO ioctl
vfio/spapr: Postpone allocation of userspace version of TCE table
PCI: Do any VF BAR updates before enabling the BARs
PCI: Ignore BAR updates on virtual functions
PCI: Update BARs using property bits appropriate for type
PCI: Don't update VF BARs while VF memory space is enabled
PCI: Decouple IORESOURCE_ROM_ENABLE and PCI_ROM_ADDRESS_ENABLE
PCI: Add comments about ROM BAR updating
PCI: Remove pci_resource_bar() and pci_iov_resource_bar()
PCI: Separate VF BAR updates from standard BAR updates
x86/hyperv: Handle unknown NMIs on one CPU when unknown_nmi_panic
igb: add i211 to i210 PHY workaround
igb: Workaround for igb i210 firmware issue
xen: do not re-use pirq number cached in pci device msi msg data
xfs: clear _XBF_PAGES from buffers when readahead page
USB: usbtmc: add missing endpoint sanity check
nl80211: fix dumpit error path RTNL deadlocks
xfs: fix up xfs_swap_extent_forks inline extent handling
xfs: don't allow di_size with high bit set
libceph: don't set weight to IN when OSD is destroyed
raid10: increment write counter after bio is split
cpufreq: Restore policy min/max limits on CPU online
ARM: dts: at91: sama5d2: add dma properties to UART nodes
ARM: at91: pm: cpu_idle: switch DDR to power-down mode
iommu/vt-d: Fix NULL pointer dereference in device_to_iommu
xen/acpi: upload PM state from init-domain to Xen
mmc: sdhci: Do not disable interrupts while waiting for clock
ext4: mark inode dirty after converting inline directory
parport: fix attempt to write duplicate procfiles
iio: hid-sensor-trigger: Change get poll value function order to avoid sensor properties losing after resume from S3
iio: adc: ti_am335x_adc: fix fifo overrun recovery
mmc: ushc: fix NULL-deref at probe
uwb: hwa-rc: fix NULL-deref at probe
uwb: i1480-dfu: fix NULL-deref at probe
usb: hub: Fix crash after failure to read BOS descriptor
usb: musb: cppi41: don't check early-TX-interrupt for Isoch transfer
USB: wusbcore: fix NULL-deref at probe
USB: idmouse: fix NULL-deref at probe
USB: lvtest: fix NULL-deref at probe
USB: uss720: fix NULL-deref at probe
usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk
usb: gadget: f_uvc: Fix SuperSpeed companion descriptor's wBytesPerInterval
ACM gadget: fix endianness in notifications
USB: serial: qcserial: add Dell DW5811e
USB: serial: option: add Quectel UC15, UC20, EC21, and EC25 modems
ALSA: hda - Adding a group of pin definition to fix headset problem
ALSA: ctxfi: Fix the incorrect check of dma_set_mask() call
ALSA: seq: Fix racy cell insertions during snd_seq_pool_done()
Input: sur40 - validate number of endpoints before using them
Input: kbtab - validate number of endpoints before using them
Input: cm109 - validate number of endpoints before using them
Input: yealink - validate number of endpoints before using them
Input: hanwang - validate number of endpoints before using them
Input: ims-pcu - validate number of endpoints before using them
Input: iforce - validate number of endpoints before using them
Input: i8042 - add noloop quirk for Dell Embedded Box PC 3000
Input: elan_i2c - add ASUS EeeBook X205TA special touchpad fw
tcp: initialize icsk_ack.lrcvtime at session start time
socket, bpf: fix sk_filter use after free in sk_clone_lock
ipv4: provide stronger user input validation in nl_fib_input()
net: bcmgenet: remove bcmgenet_internal_phy_setup()
net/mlx5e: Count LRO packets correctly
net/mlx5: Increase number of max QPs in default profile
net: unix: properly re-increment inflight counter of GC discarded candidates
amd-xgbe: Fix jumbo MTU processing on newer hardware
net: properly release sk_frag.page
net: bcmgenet: Do not suspend PHY if Wake-on-LAN is enabled
net/openvswitch: Set the ipv6 source tunnel key address attribute correctly
Linux 4.4.57
ext4: fix fencepost in s_first_meta_bg validation
percpu: acquire pcpu_lock when updating pcpu_nr_empty_pop_pages
gfs2: Avoid alignment hole in struct lm_lockname
isdn/gigaset: fix NULL-deref at probe
target: Fix VERIFY_16 handling in sbc_parse_cdb
scsi: libiscsi: add lock around task lists to fix list corruption regression
scsi: lpfc: Add shutdown method for kexec
target/pscsi: Fix TYPE_TAPE + TYPE_MEDIMUM_CHANGER export
md/raid1/10: fix potential deadlock
powerpc/boot: Fix zImage TOC alignment
cpufreq: Fix and clean up show_cpuinfo_cur_freq()
perf/core: Fix event inheritance on fork()
give up on gcc ilog2() constant optimizations
kernek/fork.c: allocate idle task for a CPU always on its local node
hv_netvsc: use skb_get_hash() instead of a homegrown implementation
tpm_tis: Use devm_free_irq not free_irq
drm/amdgpu: add missing irq.h include
s390/pci: fix use after free in dma_init
KVM: PPC: Book3S PR: Fix illegal opcode emulation
xen/qspinlock: Don't kick CPU if IRQ is not initialized
Drivers: hv: avoid vfree() on crash
Drivers: hv: balloon: don't crash when memory is added in non-sorted order
pinctrl: cherryview: Do not mask all interrupts in probe
ACPI / video: skip evaluating _DOD when it does not exist
cxlflash: Increase cmd_per_lun for better throughput
crypto: mcryptd - Fix load failure
crypto: cryptd - Assign statesize properly
crypto: ghash-clmulni - Fix load failure
USB: don't free bandwidth_mutex too early
usb: core: hub: hub_port_init lock controller instead of bus
ANDROID: sdcardfs: Fix style issues in macros
ANDROID: sdcardfs: Use seq_puts over seq_printf
ANDROID: sdcardfs: Use to kstrout
ANDROID: sdcardfs: Use pr_[...] instead of printk
ANDROID: sdcardfs: remove unneeded null check
ANDROID: sdcardfs: Fix style issues with comments
ANDROID: sdcardfs: Fix formatting
ANDROID: sdcardfs: correct order of descriptors
fix the deadlock in xt_qtaguid when enable DDEBUG
net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.
Linux 4.4.56
futex: Add missing error handling to FUTEX_REQUEUE_PI
futex: Fix potential use-after-free in FUTEX_REQUEUE_PI
x86/perf: Fix CR4.PCE propagation to use active_mm instead of mm
x86/kasan: Fix boot with KASAN=y and PROFILE_ANNOTATED_BRANCHES=y
fscrypto: lock inode while setting encryption policy
fscrypt: fix renaming and linking special files
net sched actions: decrement module reference count after table flush.
dccp: fix memory leak during tear-down of unsuccessful connection request
dccp/tcp: fix routing redirect race
bridge: drop netfilter fake rtable unconditionally
ipv6: avoid write to a possibly cloned skb
ipv6: make ECMP route replacement less greedy
mpls: Send route delete notifications when router module is unloaded
act_connmark: avoid crashing on malformed nlattrs with null parms
uapi: fix linux/packet_diag.h userspace compilation error
vrf: Fix use-after-free in vrf_xmit
dccp: fix use-after-free in dccp_feat_activate_values
net: fix socket refcounting in skb_complete_tx_timestamp()
net: fix socket refcounting in skb_complete_wifi_ack()
tcp: fix various issues for sockets morphing to listen state
dccp: Unlock sock before calling sk_free()
net: net_enable_timestamp() can be called from irq contexts
net: don't call strlen() on the user buffer in packet_bind_spkt()
l2tp: avoid use-after-free caused by l2tp_ip_backlog_recv
ipv4: mask tos for input route
vti6: return GRE_KEY for vti6
vxlan: correctly validate VXLAN ID against VXLAN_N_VID
netlink: remove mmapped netlink support
ANDROID: mmc: core: export emmc revision
BACKPORT: mmc: core: Export device lifetime information through sysfs
ANDROID: android-verity: do not compile as independent module
ANDROID: sched: fix duplicate sched_group_energy const specifiers
config: disable CONFIG_USELIB and CONFIG_FHANDLE
ANDROID: power: align wakeup_sources format
ANDROID: dm: android-verity: allow disable dm-verity for Treble VTS
uid_sys_stats: change to use rt_mutex
ANDROID: vfs: user permission2 in notify_change2
ANDROID: sdcardfs: Fix gid issue
ANDROID: sdcardfs: Use tabs instead of spaces in multiuser.h
ANDROID: sdcardfs: Remove uninformative prints
ANDROID: sdcardfs: move path_put outside of spinlock
ANDROID: sdcardfs: Use case insensitive hash function
ANDROID: sdcardfs: declare MODULE_ALIAS_FS
ANDROID: sdcardfs: Get the blocksize from the lower fs
ANDROID: sdcardfs: Use d_invalidate instead of drop_recurisve
ANDROID: sdcardfs: Switch to internal case insensitive compare
ANDROID: sdcardfs: Use spin_lock_nested
ANDROID: sdcardfs: Replace get/put with d_lock
ANDROID: sdcardfs: rate limit warning print
ANDROID: sdcardfs: Fix case insensitive lookup
ANDROID: uid_sys_stats: account for fsync syscalls
ANDROID: sched: add a counter to track fsync
ANDROID: uid_sys_stats: fix negative write bytes.
ANDROID: uid_sys_stats: allow writing same state
ANDROID: uid_sys_stats: rename uid_cputime.c to uid_sys_stats.c
ANDROID: uid_cputime: add per-uid IO usage accounting
DTB: Add EAS compatible Juno Energy model to 'juno.dts'
arm64: dts: juno: Add idle-states to device tree
ANDROID: Replace spaces by '_' for some android filesystem tracepoints.
usb: gadget: f_accessory: Fix for UsbAccessory clean unbind.
android: binder: move global binder state into context struct.
android: binder: add padding to binder_fd_array_object.
binder: use group leader instead of open thread
nf: IDLETIMER: Use fullsock when querying uid
nf: IDLETIMER: Fix use after free condition during work
ANDROID: dm: android-verity: fix table_make_digest() error handling
ANDROID: usb: gadget: function: Fix commenting style
cpufreq: interactive governor drops bits in time calculation
ANDROID: sdcardfs: support direct-IO (DIO) operations
ANDROID: sdcardfs: implement vm_ops->page_mkwrite
ANDROID: sdcardfs: Don't bother deleting freelist
ANDROID: sdcardfs: Add missing path_put
ANDROID: sdcardfs: Fix incorrect hash
ANDROID: ext4 crypto: Disables zeroing on truncation when there's no key
ANDROID: ext4: add a non-reversible key derivation method
ANDROID: ext4: allow encrypting filenames using HEH algorithm
ANDROID: arm64/crypto: add ARMv8-CE optimized poly_hash algorithm
ANDROID: crypto: heh - factor out poly_hash algorithm
ANDROID: crypto: heh - Add Hash-Encrypt-Hash (HEH) algorithm
ANDROID: crypto: gf128mul - Add ble multiplication functions
ANDROID: crypto: gf128mul - Refactor gf128 overflow macros and tables
UPSTREAM: crypto: gf128mul - Zero memory when freeing multiplication table
ANDROID: crypto: shash - Add crypto_grab_shash() and crypto_spawn_shash_alg()
ANDROID: crypto: allow blkcipher walks over ablkcipher data
UPSTREAM: arm/arm64: crypto: assure that ECB modes don't require an IV
ANDROID: Refactor fs readpage/write tracepoints.
ANDROID: export security_path_chown
Squashfs: optimize reading uncompressed data
Squashfs: implement .readpages()
Squashfs: replace buffer_head with BIO
Squashfs: refactor page_actor
Squashfs: remove the FILE_CACHE option
ANDROID: android-recommended.cfg: CONFIG_CPU_SW_DOMAIN_PAN=y
FROMLIST: 9p: fix a potential acl leak
BACKPORT: posix_acl: Clear SGID bit when setting file permissions
UPSTREAM: udp: properly support MSG_PEEK with truncated buffers
UPSTREAM: arm64: Allow hw watchpoint of length 3,5,6 and 7
BACKPORT: arm64: hw_breakpoint: Handle inexact watchpoint addresses
UPSTREAM: arm64: Allow hw watchpoint at varied offset from base address
BACKPORT: hw_breakpoint: Allow watchpoint of length 3,5,6 and 7
ANDROID: sdcardfs: Switch strcasecmp for internal call
ANDROID: sdcardfs: switch to full_name_hash and qstr
ANDROID: sdcardfs: Add GID Derivation to sdcardfs
ANDROID: sdcardfs: Remove redundant operation
ANDROID: sdcardfs: add support for user permission isolation
ANDROID: sdcardfs: Refactor configfs interface
ANDROID: sdcardfs: Allow non-owners to touch
ANDROID: binder: fix format specifier for type binder_size_t
ANDROID: fs: Export vfs_rmdir2
ANDROID: fs: Export free_fs_struct and set_fs_pwd
BACKPORT: Input: xpad - validate USB endpoint count during probe
BACKPORT: Input: xpad - fix oops when attaching an unknown Xbox One gamepad
ANDROID: mnt: remount should propagate to slaves of slaves
ANDROID: sdcardfs: Switch ->d_inode to d_inode()
ANDROID: sdcardfs: Fix locking issue with permision fix up
ANDROID: sdcardfs: Change magic value
ANDROID: sdcardfs: Use per mount permissions
ANDROID: sdcardfs: Add gid and mask to private mount data
ANDROID: sdcardfs: User new permission2 functions
ANDROID: vfs: Add setattr2 for filesystems with per mount permissions
ANDROID: vfs: Add permission2 for filesystems with per mount permissions
ANDROID: vfs: Allow filesystems to access their private mount data
ANDROID: mnt: Add filesystem private data to mount points
ANDROID: sdcardfs: Move directory unlock before touch
ANDROID: sdcardfs: fix external storage exporting incorrect uid
ANDROID: sdcardfs: Added top to sdcardfs_inode_info
ANDROID: sdcardfs: Switch package list to RCU
ANDROID: sdcardfs: Fix locking for permission fix up
ANDROID: sdcardfs: Check for other cases on path lookup
ANDROID: sdcardfs: override umask on mkdir and create
arm64: kernel: Fix build warning
DEBUG: sched/fair: Fix sched_load_avg_cpu events for task_groups
DEBUG: sched/fair: Fix missing sched_load_avg_cpu events
UPSTREAM: l2tp: fix racy SOCK_ZAPPED flag check in l2tp_ip{,6}_bind()
UPSTREAM: packet: fix race condition in packet_set_ring
UPSTREAM: netlink: Fix dump skb leak/double free
UPSTREAM: net: avoid signed overflows for SO_{SND|RCV}BUFFORCE
MIPS: Prevent "restoration" of MSA context in non-MSA kernels
net: socket: don't set sk_uid to garbage value in ->setattr()
ANDROID: configs: CONFIG_ARM64_SW_TTBR0_PAN=y
UPSTREAM: arm64: Disable PAN on uaccess_enable()
UPSTREAM: arm64: Enable CONFIG_ARM64_SW_TTBR0_PAN
UPSTREAM: arm64: xen: Enable user access before a privcmd hvc call
UPSTREAM: arm64: Handle faults caused by inadvertent user access with PAN enabled
BACKPORT: arm64: Disable TTBR0_EL1 during normal kernel execution
BACKPORT: arm64: Introduce uaccess_{disable,enable} functionality based on TTBR0_EL1
BACKPORT: arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro
BACKPORT: arm64: Factor out PAN enabling/disabling into separate uaccess_* macros
UPSTREAM: arm64: alternative: add auto-nop infrastructure
UPSTREAM: arm64: barriers: introduce nops and __nops macros for NOP sequences
Revert "FROMLIST: arm64: Factor out PAN enabling/disabling into separate uaccess_* macros"
Revert "FROMLIST: arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro"
Revert "FROMLIST: arm64: Introduce uaccess_{disable,enable} functionality based on TTBR0_EL1"
Revert "FROMLIST: arm64: Disable TTBR0_EL1 during normal kernel execution"
Revert "FROMLIST: arm64: Handle faults caused by inadvertent user access with PAN enabled"
Revert "FROMLIST: arm64: xen: Enable user access before a privcmd hvc call"
Revert "FROMLIST: arm64: Enable CONFIG_ARM64_SW_TTBR0_PAN"
ANDROID: sched/walt: fix build failure if FAIR_GROUP_SCHED=n
ANDROID: trace: net: use %pK for kernel pointers
ANDROID: android-base: Enable QUOTA related configs
net: ipv4: Don't crash if passing a null sk to ip_rt_update_pmtu.
net: inet: Support UID-based routing in IP protocols.
net: core: add UID to flows, rules, and routes
net: core: Add a UID field to struct sock.
Revert "net: core: Support UID-based routing."
UPSTREAM: efi/arm64: Don't apply MEMBLOCK_NOMAP to UEFI memory map mapping
UPSTREAM: arm64: mm: always take dirty state from new pte in ptep_set_access_flags
UPSTREAM: arm64: Implement pmdp_set_access_flags() for hardware AF/DBM
UPSTREAM: arm64: Fix typo in the pmdp_huge_get_and_clear() definition
UPSTREAM: arm64: enable CONFIG_DEBUG_RODATA by default
goldfish: enable CONFIG_INET_DIAG_DESTROY
sched/walt: kill {min,max}_capacity
sched: fix wrong truncation of walt_avg
build: fix build config kernel_dir
ANDROID: dm verity: add minimum prefetch size
build: add build server configs for goldfish
usb: gadget: Fix compilation problem with tx_qlen field
Conflicts:
android/configs/android-base.cfg
arch/arm64/Makefile
arch/arm64/include/asm/cpufeature.h
arch/arm64/kernel/vdso/gettimeofday.S
arch/arm64/mm/cache.S
drivers/md/Kconfig
drivers/misc/Makefile
drivers/mmc/host/sdhci.c
drivers/usb/core/hcd.c
drivers/usb/gadget/function/u_ether.c
fs/sdcardfs/derived_perm.c
fs/sdcardfs/file.c
fs/sdcardfs/inode.c
fs/sdcardfs/lookup.c
fs/sdcardfs/main.c
fs/sdcardfs/multiuser.h
fs/sdcardfs/packagelist.c
fs/sdcardfs/sdcardfs.h
fs/sdcardfs/super.c
include/linux/mmc/card.h
include/linux/mmc/mmc.h
include/trace/events/android_fs.h
include/trace/events/android_fs_template.h
drivers/android/binder.c
fs/exec.c
fs/ext4/crypto_key.c
fs/ext4/ext4.h
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/readpage.c
fs/f2fs/data.c
fs/f2fs/inline.c
fs/mpage.c
include/linux/dcache.h
include/trace/events/sched.h
include/uapi/linux/ipv6.h
net/ipv4/tcp_ipv4.c
net/netfilter/xt_IDLETIMER.c
Change-Id: Ie345db6a14869fe0aa794aef4b71b5d0d503690b
Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
2017-04-12 12:19:15 -07:00
|
|
|
res = ext4_derive_key(&ctx, master_key->raw,
|
2016-09-13 18:45:47 +03:00
|
|
|
crypt_info->ci_raw_key);
|
2015-12-10 00:57:58 -05:00
|
|
|
up_read(&keyring_key->sem);
|
2015-07-22 00:08:08 -04:00
|
|
|
if (res)
|
|
|
|
goto out;
|
2015-05-31 13:34:22 -04:00
|
|
|
got_key:
|
2016-09-13 18:45:47 +03:00
|
|
|
if (for_fname ||
|
|
|
|
(crypt_info->ci_data_mode != EXT4_ENCRYPTION_MODE_PRIVATE)) {
|
|
|
|
ctfm = crypto_alloc_ablkcipher(cipher_str, 0, 0);
|
|
|
|
if (!ctfm || IS_ERR(ctfm)) {
|
|
|
|
res = ctfm ? PTR_ERR(ctfm) : -ENOMEM;
|
|
|
|
pr_debug("%s: error %d (inode %u) allocating crypto tfm\n",
|
|
|
|
__func__, res, (unsigned) inode->i_ino);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
crypt_info->ci_ctfm = ctfm;
|
|
|
|
crypto_ablkcipher_clear_flags(ctfm, ~0);
|
|
|
|
crypto_tfm_set_flags(crypto_ablkcipher_tfm(ctfm),
|
|
|
|
CRYPTO_TFM_REQ_WEAK_KEY);
|
|
|
|
res = crypto_ablkcipher_setkey(ctfm, crypt_info->ci_raw_key,
|
|
|
|
ext4_encryption_key_size(mode));
|
|
|
|
if (res)
|
|
|
|
goto out;
|
|
|
|
memzero_explicit(crypt_info->ci_raw_key,
|
|
|
|
sizeof(crypt_info->ci_raw_key));
|
|
|
|
} else if (!ext4_is_ice_enabled()) {
|
|
|
|
pr_warn("%s: ICE support not available\n",
|
|
|
|
__func__);
|
|
|
|
res = -EINVAL;
|
2015-05-31 13:34:22 -04:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) != NULL) {
|
|
|
|
ext4_free_crypt_info(crypt_info);
|
|
|
|
goto retry;
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
}
|
2015-05-31 13:34:22 -04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (res == -ENOKEY)
|
|
|
|
res = 0;
|
2016-09-13 18:45:47 +03:00
|
|
|
memzero_explicit(crypt_info->ci_raw_key,
|
|
|
|
sizeof(crypt_info->ci_raw_key));
|
2015-05-31 13:34:22 -04:00
|
|
|
ext4_free_crypt_info(crypt_info);
|
2015-04-12 00:55:06 -04:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ext4_has_encryption_key(struct inode *inode)
|
|
|
|
{
|
|
|
|
struct ext4_inode_info *ei = EXT4_I(inode);
|
|
|
|
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-18 13:17:47 -04:00
|
|
|
return (ei->i_crypt_info != NULL);
|
2015-04-12 00:55:06 -04:00
|
|
|
}
|