mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-08 09:20:11 +01:00
Support init_by_name for verity.
This commit is contained in:
@@ -256,12 +256,31 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
|
|||||||
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
|
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hex_to_bytes(const char *hex, char *result)
|
||||||
|
{
|
||||||
|
char buf[3] = "xx\0", *endp;
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
len = strlen(hex) / 2;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
memcpy(buf, &hex[i * 2], 2);
|
||||||
|
result[i] = strtoul(buf, &endp, 16);
|
||||||
|
if (endp != &buf[2])
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://code.google.com/p/cryptsetup/wiki/DMCrypt */
|
||||||
static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
|
static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
|
||||||
{
|
{
|
||||||
int r, max_size, null_cipher = 0;
|
int r, max_size, null_cipher = 0;
|
||||||
char *params, *hexkey;
|
char *params, *hexkey;
|
||||||
const char *features = "";
|
const char *features = "";
|
||||||
|
|
||||||
|
if (!dmd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
if (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
||||||
if (dm_flags() & DM_DISCARDS_SUPPORTED) {
|
if (dm_flags() & DM_DISCARDS_SUPPORTED) {
|
||||||
features = " 1 allow_discards";
|
features = " 1 allow_discards";
|
||||||
@@ -283,14 +302,14 @@ static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
|
|||||||
hex_key(hexkey, dmd->u.crypt.vk->keylength, dmd->u.crypt.vk->key);
|
hex_key(hexkey, dmd->u.crypt.vk->keylength, dmd->u.crypt.vk->key);
|
||||||
|
|
||||||
max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) +
|
max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) +
|
||||||
strlen(dmd->u.crypt.device) + strlen(features) + 64;
|
strlen(dmd->data_device) + strlen(features) + 64;
|
||||||
params = crypt_safe_alloc(max_size);
|
params = crypt_safe_alloc(max_size);
|
||||||
if (!params)
|
if (!params)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
|
r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
|
||||||
dmd->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset,
|
dmd->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset,
|
||||||
dmd->u.crypt.device, dmd->u.crypt.offset, features);
|
dmd->data_device, dmd->u.crypt.offset, features);
|
||||||
if (r < 0 || r >= max_size) {
|
if (r < 0 || r >= max_size) {
|
||||||
crypt_safe_free(params);
|
crypt_safe_free(params);
|
||||||
params = NULL;
|
params = NULL;
|
||||||
@@ -299,12 +318,17 @@ out:
|
|||||||
crypt_safe_free(hexkey);
|
crypt_safe_free(hexkey);
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* http://code.google.com/p/cryptsetup/wiki/DMVerity */
|
||||||
static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
||||||
struct crypt_dm_active_device *dmd)
|
struct crypt_dm_active_device *dmd)
|
||||||
{
|
{
|
||||||
int max_size, r;
|
int max_size, r;
|
||||||
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
|
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
|
||||||
|
|
||||||
|
if (!vp || !dmd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
hexroot = crypt_safe_alloc(dmd->u.verity.root_hash_size * 2 + 1);
|
hexroot = crypt_safe_alloc(dmd->u.verity.root_hash_size * 2 + 1);
|
||||||
if (!hexroot)
|
if (!hexroot)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -316,7 +340,7 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
|||||||
hex_key(hexsalt, vp->salt_size, vp->salt);
|
hex_key(hexsalt, vp->salt_size, vp->salt);
|
||||||
|
|
||||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||||
strlen(dmd->u.verity.data_device) +
|
strlen(dmd->data_device) +
|
||||||
strlen(dmd->u.verity.hash_device) +
|
strlen(dmd->u.verity.hash_device) +
|
||||||
strlen(vp->hash_name) + 128;
|
strlen(vp->hash_name) + 128;
|
||||||
|
|
||||||
@@ -326,7 +350,7 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
|||||||
|
|
||||||
r = snprintf(params, max_size,
|
r = snprintf(params, max_size,
|
||||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s",
|
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s",
|
||||||
vp->version, dmd->u.verity.data_device,
|
vp->version, dmd->data_device,
|
||||||
dmd->u.verity.hash_device,
|
dmd->u.verity.hash_device,
|
||||||
vp->data_block_size, vp->hash_block_size,
|
vp->data_block_size, vp->hash_block_size,
|
||||||
vp->data_size, dmd->u.verity.hash_offset,
|
vp->data_size, dmd->u.verity.hash_offset,
|
||||||
@@ -581,7 +605,6 @@ out_no_removal:
|
|||||||
int dm_create_device(const char *name,
|
int dm_create_device(const char *name,
|
||||||
const char *type,
|
const char *type,
|
||||||
struct crypt_dm_active_device *dmd,
|
struct crypt_dm_active_device *dmd,
|
||||||
void *params,
|
|
||||||
int reload)
|
int reload)
|
||||||
{
|
{
|
||||||
char *table_params = NULL;
|
char *table_params = NULL;
|
||||||
@@ -589,12 +612,12 @@ int dm_create_device(const char *name,
|
|||||||
if (dmd->target == DM_CRYPT)
|
if (dmd->target == DM_CRYPT)
|
||||||
table_params = get_dm_crypt_params(dmd);
|
table_params = get_dm_crypt_params(dmd);
|
||||||
else if (dmd->target == DM_VERITY)
|
else if (dmd->target == DM_VERITY)
|
||||||
table_params = get_dm_verity_params(params, dmd);
|
table_params = get_dm_verity_params(dmd->u.verity.vp, dmd);
|
||||||
|
|
||||||
if (!table_params)
|
if (!table_params)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return _dm_create_device(name, type, dmd->u.crypt.device, dmd->flags,
|
return _dm_create_device(name, type, dmd->data_device, dmd->flags,
|
||||||
dmd->uuid, dmd->size, table_params, reload);
|
dmd->uuid, dmd->size, table_params, reload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,10 +649,17 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
|||||||
|
|
||||||
next = dm_get_next_target(dmt, next, &start, &length,
|
next = dm_get_next_target(dmt, next, &start, &length,
|
||||||
&target_type, ¶ms);
|
&target_type, ¶ms);
|
||||||
if (!target_type || strcmp(target_type, target) != 0 ||
|
|
||||||
start != 0 || next)
|
if (!target_type || start != 0 || next)
|
||||||
r = -EINVAL;
|
goto out;
|
||||||
else
|
|
||||||
|
if (target && strcmp(target_type, target))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* for target == NULL check all supported */
|
||||||
|
if (!target && (strcmp(target_type, DM_CRYPT_TARGET) &&
|
||||||
|
strcmp(target_type, DM_VERITY_TARGET)))
|
||||||
|
goto out;
|
||||||
r = 0;
|
r = 0;
|
||||||
out:
|
out:
|
||||||
if (!r && status_line && !(*status_line = strdup(params)))
|
if (!r && status_line && !(*status_line = strdup(params)))
|
||||||
@@ -646,7 +676,7 @@ int dm_status_device(const char *name)
|
|||||||
int r;
|
int r;
|
||||||
struct dm_info dmi;
|
struct dm_info dmi;
|
||||||
|
|
||||||
r = dm_status_dmi(name, &dmi, DM_CRYPT_TARGET, NULL);
|
r = dm_status_dmi(name, &dmi, NULL, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -684,6 +714,7 @@ int dm_status_verity_ok(const char *name)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME use hex wrapper, user val wrappers for line parsing */
|
||||||
static int _dm_query_crypt(uint32_t get_flags,
|
static int _dm_query_crypt(uint32_t get_flags,
|
||||||
struct dm_info *dmi,
|
struct dm_info *dmi,
|
||||||
char *params,
|
char *params,
|
||||||
@@ -693,11 +724,12 @@ static int _dm_query_crypt(uint32_t get_flags,
|
|||||||
char *rcipher, *key_, *rdevice, *endp, buffer[3], *arg;
|
char *rcipher, *key_, *rdevice, *endp, buffer[3], *arg;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
memset(dmd, 0, sizeof(*dmd));
|
||||||
dmd->target = DM_CRYPT;
|
dmd->target = DM_CRYPT;
|
||||||
|
|
||||||
rcipher = strsep(¶ms, " ");
|
rcipher = strsep(¶ms, " ");
|
||||||
/* cipher */
|
/* cipher */
|
||||||
if (get_flags & DM_ACTIVE_CIPHER)
|
if (get_flags & DM_ACTIVE_CRYPT_CIPHER)
|
||||||
dmd->u.crypt.cipher = strdup(rcipher);
|
dmd->u.crypt.cipher = strdup(rcipher);
|
||||||
|
|
||||||
/* skip */
|
/* skip */
|
||||||
@@ -714,7 +746,7 @@ static int _dm_query_crypt(uint32_t get_flags,
|
|||||||
/* device */
|
/* device */
|
||||||
rdevice = strsep(¶ms, " ");
|
rdevice = strsep(¶ms, " ");
|
||||||
if (get_flags & DM_ACTIVE_DEVICE)
|
if (get_flags & DM_ACTIVE_DEVICE)
|
||||||
dmd->u.crypt.device = crypt_lookup_dev(rdevice);
|
dmd->data_device = crypt_lookup_dev(rdevice);
|
||||||
|
|
||||||
/*offset */
|
/*offset */
|
||||||
if (!params)
|
if (!params)
|
||||||
@@ -750,17 +782,17 @@ static int _dm_query_crypt(uint32_t get_flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Never allow to return empty key */
|
/* Never allow to return empty key */
|
||||||
if ((get_flags & DM_ACTIVE_KEY) && dmi->suspended) {
|
if ((get_flags & DM_ACTIVE_CRYPT_KEY) && dmi->suspended) {
|
||||||
log_dbg("Cannot read volume key while suspended.");
|
log_dbg("Cannot read volume key while suspended.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_flags & DM_ACTIVE_KEYSIZE) {
|
if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
|
||||||
dmd->u.crypt.vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL);
|
dmd->u.crypt.vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL);
|
||||||
if (!dmd->u.crypt.vk)
|
if (!dmd->u.crypt.vk)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (get_flags & DM_ACTIVE_KEY) {
|
if (get_flags & DM_ACTIVE_CRYPT_KEY) {
|
||||||
buffer[2] = '\0';
|
buffer[2] = '\0';
|
||||||
for(i = 0; i < dmd->u.crypt.vk->keylength; i++) {
|
for(i = 0; i < dmd->u.crypt.vk->keylength; i++) {
|
||||||
memcpy(buffer, &key_[i * 2], 2);
|
memcpy(buffer, &key_[i * 2], 2);
|
||||||
@@ -783,8 +815,109 @@ static int _dm_query_verity(uint32_t get_flags,
|
|||||||
char *params,
|
char *params,
|
||||||
struct crypt_dm_active_device *dmd)
|
struct crypt_dm_active_device *dmd)
|
||||||
{
|
{
|
||||||
|
struct crypt_params_verity *vp = NULL;
|
||||||
|
uint32_t val32;
|
||||||
|
uint64_t val64;
|
||||||
|
size_t len;
|
||||||
|
char *str, *str2;
|
||||||
|
|
||||||
|
if (get_flags & DM_ACTIVE_VERITY_PARAMS)
|
||||||
|
vp = dmd->u.verity.vp;
|
||||||
|
|
||||||
|
memset(dmd, 0, sizeof(*dmd));
|
||||||
|
|
||||||
dmd->target = DM_VERITY;
|
dmd->target = DM_VERITY;
|
||||||
|
dmd->u.verity.vp = vp;
|
||||||
|
|
||||||
|
/* version */
|
||||||
|
val32 = strtoul(params, ¶ms, 10);
|
||||||
|
if (*params != ' ')
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (vp)
|
||||||
|
vp->version = val32;
|
||||||
|
params++;
|
||||||
|
|
||||||
|
/* data device */
|
||||||
|
str = strsep(¶ms, " ");
|
||||||
|
if (!params)
|
||||||
|
return -EINVAL;
|
||||||
|
if (get_flags & DM_ACTIVE_DEVICE)
|
||||||
|
dmd->data_device = crypt_lookup_dev(str);
|
||||||
|
|
||||||
|
/* hash device */
|
||||||
|
str = strsep(¶ms, " ");
|
||||||
|
if (!params)
|
||||||
|
return -EINVAL;
|
||||||
|
if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE)
|
||||||
|
dmd->u.verity.hash_device = crypt_lookup_dev(str);
|
||||||
|
|
||||||
|
/* data block size*/
|
||||||
|
val32 = strtoul(params, ¶ms, 10);
|
||||||
|
if (*params != ' ')
|
||||||
|
return -EINVAL;
|
||||||
|
if (vp)
|
||||||
|
vp->data_block_size = val32;
|
||||||
|
params++;
|
||||||
|
|
||||||
|
/* hash block size */
|
||||||
|
val32 = strtoul(params, ¶ms, 10);
|
||||||
|
if (*params != ' ')
|
||||||
|
return -EINVAL;
|
||||||
|
if (vp)
|
||||||
|
vp->hash_block_size = val32;
|
||||||
|
params++;
|
||||||
|
|
||||||
|
/* data blocks */
|
||||||
|
val64 = strtoull(params, ¶ms, 10);
|
||||||
|
if (*params != ' ')
|
||||||
|
return -EINVAL;
|
||||||
|
if (vp)
|
||||||
|
vp->data_size = val64;
|
||||||
|
params++;
|
||||||
|
|
||||||
|
/* hash start */
|
||||||
|
val64 = strtoull(params, ¶ms, 10);
|
||||||
|
if (*params != ' ')
|
||||||
|
return -EINVAL;
|
||||||
|
dmd->u.verity.hash_offset = val64;
|
||||||
|
params++;
|
||||||
|
|
||||||
|
/* hash algorithm */
|
||||||
|
str = strsep(¶ms, " ");
|
||||||
|
if (!params)
|
||||||
|
return -EINVAL;
|
||||||
|
if (vp)
|
||||||
|
vp->hash_name = strdup(str);
|
||||||
|
|
||||||
|
/* root digest */
|
||||||
|
str = strsep(¶ms, " ");
|
||||||
|
if (!params)
|
||||||
|
return -EINVAL;
|
||||||
|
len = strlen(str) / 2;
|
||||||
|
dmd->u.verity.root_hash_size = len;
|
||||||
|
if (get_flags & DM_ACTIVE_VERITY_ROOT_HASH) {
|
||||||
|
if (!(str2 = malloc(len)))
|
||||||
|
return -ENOMEM;
|
||||||
|
if (hex_to_bytes(str, str2) != len)
|
||||||
|
return -EINVAL;
|
||||||
|
dmd->u.verity.root_hash = str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* salt */
|
||||||
|
str = strsep(¶ms, " ");
|
||||||
|
if (params)
|
||||||
|
return -EINVAL;
|
||||||
|
if (vp) {
|
||||||
|
len = strlen(str) / 2;
|
||||||
|
vp->salt_size = len;
|
||||||
|
if (!(str2 = malloc(len)))
|
||||||
|
return -ENOMEM;
|
||||||
|
if (hex_to_bytes(str, str2) != len)
|
||||||
|
return -EINVAL;
|
||||||
|
vp->salt = str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_query_device(const char *name, uint32_t get_flags,
|
int dm_query_device(const char *name, uint32_t get_flags,
|
||||||
@@ -798,8 +931,6 @@ int dm_query_device(const char *name, uint32_t get_flags,
|
|||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
int r = -EINVAL;
|
int r = -EINVAL;
|
||||||
|
|
||||||
memset(dmd, 0, sizeof(*dmd));
|
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
|
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
|
||||||
goto out;
|
goto out;
|
||||||
if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
|
if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
|
||||||
|
|||||||
@@ -196,8 +196,8 @@ int LOOPAES_activate(struct crypt_device *cd,
|
|||||||
.uuid = crypt_get_uuid(cd),
|
.uuid = crypt_get_uuid(cd),
|
||||||
.size = 0,
|
.size = 0,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
|
.data_device = crypt_get_device_name(cd),
|
||||||
.u.crypt = {
|
.u.crypt = {
|
||||||
.device = crypt_get_device_name(cd),
|
|
||||||
.cipher = NULL,
|
.cipher = NULL,
|
||||||
.vk = vk,
|
.vk = vk,
|
||||||
.offset = crypt_get_data_offset(cd),
|
.offset = crypt_get_data_offset(cd),
|
||||||
@@ -206,7 +206,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
r = device_check_and_adjust(cd, dmd.u.crypt.device, DEV_EXCL,
|
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||||
&dmd.size, &dmd.u.crypt.offset, &flags);
|
&dmd.size, &dmd.u.crypt.offset, &flags);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
@@ -225,7 +225,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
|||||||
log_dbg("Trying to activate loop-AES device %s using cipher %s.",
|
log_dbg("Trying to activate loop-AES device %s using cipher %s.",
|
||||||
name, dmd.u.crypt.cipher);
|
name, dmd.u.crypt.cipher);
|
||||||
|
|
||||||
r = dm_create_device(name, CRYPT_LOOPAES, &dmd, NULL, 0);
|
r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0);
|
||||||
|
|
||||||
if (!r && !(dm_flags() & req_flags)) {
|
if (!r && !(dm_flags() & req_flags)) {
|
||||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping.\n"));
|
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping.\n"));
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ static int setup_mapping(const char *cipher, const char *name,
|
|||||||
.uuid = NULL,
|
.uuid = NULL,
|
||||||
.size = 0,
|
.size = 0,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
.data_device = device,
|
||||||
.u.crypt = {
|
.u.crypt = {
|
||||||
.device = device,
|
|
||||||
.cipher = cipher,
|
.cipher = cipher,
|
||||||
.vk = vk,
|
.vk = vk,
|
||||||
.offset = sector,
|
.offset = sector,
|
||||||
@@ -86,7 +86,7 @@ static int setup_mapping(const char *cipher, const char *name,
|
|||||||
dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
|
dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
|
||||||
cleaner_size = dmd.size;
|
cleaner_size = dmd.size;
|
||||||
|
|
||||||
return dm_create_device(name, "TEMP", &dmd, NULL, 0);
|
return dm_create_device(name, "TEMP", &dmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigint_handler(int sig __attribute__((unused)))
|
static void sigint_handler(int sig __attribute__((unused)))
|
||||||
|
|||||||
@@ -1037,8 +1037,8 @@ int LUKS1_activate(struct crypt_device *cd,
|
|||||||
.uuid = crypt_get_uuid(cd),
|
.uuid = crypt_get_uuid(cd),
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
.size = 0,
|
.size = 0,
|
||||||
|
.data_device = crypt_get_device_name(cd),
|
||||||
.u.crypt = {
|
.u.crypt = {
|
||||||
.device = crypt_get_device_name(cd),
|
|
||||||
.cipher = NULL,
|
.cipher = NULL,
|
||||||
.vk = vk,
|
.vk = vk,
|
||||||
.offset = crypt_get_data_offset(cd),
|
.offset = crypt_get_data_offset(cd),
|
||||||
@@ -1051,7 +1051,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
|||||||
else
|
else
|
||||||
device_check = DEV_EXCL;
|
device_check = DEV_EXCL;
|
||||||
|
|
||||||
r = device_check_and_adjust(cd, dmd.u.crypt.device, device_check,
|
r = device_check_and_adjust(cd, dmd.data_device, device_check,
|
||||||
&dmd.size, &dmd.u.crypt.offset,
|
&dmd.size, &dmd.u.crypt.offset,
|
||||||
&dmd.flags);
|
&dmd.flags);
|
||||||
if (r)
|
if (r)
|
||||||
@@ -1062,7 +1062,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dmd.u.crypt.cipher = dm_cipher;
|
dmd.u.crypt.cipher = dm_cipher;
|
||||||
r = dm_create_device(name, CRYPT_LUKS1, &dmd, NULL, 0);
|
r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0);
|
||||||
|
|
||||||
free(dm_cipher);
|
free(dm_cipher);
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
217
lib/setup.c
217
lib/setup.c
@@ -305,8 +305,8 @@ int PLAIN_activate(struct crypt_device *cd,
|
|||||||
.uuid = crypt_get_uuid(cd),
|
.uuid = crypt_get_uuid(cd),
|
||||||
.size = size,
|
.size = size,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
|
.data_device = crypt_get_device_name(cd),
|
||||||
.u.crypt = {
|
.u.crypt = {
|
||||||
.device = crypt_get_device_name(cd),
|
|
||||||
.cipher = NULL,
|
.cipher = NULL,
|
||||||
.vk = vk,
|
.vk = vk,
|
||||||
.offset = crypt_get_data_offset(cd),
|
.offset = crypt_get_data_offset(cd),
|
||||||
@@ -319,7 +319,7 @@ int PLAIN_activate(struct crypt_device *cd,
|
|||||||
else
|
else
|
||||||
device_check = DEV_EXCL;
|
device_check = DEV_EXCL;
|
||||||
|
|
||||||
r = device_check_and_adjust(cd, dmd.u.crypt.device, device_check,
|
r = device_check_and_adjust(cd, dmd.data_device, device_check,
|
||||||
&dmd.size, &dmd.u.crypt.offset, &dmd.flags);
|
&dmd.size, &dmd.u.crypt.offset, &dmd.flags);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
@@ -335,7 +335,7 @@ int PLAIN_activate(struct crypt_device *cd,
|
|||||||
log_dbg("Trying to activate PLAIN device %s using cipher %s.",
|
log_dbg("Trying to activate PLAIN device %s using cipher %s.",
|
||||||
name, dmd.u.crypt.cipher);
|
name, dmd.u.crypt.cipher);
|
||||||
|
|
||||||
r = dm_create_device(name, CRYPT_PLAIN, &dmd, NULL, 0);
|
r = dm_create_device(name, CRYPT_PLAIN, &dmd, 0);
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
if (!cd->plain_uuid && dm_query_device(name, DM_ACTIVE_UUID, &dmd) >= 0)
|
if (!cd->plain_uuid && dm_query_device(name, DM_ACTIVE_UUID, &dmd) >= 0)
|
||||||
@@ -677,15 +677,121 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
|
||||||
|
{
|
||||||
|
struct crypt_dm_active_device dmd = {};
|
||||||
|
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||||
|
int key_nums, r;
|
||||||
|
|
||||||
|
r = dm_query_device(name, DM_ACTIVE_DEVICE |
|
||||||
|
DM_ACTIVE_UUID |
|
||||||
|
DM_ACTIVE_CRYPT_CIPHER |
|
||||||
|
DM_ACTIVE_CRYPT_KEYSIZE, &dmd);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (isPLAIN(cd->type)) {
|
||||||
|
cd->plain_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
|
||||||
|
cd->plain_hdr.hash = NULL; /* no way to get this */
|
||||||
|
cd->plain_hdr.offset = dmd.u.crypt.offset;
|
||||||
|
cd->plain_hdr.skip = dmd.u.crypt.iv_offset;
|
||||||
|
cd->plain_key_size = dmd.u.crypt.vk->keylength;
|
||||||
|
|
||||||
|
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher, NULL, cipher_mode);
|
||||||
|
if (!r) {
|
||||||
|
cd->plain_cipher = strdup(cipher);
|
||||||
|
cd->plain_cipher_mode = strdup(cipher_mode);
|
||||||
|
}
|
||||||
|
} else if (isLOOPAES(cd->type)) {
|
||||||
|
cd->loopaes_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
|
||||||
|
cd->loopaes_hdr.offset = dmd.u.crypt.offset;
|
||||||
|
|
||||||
|
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher,
|
||||||
|
&key_nums, cipher_mode);
|
||||||
|
if (!r) {
|
||||||
|
cd->loopaes_cipher = strdup(cipher);
|
||||||
|
cd->loopaes_cipher_mode = strdup(cipher_mode);
|
||||||
|
/* version 3 uses last key for IV */
|
||||||
|
if (dmd.u.crypt.vk->keylength % key_nums)
|
||||||
|
key_nums++;
|
||||||
|
cd->loopaes_key_size = dmd.u.crypt.vk->keylength / key_nums;
|
||||||
|
}
|
||||||
|
} else if (isLUKS(cd->type)) {
|
||||||
|
if (mdata_device(cd)) {
|
||||||
|
r = _crypt_load_luks1(cd, 0, 0);
|
||||||
|
if (r < 0) {
|
||||||
|
log_dbg("LUKS device header does not match active device.");
|
||||||
|
free(cd->type);
|
||||||
|
cd->type = NULL;
|
||||||
|
r = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* check whether UUIDs match each other */
|
||||||
|
r = crypt_uuid_cmp(dmd.uuid, cd->hdr.uuid);
|
||||||
|
if (r < 0) {
|
||||||
|
log_dbg("LUKS device header uuid: %s mismatches DM returned uuid %s",
|
||||||
|
cd->hdr.uuid, dmd.uuid);
|
||||||
|
free(cd->type);
|
||||||
|
cd->type = NULL;
|
||||||
|
r = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
crypt_free_volume_key(dmd.u.crypt.vk);
|
||||||
|
free(CONST_CAST(void*)dmd.u.crypt.cipher);
|
||||||
|
free(CONST_CAST(void*)dmd.data_device);
|
||||||
|
free(CONST_CAST(void*)dmd.uuid);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
||||||
|
{
|
||||||
|
struct crypt_params_verity params = {};
|
||||||
|
struct crypt_dm_active_device dmd = {
|
||||||
|
.target = DM_VERITY,
|
||||||
|
.u.verity.vp = ¶ms,
|
||||||
|
};
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = dm_query_device(name, DM_ACTIVE_DEVICE |
|
||||||
|
DM_ACTIVE_UUID |
|
||||||
|
DM_ACTIVE_VERITY_HASH_DEVICE |
|
||||||
|
DM_ACTIVE_VERITY_PARAMS, &dmd);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (isVERITY(cd->type)) {
|
||||||
|
cd->verity_flags = CRYPT_VERITY_NO_HEADER; //FIXME
|
||||||
|
//cd->verity_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
|
||||||
|
cd->verity_hdr.data_size = params.data_size;
|
||||||
|
cd->verity_root_hash_size = dmd.u.verity.root_hash_size;
|
||||||
|
cd->verity_root_hash = NULL;
|
||||||
|
cd->verity_hdr.hash_name = params.hash_name;
|
||||||
|
cd->verity_hdr.data_device = NULL;
|
||||||
|
cd->verity_hdr.data_block_size = params.data_block_size;
|
||||||
|
cd->verity_hdr.hash_block_size = params.hash_block_size;
|
||||||
|
cd->verity_hdr.hash_area_offset = params.hash_area_offset;
|
||||||
|
cd->verity_hdr.version = params.version;
|
||||||
|
cd->verity_hdr.flags = params.flags;
|
||||||
|
cd->verity_hdr.salt_size = params.salt_size;
|
||||||
|
cd->verity_hdr.salt = params.salt;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(CONST_CAST(void*)dmd.u.verity.hash_device);
|
||||||
|
free(CONST_CAST(void*)dmd.data_device);
|
||||||
|
free(CONST_CAST(void*)dmd.uuid);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_init_by_name_and_header(struct crypt_device **cd,
|
int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *header_device)
|
const char *header_device)
|
||||||
{
|
{
|
||||||
crypt_status_info ci;
|
crypt_status_info ci;
|
||||||
struct crypt_dm_active_device dmd;
|
struct crypt_dm_active_device dmd;
|
||||||
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
int r;
|
||||||
int key_nums, r;
|
|
||||||
|
|
||||||
|
|
||||||
log_dbg("Allocating crypt device context by device %s.", name);
|
log_dbg("Allocating crypt device context by device %s.", name);
|
||||||
|
|
||||||
@@ -698,8 +804,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = dm_query_device(name, DM_ACTIVE_DEVICE | DM_ACTIVE_CIPHER |
|
r = dm_query_device(name, DM_ACTIVE_DEVICE | DM_ACTIVE_UUID, &dmd);
|
||||||
DM_ACTIVE_UUID | DM_ACTIVE_KEYSIZE, &dmd);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -708,17 +813,17 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
|||||||
if (header_device) {
|
if (header_device) {
|
||||||
r = crypt_init(cd, header_device);
|
r = crypt_init(cd, header_device);
|
||||||
} else {
|
} else {
|
||||||
r = crypt_init(cd, dmd.u.crypt.device);
|
r = crypt_init(cd, dmd.data_device);
|
||||||
|
|
||||||
/* Underlying device disappeared but mapping still active */
|
/* Underlying device disappeared but mapping still active */
|
||||||
if (!dmd.u.crypt.device || r == -ENOTBLK)
|
if (!dmd.data_device || r == -ENOTBLK)
|
||||||
log_verbose(NULL, _("Underlying device for crypt device %s disappeared.\n"),
|
log_verbose(NULL, _("Underlying device for crypt device %s disappeared.\n"),
|
||||||
name);
|
name);
|
||||||
|
|
||||||
/* Underlying device is not readable but crypt mapping exists */
|
/* Underlying device is not readable but crypt mapping exists */
|
||||||
if (r == -ENOTBLK) {
|
if (r == -ENOTBLK) {
|
||||||
free(CONST_CAST(void*)dmd.u.crypt.device);
|
free(CONST_CAST(void*)dmd.data_device);
|
||||||
dmd.u.crypt.device = NULL;
|
dmd.data_device = NULL;
|
||||||
r = crypt_init(cd, NULL);
|
r = crypt_init(cd, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -733,83 +838,38 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
|||||||
(*cd)->type = strdup(CRYPT_LOOPAES);
|
(*cd)->type = strdup(CRYPT_LOOPAES);
|
||||||
else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1))
|
else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1))
|
||||||
(*cd)->type = strdup(CRYPT_LUKS1);
|
(*cd)->type = strdup(CRYPT_LUKS1);
|
||||||
|
else if (!strncmp(CRYPT_VERITY, dmd.uuid, sizeof(CRYPT_VERITY)-1))
|
||||||
|
(*cd)->type = strdup(CRYPT_VERITY);
|
||||||
else
|
else
|
||||||
log_dbg("Unknown UUID set, some parameters are not set.");
|
log_dbg("Unknown UUID set, some parameters are not set.");
|
||||||
} else
|
} else
|
||||||
log_dbg("Active device has no UUID set, some parameters are not set.");
|
log_dbg("Active device has no UUID set, some parameters are not set.");
|
||||||
|
|
||||||
if (header_device) {
|
if (header_device) {
|
||||||
r = crypt_set_data_device(*cd, dmd.u.crypt.device);
|
r = crypt_set_data_device(*cd, dmd.data_device);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to initialise basic parameters from active device */
|
/* Try to initialise basic parameters from active device */
|
||||||
|
|
||||||
if (!(*cd)->backing_file && dmd.u.crypt.device &&
|
if (!(*cd)->backing_file && dmd.data_device &&
|
||||||
crypt_loop_device(dmd.u.crypt.device) &&
|
crypt_loop_device(dmd.data_device) &&
|
||||||
!((*cd)->backing_file = crypt_loop_backing_file(dmd.u.crypt.device))) {
|
!((*cd)->backing_file = crypt_loop_backing_file(dmd.data_device))) {
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPLAIN((*cd)->type)) {
|
if (dmd.target == DM_CRYPT)
|
||||||
(*cd)->plain_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
|
r = _init_by_name_crypt(*cd, name);
|
||||||
(*cd)->plain_hdr.hash = NULL; /* no way to get this */
|
else if (dmd.target == DM_VERITY)
|
||||||
(*cd)->plain_hdr.offset = dmd.u.crypt.offset;
|
r = _init_by_name_verity(*cd, name);
|
||||||
(*cd)->plain_hdr.skip = dmd.u.crypt.iv_offset;
|
|
||||||
(*cd)->plain_key_size = dmd.u.crypt.vk->keylength;
|
|
||||||
|
|
||||||
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher, NULL, cipher_mode);
|
|
||||||
if (!r) {
|
|
||||||
(*cd)->plain_cipher = strdup(cipher);
|
|
||||||
(*cd)->plain_cipher_mode = strdup(cipher_mode);
|
|
||||||
}
|
|
||||||
} else if (isLOOPAES((*cd)->type)) {
|
|
||||||
(*cd)->loopaes_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
|
|
||||||
(*cd)->loopaes_hdr.offset = dmd.u.crypt.offset;
|
|
||||||
|
|
||||||
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher,
|
|
||||||
&key_nums, cipher_mode);
|
|
||||||
if (!r) {
|
|
||||||
(*cd)->loopaes_cipher = strdup(cipher);
|
|
||||||
(*cd)->loopaes_cipher_mode = strdup(cipher_mode);
|
|
||||||
/* version 3 uses last key for IV */
|
|
||||||
if (dmd.u.crypt.vk->keylength % key_nums)
|
|
||||||
key_nums++;
|
|
||||||
(*cd)->loopaes_key_size = dmd.u.crypt.vk->keylength / key_nums;
|
|
||||||
}
|
|
||||||
} else if (isLUKS((*cd)->type)) {
|
|
||||||
if (mdata_device(*cd)) {
|
|
||||||
r = _crypt_load_luks1(*cd, 0, 0);
|
|
||||||
if (r < 0) {
|
|
||||||
log_dbg("LUKS device header does not match active device.");
|
|
||||||
free((*cd)->type);
|
|
||||||
(*cd)->type = NULL;
|
|
||||||
r = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* checks whether UUIDs match each other */
|
|
||||||
r = crypt_uuid_cmp(dmd.uuid, (*cd)->hdr.uuid);
|
|
||||||
if (r < 0) {
|
|
||||||
log_dbg("LUKS device header uuid: %s mismatches DM returned uuid %s",
|
|
||||||
(*cd)->hdr.uuid, dmd.uuid);
|
|
||||||
free((*cd)->type);
|
|
||||||
(*cd)->type = NULL;
|
|
||||||
r = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
crypt_free(*cd);
|
crypt_free(*cd);
|
||||||
*cd = NULL;
|
*cd = NULL;
|
||||||
}
|
}
|
||||||
crypt_free_volume_key(dmd.u.crypt.vk);
|
free(CONST_CAST(void*)dmd.data_device);
|
||||||
free(CONST_CAST(void*)dmd.u.crypt.device);
|
|
||||||
free(CONST_CAST(void*)dmd.u.crypt.cipher);
|
|
||||||
free(CONST_CAST(void*)dmd.uuid);
|
free(CONST_CAST(void*)dmd.uuid);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -1171,20 +1231,20 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
|||||||
|
|
||||||
log_dbg("Resizing device %s to %" PRIu64 " sectors.", name, new_size);
|
log_dbg("Resizing device %s to %" PRIu64 " sectors.", name, new_size);
|
||||||
|
|
||||||
r = dm_query_device(name, DM_ACTIVE_DEVICE | DM_ACTIVE_CIPHER |
|
r = dm_query_device(name, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER |
|
||||||
DM_ACTIVE_UUID | DM_ACTIVE_KEYSIZE |
|
DM_ACTIVE_UUID | DM_ACTIVE_CRYPT_KEYSIZE |
|
||||||
DM_ACTIVE_KEY, &dmd);
|
DM_ACTIVE_CRYPT_KEY, &dmd);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(NULL, _("Device %s is not active.\n"), name);
|
log_err(NULL, _("Device %s is not active.\n"), name);
|
||||||
goto out;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dmd.uuid) {
|
if (!dmd.uuid || dmd.target != DM_CRYPT) {
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = device_check_and_adjust(cd, dmd.u.crypt.device, DEV_OK, &new_size,
|
r = device_check_and_adjust(cd, dmd.data_device, DEV_OK, &new_size,
|
||||||
&dmd.u.crypt.offset, &dmd.flags);
|
&dmd.u.crypt.offset, &dmd.flags);
|
||||||
if (r)
|
if (r)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1195,12 +1255,14 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
|||||||
r = 0;
|
r = 0;
|
||||||
} else {
|
} else {
|
||||||
dmd.size = new_size;
|
dmd.size = new_size;
|
||||||
r = dm_create_device(name, cd->type, &dmd, NULL, 1);
|
r = dm_create_device(name, cd->type, &dmd, 1);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
if (dmd.target == DM_CRYPT) {
|
||||||
crypt_free_volume_key(dmd.u.crypt.vk);
|
crypt_free_volume_key(dmd.u.crypt.vk);
|
||||||
free(CONST_CAST(void*)dmd.u.crypt.cipher);
|
free(CONST_CAST(void*)dmd.u.crypt.cipher);
|
||||||
free(CONST_CAST(void*)dmd.u.crypt.device);
|
}
|
||||||
|
free(CONST_CAST(void*)dmd.data_device);
|
||||||
free(CONST_CAST(void*)dmd.uuid);
|
free(CONST_CAST(void*)dmd.uuid);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@@ -2342,6 +2404,9 @@ int crypt_get_active_device(struct crypt_device *cd __attribute__((unused)),
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (dmd.target != DM_CRYPT)
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
cad->offset = dmd.u.crypt.offset;
|
cad->offset = dmd.u.crypt.offset;
|
||||||
cad->iv_offset = dmd.u.crypt.iv_offset;
|
cad->iv_offset = dmd.u.crypt.iv_offset;
|
||||||
cad->size = dmd.size;
|
cad->size = dmd.size;
|
||||||
|
|||||||
@@ -39,19 +39,24 @@ struct crypt_params_verity;
|
|||||||
uint32_t dm_flags(void);
|
uint32_t dm_flags(void);
|
||||||
|
|
||||||
#define DM_ACTIVE_DEVICE (1 << 0)
|
#define DM_ACTIVE_DEVICE (1 << 0)
|
||||||
#define DM_ACTIVE_CIPHER (1 << 1)
|
#define DM_ACTIVE_UUID (1 << 1)
|
||||||
#define DM_ACTIVE_UUID (1 << 2)
|
|
||||||
#define DM_ACTIVE_KEYSIZE (1 << 3)
|
#define DM_ACTIVE_CRYPT_CIPHER (1 << 2)
|
||||||
#define DM_ACTIVE_KEY (1 << 4)
|
#define DM_ACTIVE_CRYPT_KEYSIZE (1 << 3)
|
||||||
|
#define DM_ACTIVE_CRYPT_KEY (1 << 4)
|
||||||
|
|
||||||
|
#define DM_ACTIVE_VERITY_ROOT_HASH (1 << 5)
|
||||||
|
#define DM_ACTIVE_VERITY_HASH_DEVICE (1 << 6)
|
||||||
|
#define DM_ACTIVE_VERITY_PARAMS (1 << 7)
|
||||||
|
|
||||||
struct crypt_dm_active_device {
|
struct crypt_dm_active_device {
|
||||||
enum { DM_CRYPT = 0, DM_VERITY } target;
|
enum { DM_CRYPT = 0, DM_VERITY } target;
|
||||||
uint64_t size; /* active device size */
|
uint64_t size; /* active device size */
|
||||||
uint32_t flags; /* activation flags */
|
uint32_t flags; /* activation flags */
|
||||||
const char *uuid;
|
const char *uuid;
|
||||||
|
const char *data_device;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
const char *device;
|
|
||||||
const char *cipher;
|
const char *cipher;
|
||||||
|
|
||||||
/* Active key for device */
|
/* Active key for device */
|
||||||
@@ -62,13 +67,13 @@ struct crypt_dm_active_device {
|
|||||||
uint64_t iv_offset; /* IV initilisation sector */
|
uint64_t iv_offset; /* IV initilisation sector */
|
||||||
} crypt;
|
} crypt;
|
||||||
struct {
|
struct {
|
||||||
const char *data_device;
|
|
||||||
const char *hash_device;
|
const char *hash_device;
|
||||||
|
|
||||||
const char *root_hash;
|
const char *root_hash;
|
||||||
size_t root_hash_size;
|
uint32_t root_hash_size;
|
||||||
|
|
||||||
uint64_t hash_offset; /* hash offset (not header) */
|
uint64_t hash_offset; /* hash offset (not header) */
|
||||||
|
struct crypt_params_verity *vp;
|
||||||
} verity;
|
} verity;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
@@ -85,7 +90,6 @@ int dm_query_device(const char *name, uint32_t get_flags,
|
|||||||
int dm_create_device(const char *name,
|
int dm_create_device(const char *name,
|
||||||
const char *type,
|
const char *type,
|
||||||
struct crypt_dm_active_device *dmd,
|
struct crypt_dm_active_device *dmd,
|
||||||
void *params,
|
|
||||||
int reload);
|
int reload);
|
||||||
int dm_suspend_and_wipe_key(const char *name);
|
int dm_suspend_and_wipe_key(const char *name);
|
||||||
int dm_resume_and_reinstate_key(const char *name,
|
int dm_resume_and_reinstate_key(const char *name,
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ int VERITY_activate(struct crypt_device *cd,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dmd.target = DM_VERITY;
|
dmd.target = DM_VERITY;
|
||||||
dmd.u.verity.data_device = crypt_get_device_name(cd);
|
dmd.data_device = crypt_get_device_name(cd);
|
||||||
dmd.u.verity.hash_device = hash_device;
|
dmd.u.verity.hash_device = hash_device;
|
||||||
dmd.u.verity.root_hash = root_hash;
|
dmd.u.verity.root_hash = root_hash;
|
||||||
dmd.u.verity.root_hash_size = root_hash_size;
|
dmd.u.verity.root_hash_size = root_hash_size;
|
||||||
@@ -198,13 +198,14 @@ int VERITY_activate(struct crypt_device *cd,
|
|||||||
dmd.flags = CRYPT_ACTIVATE_READONLY;
|
dmd.flags = CRYPT_ACTIVATE_READONLY;
|
||||||
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
|
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
|
||||||
dmd.uuid = NULL;
|
dmd.uuid = NULL;
|
||||||
|
dmd.u.verity.vp = verity_hdr;
|
||||||
|
|
||||||
r = device_check_and_adjust(cd, dmd.u.verity.data_device, DEV_EXCL,
|
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||||
&dmd.size, &offset, &dmd.flags);
|
&dmd.size, &offset, &dmd.flags);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = dm_create_device(name, CRYPT_VERITY, &dmd, verity_hdr, 0);
|
r = dm_create_device(name, CRYPT_VERITY, &dmd, 0);
|
||||||
if (!r && !(dm_flags() & DM_VERITY_SUPPORTED)) {
|
if (!r && !(dm_flags() & DM_VERITY_SUPPORTED)) {
|
||||||
log_err(cd, _("Kernel doesn't support dm-verity mapping.\n"));
|
log_err(cd, _("Kernel doesn't support dm-verity mapping.\n"));
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|||||||
@@ -489,6 +489,8 @@ static int action_status(int arg __attribute__((unused)))
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
crypt_free(cd);
|
crypt_free(cd);
|
||||||
|
if (r == -ENOTSUP)
|
||||||
|
r = 0;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* - init_by_name()
|
|
||||||
* - support device without superblock
|
* - support device without superblock
|
||||||
* - audit alloc errors / error path
|
* - audit alloc errors / error path
|
||||||
* - change command names (cryptsetup style)
|
* - change command names (cryptsetup style)
|
||||||
* - extend superblock (UUID)
|
* - extend superblock (UUID)
|
||||||
|
* - add api tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#define MODE_CREATE 1
|
#define MODE_CREATE 1
|
||||||
#define MODE_ACTIVATE 2
|
#define MODE_ACTIVATE 2
|
||||||
#define MODE_DUMP 3
|
#define MODE_DUMP 3
|
||||||
|
#define MODE_STATUS 4
|
||||||
|
|
||||||
static int mode = -1;
|
static int mode = -1;
|
||||||
static int use_superblock = 1; /* FIXME: no superblock not supported */
|
static int use_superblock = 1; /* FIXME: no superblock not supported */
|
||||||
@@ -145,6 +146,18 @@ static int action_dump(void)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int action_status(void)
|
||||||
|
{
|
||||||
|
struct crypt_device *cd = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = crypt_init_by_name_and_header(&cd, dm_device, NULL);
|
||||||
|
if (!r)
|
||||||
|
r = crypt_dump(cd);
|
||||||
|
crypt_free(cd);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_activate(int verify)
|
static int action_activate(int verify)
|
||||||
{
|
{
|
||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
@@ -292,6 +305,7 @@ int main(int argc, const char **argv)
|
|||||||
{ "verify", 'v', POPT_ARG_VAL, &mode, MODE_VERIFY, "Verify integrity", NULL },
|
{ "verify", 'v', POPT_ARG_VAL, &mode, MODE_VERIFY, "Verify integrity", NULL },
|
||||||
{ "activate", 'a', POPT_ARG_VAL, &mode, MODE_ACTIVATE, "Activate the device", NULL },
|
{ "activate", 'a', POPT_ARG_VAL, &mode, MODE_ACTIVATE, "Activate the device", NULL },
|
||||||
{ "dump", 'd', POPT_ARG_VAL, &mode, MODE_DUMP, "Dump the device", NULL },
|
{ "dump", 'd', POPT_ARG_VAL, &mode, MODE_DUMP, "Dump the device", NULL },
|
||||||
|
{ "status", 's', POPT_ARG_VAL, &mode, MODE_STATUS, "Status active device", NULL },
|
||||||
{ "no-superblock", 0, POPT_ARG_VAL, &use_superblock, 0, "Do not create/use superblock" },
|
{ "no-superblock", 0, POPT_ARG_VAL, &use_superblock, 0, "Do not create/use superblock" },
|
||||||
{ "format", 0, POPT_ARG_INT, &version, 0, "Format version (1 - normal format, 0 - original Chromium OS format)", "number" },
|
{ "format", 0, POPT_ARG_INT, &version, 0, "Format version (1 - normal format, 0 - original Chromium OS format)", "number" },
|
||||||
{ "data-block-size", 0, POPT_ARG_INT, &data_block_size, 0, "Block size on the data device", "bytes" },
|
{ "data-block-size", 0, POPT_ARG_INT, &data_block_size, 0, "Block size on the data device", "bytes" },
|
||||||
@@ -335,7 +349,7 @@ int main(int argc, const char **argv)
|
|||||||
usage(popt_context, EXIT_FAILURE, _("Unknown action."),
|
usage(popt_context, EXIT_FAILURE, _("Unknown action."),
|
||||||
poptGetInvocationName(popt_context));
|
poptGetInvocationName(popt_context));
|
||||||
|
|
||||||
if (mode == MODE_ACTIVATE) {
|
if (mode == MODE_ACTIVATE || mode == MODE_STATUS) {
|
||||||
dm_device = poptGetArg(popt_context);
|
dm_device = poptGetArg(popt_context);
|
||||||
if (!dm_device || !*dm_device)
|
if (!dm_device || !*dm_device)
|
||||||
usage(popt_context, EXIT_FAILURE,
|
usage(popt_context, EXIT_FAILURE,
|
||||||
@@ -343,6 +357,9 @@ int main(int argc, const char **argv)
|
|||||||
poptGetInvocationName(popt_context));
|
poptGetInvocationName(popt_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode == MODE_STATUS)
|
||||||
|
goto run; //FIXME
|
||||||
|
|
||||||
data_device = poptGetArg(popt_context);
|
data_device = poptGetArg(popt_context);
|
||||||
if (!data_device)
|
if (!data_device)
|
||||||
usage(popt_context, EXIT_FAILURE, _("Missing data device name."),
|
usage(popt_context, EXIT_FAILURE, _("Missing data device name."),
|
||||||
@@ -383,7 +400,7 @@ int main(int argc, const char **argv)
|
|||||||
salt_string = "";
|
salt_string = "";
|
||||||
salt_size = strlen(salt_string) / 2;
|
salt_size = strlen(salt_string) / 2;
|
||||||
}
|
}
|
||||||
|
run:
|
||||||
if (opt_debug) {
|
if (opt_debug) {
|
||||||
opt_verbose = 1;
|
opt_verbose = 1;
|
||||||
crypt_set_debug_level(-1);
|
crypt_set_debug_level(-1);
|
||||||
@@ -403,6 +420,9 @@ int main(int argc, const char **argv)
|
|||||||
case MODE_DUMP:
|
case MODE_DUMP:
|
||||||
r = action_dump();
|
r = action_dump();
|
||||||
break;
|
break;
|
||||||
|
case MODE_STATUS:
|
||||||
|
r = action_status();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
poptFreeContext(popt_context);
|
poptFreeContext(popt_context);
|
||||||
|
|||||||
Reference in New Issue
Block a user