Support metadata encryption
Bug: 29189559 Test: Angler, Marlin build and boot Change-Id: Ia7b070781f5f16ff8bfd934569a2209c80c28385
This commit is contained in:
parent
1395aac313
commit
9dbe97b4d5
|
@ -721,6 +721,12 @@ static bool needs_block_encryption(const struct fstab_rec* rec)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool should_use_metadata_encryption(const struct fstab_rec* rec) {
|
||||
if (!(rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE))) return false;
|
||||
if (!(rec->fs_mgr_flags & MF_KEYDIRECTORY)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check to see if a mountable volume has encryption requirements
|
||||
static int handle_encryptable(const struct fstab_rec* rec)
|
||||
{
|
||||
|
@ -733,8 +739,14 @@ static int handle_encryptable(const struct fstab_rec* rec)
|
|||
<< " - allow continue unencrypted";
|
||||
return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
|
||||
}
|
||||
} else if (should_use_metadata_encryption(rec)) {
|
||||
if (umount(rec->mount_point) == 0) {
|
||||
return FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION;
|
||||
} else {
|
||||
PERROR << "Could not umount " << rec->mount_point << " - fail since can't encrypt";
|
||||
return FS_MGR_MNTALL_FAIL;
|
||||
}
|
||||
} else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) {
|
||||
// Deal with file level encryption
|
||||
LINFO << rec->mount_point << " is file encrypted";
|
||||
return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
|
||||
} else if (fs_mgr_is_encryptable(rec)) {
|
||||
|
@ -900,7 +912,6 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* mount(2) returned an error, handle the encryptable/formattable case */
|
||||
bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
|
||||
bool crypt_footer = false;
|
||||
if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
|
||||
|
@ -940,6 +951,8 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* mount(2) returned an error, handle the encryptable/formattable case */
|
||||
if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
|
||||
fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
|
||||
if (wiped) {
|
||||
|
@ -965,6 +978,9 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
|
|||
}
|
||||
}
|
||||
encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
|
||||
} else if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
|
||||
should_use_metadata_encryption(&fstab->recs[attempted_idx])) {
|
||||
encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
|
||||
} else {
|
||||
if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
|
||||
PERROR << "Ignoring failure to mount an un-encryptable or wiped partition on"
|
||||
|
@ -1256,48 +1272,46 @@ int fs_mgr_swapon_all(struct fstab *fstab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* key_loc must be at least PROPERTY_VALUE_MAX bytes long
|
||||
*
|
||||
* real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
|
||||
*/
|
||||
int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
|
||||
{
|
||||
int i = 0;
|
||||
struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab) {
|
||||
int i;
|
||||
|
||||
if (!fstab) {
|
||||
return -1;
|
||||
}
|
||||
/* Initialize return values to null strings */
|
||||
if (key_loc) {
|
||||
*key_loc = '\0';
|
||||
}
|
||||
if (real_blk_device) {
|
||||
*real_blk_device = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for the encryptable partition to find the data */
|
||||
for (i = 0; i < fstab->num_entries; i++) {
|
||||
/* Don't deal with vold managed enryptable partitions here */
|
||||
if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
|
||||
continue;
|
||||
if (!(fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) &&
|
||||
(fstab->recs[i].fs_mgr_flags &
|
||||
(MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE | MF_FILEENCRYPTION))) {
|
||||
return &fstab->recs[i];
|
||||
}
|
||||
if (!(fstab->recs[i].fs_mgr_flags
|
||||
& (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We found a match */
|
||||
if (key_loc) {
|
||||
strlcpy(key_loc, fstab->recs[i].key_loc, size);
|
||||
}
|
||||
if (real_blk_device) {
|
||||
strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* key_loc must be at least PROPERTY_VALUE_MAX bytes long
|
||||
*
|
||||
* real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
|
||||
*/
|
||||
void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size) {
|
||||
struct fstab_rec const* rec = fs_mgr_get_crypt_entry(fstab);
|
||||
if (key_loc) {
|
||||
if (rec) {
|
||||
strlcpy(key_loc, rec->key_loc, size);
|
||||
} else {
|
||||
*key_loc = '\0';
|
||||
}
|
||||
}
|
||||
if (real_blk_device) {
|
||||
if (rec) {
|
||||
strlcpy(real_blk_device, rec->blk_device, size);
|
||||
} else {
|
||||
*real_blk_device = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool fs_mgr_load_verity_state(int* mode) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
struct fs_mgr_flag_values {
|
||||
char *key_loc;
|
||||
char* key_dir;
|
||||
char *verity_loc;
|
||||
long long part_length;
|
||||
char *label;
|
||||
|
@ -70,34 +71,35 @@ static struct flag_list mount_flags[] = {
|
|||
};
|
||||
|
||||
static struct flag_list fs_mgr_flags[] = {
|
||||
{ "wait", MF_WAIT },
|
||||
{ "check", MF_CHECK },
|
||||
{ "encryptable=", MF_CRYPT },
|
||||
{ "forceencrypt=", MF_FORCECRYPT },
|
||||
{ "fileencryption=", MF_FILEENCRYPTION },
|
||||
{ "forcefdeorfbe=", MF_FORCEFDEORFBE },
|
||||
{ "nonremovable", MF_NONREMOVABLE },
|
||||
{ "voldmanaged=", MF_VOLDMANAGED},
|
||||
{ "length=", MF_LENGTH },
|
||||
{ "recoveryonly", MF_RECOVERYONLY },
|
||||
{ "swapprio=", MF_SWAPPRIO },
|
||||
{ "zramsize=", MF_ZRAMSIZE },
|
||||
{ "max_comp_streams=", MF_MAX_COMP_STREAMS },
|
||||
{ "verifyatboot", MF_VERIFYATBOOT },
|
||||
{ "verify", MF_VERIFY },
|
||||
{ "avb", MF_AVB },
|
||||
{ "noemulatedsd", MF_NOEMULATEDSD },
|
||||
{ "notrim", MF_NOTRIM },
|
||||
{ "formattable", MF_FORMATTABLE },
|
||||
{ "slotselect", MF_SLOTSELECT },
|
||||
{ "nofail", MF_NOFAIL },
|
||||
{ "latemount", MF_LATEMOUNT },
|
||||
{ "reservedsize=", MF_RESERVEDSIZE },
|
||||
{ "quota", MF_QUOTA },
|
||||
{ "eraseblk=", MF_ERASEBLKSIZE },
|
||||
{ "logicalblk=", MF_LOGICALBLKSIZE },
|
||||
{ "defaults", 0 },
|
||||
{ 0, 0 },
|
||||
{"wait", MF_WAIT},
|
||||
{"check", MF_CHECK},
|
||||
{"encryptable=", MF_CRYPT},
|
||||
{"forceencrypt=", MF_FORCECRYPT},
|
||||
{"fileencryption=", MF_FILEENCRYPTION},
|
||||
{"forcefdeorfbe=", MF_FORCEFDEORFBE},
|
||||
{"keydirectory=", MF_KEYDIRECTORY},
|
||||
{"nonremovable", MF_NONREMOVABLE},
|
||||
{"voldmanaged=", MF_VOLDMANAGED},
|
||||
{"length=", MF_LENGTH},
|
||||
{"recoveryonly", MF_RECOVERYONLY},
|
||||
{"swapprio=", MF_SWAPPRIO},
|
||||
{"zramsize=", MF_ZRAMSIZE},
|
||||
{"max_comp_streams=", MF_MAX_COMP_STREAMS},
|
||||
{"verifyatboot", MF_VERIFYATBOOT},
|
||||
{"verify", MF_VERIFY},
|
||||
{"avb", MF_AVB},
|
||||
{"noemulatedsd", MF_NOEMULATEDSD},
|
||||
{"notrim", MF_NOTRIM},
|
||||
{"formattable", MF_FORMATTABLE},
|
||||
{"slotselect", MF_SLOTSELECT},
|
||||
{"nofail", MF_NOFAIL},
|
||||
{"latemount", MF_LATEMOUNT},
|
||||
{"reservedsize=", MF_RESERVEDSIZE},
|
||||
{"quota", MF_QUOTA},
|
||||
{"eraseblk=", MF_ERASEBLKSIZE},
|
||||
{"logicalblk=", MF_LOGICALBLKSIZE},
|
||||
{"defaults", 0},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
#define EM_AES_256_XTS 1
|
||||
|
@ -266,6 +268,11 @@ static int parse_flags(char *flags, struct flag_list *fl,
|
|||
} else {
|
||||
flag_vals->file_names_mode = EM_AES_256_CTS;
|
||||
}
|
||||
} else if ((fl[i].flag == MF_KEYDIRECTORY) && flag_vals) {
|
||||
/* The metadata flag is followed by an = and the
|
||||
* directory for the keys. Get it and return it.
|
||||
*/
|
||||
flag_vals->key_dir = strdup(strchr(p, '=') + 1);
|
||||
} else if ((fl[i].flag == MF_LENGTH) && flag_vals) {
|
||||
/* The length flag is followed by an = and the
|
||||
* size of the partition. Get it and return it.
|
||||
|
@ -557,6 +564,7 @@ static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
|
|||
fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
|
||||
&flag_vals, NULL, 0);
|
||||
fstab->recs[cnt].key_loc = flag_vals.key_loc;
|
||||
fstab->recs[cnt].key_dir = flag_vals.key_dir;
|
||||
fstab->recs[cnt].verity_loc = flag_vals.verity_loc;
|
||||
fstab->recs[cnt].length = flag_vals.part_length;
|
||||
fstab->recs[cnt].label = flag_vals.label;
|
||||
|
@ -716,6 +724,7 @@ void fs_mgr_free_fstab(struct fstab *fstab)
|
|||
free(fstab->recs[i].fs_type);
|
||||
free(fstab->recs[i].fs_options);
|
||||
free(fstab->recs[i].key_loc);
|
||||
free(fstab->recs[i].key_dir);
|
||||
free(fstab->recs[i].label);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
#define MF_ERASEBLKSIZE 0x800000
|
||||
#define MF_LOGICALBLKSIZE 0X1000000
|
||||
#define MF_AVB 0X2000000
|
||||
#define MF_KEYDIRECTORY 0X4000000
|
||||
|
||||
#define DM_BUF_SIZE 4096
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ struct fstab_rec {
|
|||
char *fs_options;
|
||||
int fs_mgr_flags;
|
||||
char *key_loc;
|
||||
char* key_dir;
|
||||
char *verity_loc;
|
||||
long long length;
|
||||
char *label;
|
||||
|
@ -95,6 +96,8 @@ struct fstab *fs_mgr_read_fstab_dt();
|
|||
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
|
||||
void fs_mgr_free_fstab(struct fstab *fstab);
|
||||
|
||||
#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7
|
||||
#define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6
|
||||
#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
|
||||
#define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 4
|
||||
#define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 3
|
||||
|
@ -112,8 +115,8 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
|
|||
int fs_mgr_do_mount_one(struct fstab_rec *rec);
|
||||
int fs_mgr_do_tmpfs_mount(const char *n_name);
|
||||
int fs_mgr_unmount_all(struct fstab *fstab);
|
||||
int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc,
|
||||
char *real_blk_device, int size);
|
||||
struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab);
|
||||
void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size);
|
||||
bool fs_mgr_load_verity_state(int* mode);
|
||||
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
|
||||
int fs_mgr_add_entry(struct fstab *fstab,
|
||||
|
|
|
@ -481,6 +481,23 @@ static int queue_fs_event(int code) {
|
|||
// Although encrypted, we have device key, so we do not need to
|
||||
// do anything different from the nonencrypted case.
|
||||
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
|
||||
} else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
|
||||
if (e4crypt_install_keyring()) {
|
||||
return -1;
|
||||
}
|
||||
property_set("ro.crypto.state", "encrypted");
|
||||
property_set("ro.crypto.type", "file");
|
||||
|
||||
// defaultcrypto detects file/block encryption. init flow is same for each.
|
||||
ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
|
||||
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
|
||||
if (e4crypt_install_keyring()) {
|
||||
return -1;
|
||||
}
|
||||
property_set("ro.crypto.type", "file");
|
||||
|
||||
// encrypt detects file/block encryption. init flow is same for each.
|
||||
ActionManager::GetInstance().QueueEventTrigger("encrypt");
|
||||
} else if (code > 0) {
|
||||
PLOG(ERROR) << "fs_mgr_mount_all returned unexpected error " << code;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue