vold: Adapt req-crypt based HW disk encryption

dm-req-crypt driver is not yet tested/adapted to libdm
interfaces so enable req-crypt based HW disk encryption without
libdm. Drop the older APIs once dm-req-crypt driver is tested
for latest user interface based on libdm.

CRs-Fixed: 2530207
Change-Id: Id80a7d98f29bcb5e0dba1aa92f84c594cfad67ae
Signed-off-by: Neeraj Soni <neersoni@codeaurora.org>
gugelfrei
Neeraj Soni 5 years ago committed by Michael Bestas
parent cfc92293f8
commit 740377dda5

@ -71,6 +71,8 @@
#include <thread>
#ifdef CONFIG_HW_DISK_ENCRYPTION
#include <linux/dm-ioctl.h>
#include <sys/ioctl.h>
#include <cryptfs_hw.h>
#endif
extern "C" {
@ -1228,6 +1230,171 @@ static int add_sector_size_param(DmTargetCrypt* target, struct crypt_mnt_ftr* ft
return 0;
}
#if defined(CONFIG_HW_DISK_ENCRYPTION) && !defined(CONFIG_HW_DISK_ENCRYPT_PERF)
#define DM_CRYPT_BUF_SIZE 4096
static void ioctl_init(struct dm_ioctl* io, size_t dataSize, const char* name, unsigned flags) {
memset(io, 0, dataSize);
io->data_size = dataSize;
io->data_start = sizeof(struct dm_ioctl);
io->version[0] = 4;
io->version[1] = 0;
io->version[2] = 0;
io->flags = flags;
if (name) {
strlcpy(io->name, name, sizeof(io->name));
}
}
static int load_crypto_mapping_table(struct crypt_mnt_ftr* crypt_ftr,
const unsigned char* master_key, const char* real_blk_name,
const char* name, int fd, const char* extra_params) {
alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
struct dm_ioctl* io;
struct dm_target_spec* tgt;
char* crypt_params;
// We need two ASCII characters to represent each byte, and need space for
// the '\0' terminator.
char master_key_ascii[MAX_KEY_LEN * 2 + 1];
size_t buff_offset;
int i;
io = (struct dm_ioctl*)buffer;
/* Load the mapping table for this device */
tgt = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
io->target_count = 1;
tgt->status = 0;
tgt->sector_start = 0;
tgt->length = crypt_ftr->fs_size;
crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
buff_offset = crypt_params - buffer;
SLOGI(
"Creating crypto dev \"%s\"; cipher=%s, keysize=%u, real_dev=%s, len=%llu, params=\"%s\"\n",
name, crypt_ftr->crypto_type_name, crypt_ftr->keysize, real_blk_name, tgt->length * 512,
extra_params);
if(is_hw_disk_encryption((char*)crypt_ftr->crypto_type_name)) {
strlcpy(tgt->target_type, "req-crypt",DM_MAX_TYPE_NAME);
if (is_ice_enabled())
convert_key_to_hex_ascii(master_key, sizeof(int), master_key_ascii);
else
convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
}
snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s 0",
crypt_ftr->crypto_type_name, master_key_ascii,
real_blk_name, extra_params);
SLOGI("target_type = %s", tgt->target_type);
SLOGI("real_blk_name = %s, extra_params = %s", real_blk_name, extra_params);
crypt_params += strlen(crypt_params) + 1;
crypt_params =
(char*)(((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
tgt->next = crypt_params - buffer;
for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
if (!ioctl(fd, DM_TABLE_LOAD, io)) {
break;
}
usleep(500000);
}
if (i == TABLE_LOAD_RETRIES) {
/* We failed to load the table, return an error */
return -1;
} else {
return i + 1;
}
}
static int create_crypto_blk_dev_hw(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
const char* real_blk_name, char* crypto_blk_name, const char* name,
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;
char encrypted_state[PROPERTY_VALUE_MAX] = {0};
char progress[PROPERTY_VALUE_MAX] = {0};
const char *extra_params;
if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Cannot open device-mapper\n");
goto errout;
}
io = (struct dm_ioctl*)buffer;
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
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);
if (ioctl(fd, DM_DEV_STATUS, io)) {
SLOGE("Cannot retrieve dm-crypt device status\n");
goto errout;
}
minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
if(is_hw_disk_encryption((char*)crypt_ftr->crypto_type_name)) {
/* Set fde_enabled if either FDE completed or in-progress */
property_get("ro.crypto.state", encrypted_state, ""); /* FDE completed */
property_get("vold.encrypt_progress", progress, ""); /* FDE in progress */
if (!strcmp(encrypted_state, "encrypted") || strcmp(progress, "")) {
if (is_ice_enabled()) {
extra_params = "fde_enabled ice allow_encrypt_override";
} else {
extra_params = "fde_enabled allow_encrypt_override";
}
} else {
extra_params = "fde_enabled allow_encrypt_override";
}
load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd,
extra_params);
}
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 */
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
if (ioctl(fd, DM_DEV_SUSPEND, io)) {
SLOGE("Cannot resume the dm-crypt device\n");
goto errout;
}
/* Ensure the dm device has been created before returning. */
if (android::vold::WaitForFile(crypto_blk_name, 1s) < 0) {
// WaitForFile generates a suitable log message
goto errout;
}
/* We made it here with no errors. Woot! */
retval = 0;
errout:
close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
return retval;
}
#endif
static int create_crypto_blk_dev(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
const char* real_blk_name, std::string* crypto_blk_name,
const char* name, uint32_t flags) {
@ -1941,7 +2108,8 @@ static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
{
/* Allocate enough space for a 256 bit key, but we may use less */
unsigned char decrypted_master_key[32];
char crypto_blkdev[MAXPATHLEN];
char crypto_blkdev_hw[MAXPATHLEN];
std::string crypto_blkdev;
std::string real_blkdev;
unsigned int orig_failed_decrypt_count;
int rc = 0;
@ -1961,8 +2129,8 @@ static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
else {
if (is_ice_enabled()) {
#ifndef CONFIG_HW_DISK_ENCRYPT_PERF
if (create_crypto_blk_dev(crypt_ftr, (unsigned char*)&key_index,
real_blkdev.c_str(), crypto_blkdev, label, 0)) {
if (create_crypto_blk_dev_hw(crypt_ftr, (unsigned char*)&key_index,
real_blkdev.c_str(), crypto_blkdev_hw, label, 0)) {
SLOGE("Error creating decrypted block device");
rc = -1;
goto errout;
@ -1970,7 +2138,7 @@ static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
#endif
} else {
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key,
real_blkdev.c_str(), crypto_blkdev, label, 0)) {
real_blkdev.c_str(), &crypto_blkdev, label, 0)) {
SLOGE("Error creating decrypted block device");
rc = -1;
goto errout;
@ -1989,8 +2157,10 @@ static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
* so we can mount it when restarting the framework. */
#ifdef CONFIG_HW_DISK_ENCRYPT_PERF
if (!is_ice_enabled())
#endif
property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev_hw);
#else
property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
#endif
master_key_saved = 1;
}
@ -2743,7 +2913,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
#ifdef CONFIG_HW_DISK_ENCRYPT_PERF
crypto_blkdev = real_blkdev;
#else
create_crypto_blk_dev(&crypt_ftr, (unsigned char*)&key_index, real_blkdev.c_str(), crypto_blkdev,
create_crypto_blk_dev_hw(&crypt_ftr, (unsigned char*)&key_index, real_blkdev.c_str(), &crypto_blkdev,
CRYPTO_BLOCK_DEVICE, 0);
#endif
else

Loading…
Cancel
Save