No double encryption on FDE+FBE SD cards
On FBE systems, adoptable storage uses both file-based encryption (for per-user protection) and full disk encryption (for metadata protection). For performance/battery reasons, we don't want to encrypt the same data twice; to that end, ensure that the allow_encrypt_override flag is sent to dm_crypt. Bug: 25861755 Test: see ag/3247969 Change-Id: Ib0c5891ab2d2ee9007e27a50254d29fc867d7bc5
This commit is contained in:
parent
130a994f4f
commit
5afbc6276d
1 changed files with 76 additions and 64 deletions
140
cryptfs.cpp
140
cryptfs.cpp
|
@ -96,6 +96,8 @@ extern "C" {
|
||||||
#define RETRY_MOUNT_ATTEMPTS 10
|
#define RETRY_MOUNT_ATTEMPTS 10
|
||||||
#define RETRY_MOUNT_DELAY_SECONDS 1
|
#define RETRY_MOUNT_DELAY_SECONDS 1
|
||||||
|
|
||||||
|
#define CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE (1)
|
||||||
|
|
||||||
static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr);
|
static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr);
|
||||||
|
|
||||||
static unsigned char saved_master_key[KEY_LEN_BYTES];
|
static unsigned char saved_master_key[KEY_LEN_BYTES];
|
||||||
|
@ -864,6 +866,7 @@ static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr,
|
||||||
convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
|
convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
|
||||||
|
|
||||||
buff_offset = crypt_params - buffer;
|
buff_offset = crypt_params - buffer;
|
||||||
|
SLOGI("Extra parameters for dm_crypt: %s\n", extra_params);
|
||||||
snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s",
|
snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s",
|
||||||
crypt_ftr->crypto_type_name, master_key_ascii, real_blk_name,
|
crypt_ftr->crypto_type_name, master_key_ascii, real_blk_name,
|
||||||
extra_params);
|
extra_params);
|
||||||
|
@ -919,71 +922,80 @@ static int get_dm_crypt_version(int fd, const char *name, int *version)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr,
|
static std::string extra_params_as_string(const std::vector<std::string>& extra_params_vec) {
|
||||||
const unsigned char *master_key, const char *real_blk_name,
|
if (extra_params_vec.empty()) return "";
|
||||||
char *crypto_blk_name, const char *name) {
|
std::string extra_params = std::to_string(extra_params_vec.size());
|
||||||
char buffer[DM_CRYPT_BUF_SIZE];
|
for (const auto& p : extra_params_vec) {
|
||||||
struct dm_ioctl *io;
|
extra_params.append(" ");
|
||||||
unsigned int minor;
|
extra_params.append(p);
|
||||||
int fd=0;
|
}
|
||||||
int err;
|
return extra_params;
|
||||||
int retval = -1;
|
}
|
||||||
int version[3];
|
|
||||||
const char *extra_params;
|
|
||||||
int load_count;
|
|
||||||
|
|
||||||
if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) {
|
static int create_crypto_blk_dev(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
|
||||||
SLOGE("Cannot open device-mapper\n");
|
const char* real_blk_name, char* crypto_blk_name, const char* name,
|
||||||
goto errout;
|
uint32_t flags) {
|
||||||
}
|
char buffer[DM_CRYPT_BUF_SIZE];
|
||||||
|
struct dm_ioctl* io;
|
||||||
|
unsigned int minor;
|
||||||
|
int fd = 0;
|
||||||
|
int err;
|
||||||
|
int retval = -1;
|
||||||
|
int version[3];
|
||||||
|
int load_count;
|
||||||
|
std::vector<std::string> extra_params_vec;
|
||||||
|
|
||||||
io = (struct dm_ioctl *) buffer;
|
if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
|
||||||
|
SLOGE("Cannot open device-mapper\n");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
io = (struct dm_ioctl*)buffer;
|
||||||
err = ioctl(fd, DM_DEV_CREATE, io);
|
|
||||||
if (err) {
|
|
||||||
SLOGE("Cannot create dm-crypt device %s: %s\n", name, strerror(errno));
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the device status, in particular, the name of it's device file */
|
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
||||||
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
err = ioctl(fd, DM_DEV_CREATE, io);
|
||||||
if (ioctl(fd, DM_DEV_STATUS, io)) {
|
if (err) {
|
||||||
SLOGE("Cannot retrieve dm-crypt device status\n");
|
SLOGE("Cannot create dm-crypt device %s: %s\n", name, strerror(errno));
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
|
|
||||||
snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
|
|
||||||
|
|
||||||
extra_params = "";
|
/* Get the device status, in particular, the name of it's device file */
|
||||||
if (! get_dm_crypt_version(fd, name, version)) {
|
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
||||||
/* Support for allow_discards was added in version 1.11.0 */
|
if (ioctl(fd, DM_DEV_STATUS, io)) {
|
||||||
if ((version[0] >= 2) ||
|
SLOGE("Cannot retrieve dm-crypt device status\n");
|
||||||
((version[0] == 1) && (version[1] >= 11))) {
|
goto errout;
|
||||||
extra_params = "1 allow_discards";
|
}
|
||||||
SLOGI("Enabling support for allow_discards in dmcrypt.\n");
|
minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
|
||||||
}
|
snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
|
||||||
}
|
|
||||||
|
|
||||||
load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name,
|
if (!get_dm_crypt_version(fd, name, version)) {
|
||||||
fd, extra_params);
|
/* Support for allow_discards was added in version 1.11.0 */
|
||||||
if (load_count < 0) {
|
if ((version[0] >= 2) || ((version[0] == 1) && (version[1] >= 11))) {
|
||||||
SLOGE("Cannot load dm-crypt mapping table.\n");
|
extra_params_vec.emplace_back("allow_discards");
|
||||||
goto errout;
|
}
|
||||||
} else if (load_count > 1) {
|
}
|
||||||
SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
|
if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE) {
|
||||||
}
|
extra_params_vec.emplace_back("allow_encrypt_override");
|
||||||
|
}
|
||||||
|
load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd,
|
||||||
|
extra_params_as_string(extra_params_vec).c_str());
|
||||||
|
if (load_count < 0) {
|
||||||
|
SLOGE("Cannot load dm-crypt mapping table.\n");
|
||||||
|
goto errout;
|
||||||
|
} else if (load_count > 1) {
|
||||||
|
SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
|
||||||
|
}
|
||||||
|
|
||||||
/* Resume this device to activate it */
|
/* Resume this device to activate it */
|
||||||
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
||||||
|
|
||||||
if (ioctl(fd, DM_DEV_SUSPEND, io)) {
|
if (ioctl(fd, DM_DEV_SUSPEND, io)) {
|
||||||
SLOGE("Cannot resume the dm-crypt device\n");
|
SLOGE("Cannot resume the dm-crypt device\n");
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We made it here with no errors. Woot! */
|
/* We made it here with no errors. Woot! */
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
|
close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
|
||||||
|
@ -1612,11 +1624,10 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
|
||||||
|
|
||||||
// Create crypto block device - all (non fatal) code paths
|
// Create crypto block device - all (non fatal) code paths
|
||||||
// need it
|
// need it
|
||||||
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key,
|
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, label, 0)) {
|
||||||
real_blkdev, crypto_blkdev, label)) {
|
SLOGE("Error creating decrypted block device\n");
|
||||||
SLOGE("Error creating decrypted block device\n");
|
rc = -1;
|
||||||
rc = -1;
|
goto errout;
|
||||||
goto errout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Work out if the problem is the password or the data */
|
/* Work out if the problem is the password or the data */
|
||||||
|
@ -1744,8 +1755,9 @@ int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
|
||||||
strlcpy((char*) ext_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256",
|
strlcpy((char*) ext_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256",
|
||||||
MAX_CRYPTO_TYPE_NAME_LEN);
|
MAX_CRYPTO_TYPE_NAME_LEN);
|
||||||
|
|
||||||
return create_crypto_blk_dev(&ext_crypt_ftr, key, real_blkdev,
|
return create_crypto_blk_dev(
|
||||||
out_crypto_blkdev, label);
|
&ext_crypt_ftr, key, real_blkdev, out_crypto_blkdev, label,
|
||||||
|
e4crypt_is_native() ? CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2313,7 +2325,7 @@ int cryptfs_enable_internal(const char *howarg, int crypt_type, const char *pass
|
||||||
|
|
||||||
decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
|
decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
|
||||||
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
|
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
|
||||||
CRYPTO_BLOCK_DEVICE);
|
CRYPTO_BLOCK_DEVICE, 0);
|
||||||
|
|
||||||
/* If we are continuing, check checksums match */
|
/* If we are continuing, check checksums match */
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
Loading…
Reference in a new issue