Use union in dm (crypt/verity) query structure.

This commit is contained in:
Milan Broz
2012-06-08 08:58:35 +02:00
parent c35839afbc
commit b016e65daa
6 changed files with 121 additions and 88 deletions

View File

@@ -270,27 +270,27 @@ static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
log_dbg("Discard/TRIM is not supported by the kernel."); log_dbg("Discard/TRIM is not supported by the kernel.");
} }
if (!strncmp(dmd->cipher, "cipher_null-", 12)) if (!strncmp(dmd->u.crypt.cipher, "cipher_null-", 12))
null_cipher = 1; null_cipher = 1;
hexkey = crypt_safe_alloc(null_cipher ? 2 : (dmd->vk->keylength * 2 + 1)); hexkey = crypt_safe_alloc(null_cipher ? 2 : (dmd->u.crypt.vk->keylength * 2 + 1));
if (!hexkey) if (!hexkey)
return NULL; return NULL;
if (null_cipher) if (null_cipher)
strncpy(hexkey, "-", 2); strncpy(hexkey, "-", 2);
else else
hex_key(hexkey, dmd->vk->keylength, dmd->vk->key); hex_key(hexkey, dmd->u.crypt.vk->keylength, dmd->u.crypt.vk->key);
max_size = strlen(hexkey) + strlen(dmd->cipher) + max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) +
strlen(dmd->device) + strlen(features) + 64; strlen(dmd->u.crypt.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->cipher, hexkey, dmd->iv_offset, dmd->device, dmd->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset,
dmd->offset, features); dmd->u.crypt.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;
@@ -587,7 +587,7 @@ int dm_create_device(const char *name,
if (!table_params) if (!table_params)
return -EINVAL; return -EINVAL;
return _dm_create_device(name, type, dmd->device, dmd->flags, return _dm_create_device(name, type, dmd->u.crypt.device, dmd->flags,
dmd->uuid, dmd->size, table_params, reload); dmd->uuid, dmd->size, table_params, reload);
} }
@@ -737,7 +737,7 @@ int dm_query_device(const char *name, uint32_t get_flags,
rcipher = strsep(&params, " "); rcipher = strsep(&params, " ");
/* cipher */ /* cipher */
if (get_flags & DM_ACTIVE_CIPHER) if (get_flags & DM_ACTIVE_CIPHER)
dmd->cipher = strdup(rcipher); dmd->u.crypt.cipher = strdup(rcipher);
/* skip */ /* skip */
key_ = strsep(&params, " "); key_ = strsep(&params, " ");
@@ -748,18 +748,18 @@ int dm_query_device(const char *name, uint32_t get_flags,
goto out; goto out;
params++; params++;
dmd->iv_offset = val64; dmd->u.crypt.iv_offset = val64;
/* device */ /* device */
rdevice = strsep(&params, " "); rdevice = strsep(&params, " ");
if (get_flags & DM_ACTIVE_DEVICE) if (get_flags & DM_ACTIVE_DEVICE)
dmd->device = crypt_lookup_dev(rdevice); dmd->u.crypt.device = crypt_lookup_dev(rdevice);
/*offset */ /*offset */
if (!params) if (!params)
goto out; goto out;
val64 = strtoull(params, &params, 10); val64 = strtoull(params, &params, 10);
dmd->offset = val64; dmd->u.crypt.offset = val64;
/* Features section, available since crypt target version 1.11 */ /* Features section, available since crypt target version 1.11 */
if (*params) { if (*params) {
@@ -796,20 +796,20 @@ int dm_query_device(const char *name, uint32_t get_flags,
} }
if (get_flags & DM_ACTIVE_KEYSIZE) { if (get_flags & DM_ACTIVE_KEYSIZE) {
dmd->vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL); dmd->u.crypt.vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL);
if (!dmd->vk) { if (!dmd->u.crypt.vk) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
} }
if (get_flags & DM_ACTIVE_KEY) { if (get_flags & DM_ACTIVE_KEY) {
buffer[2] = '\0'; buffer[2] = '\0';
for(i = 0; i < dmd->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);
dmd->vk->key[i] = strtoul(buffer, &endp, 16); dmd->u.crypt.vk->key[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) { if (endp != &buffer[2]) {
crypt_free_volume_key(dmd->vk); crypt_free_volume_key(dmd->u.crypt.vk);
dmd->vk = NULL; dmd->u.crypt.vk = NULL;
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
@@ -946,13 +946,14 @@ int dm_check_segment(const char *name, uint64_t offset, uint64_t size)
if (r < 0) if (r < 0)
return r; return r;
if (offset >= (dmd.offset + dmd.size) || (offset + size) <= dmd.offset) if (offset >= (dmd.u.crypt.offset + dmd.size) ||
(offset + size) <= dmd.u.crypt.offset)
r = 0; r = 0;
else else
r = -EBUSY; r = -EBUSY;
log_dbg("seg: %" PRIu64 " - %" PRIu64 ", new %" PRIu64 " - %" PRIu64 "%s", log_dbg("seg: %" PRIu64 " - %" PRIu64 ", new %" PRIu64 " - %" PRIu64 "%s",
dmd.offset, dmd.offset + dmd.size, offset, offset + size, dmd.u.crypt.offset, dmd.u.crypt.offset + dmd.size, offset, offset + size,
r ? " (overlapping)" : " (ok)"); r ? " (overlapping)" : " (ok)");
return r; return r;

View File

@@ -192,18 +192,22 @@ int LOOPAES_activate(struct crypt_device *cd,
uint32_t req_flags; uint32_t req_flags;
int r; int r;
struct crypt_dm_active_device dmd = { struct crypt_dm_active_device dmd = {
.device = crypt_get_device_name(cd), .target = DM_CRYPT,
.cipher = NULL,
.uuid = crypt_get_uuid(cd), .uuid = crypt_get_uuid(cd),
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = crypt_get_iv_offset(cd),
.size = 0, .size = 0,
.flags = flags .flags = flags,
.u.crypt = {
.device = crypt_get_device_name(cd),
.cipher = NULL,
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = crypt_get_iv_offset(cd),
}
}; };
r = device_check_and_adjust(cd, dmd.device, DEV_EXCL, &dmd.size, &dmd.offset, &flags); r = device_check_and_adjust(cd, dmd.u.crypt.device, DEV_EXCL,
&dmd.size, &dmd.u.crypt.offset, &flags);
if (r) if (r)
return r; return r;
@@ -217,8 +221,9 @@ int LOOPAES_activate(struct crypt_device *cd,
if (r < 0) if (r < 0)
return -ENOMEM; return -ENOMEM;
dmd.cipher = cipher; dmd.u.crypt.cipher = cipher;
log_dbg("Trying to activate loop-AES device %s using cipher %s.", name, dmd.cipher); log_dbg("Trying to activate loop-AES device %s using cipher %s.",
name, dmd.u.crypt.cipher);
r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0); r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0);

View File

@@ -58,14 +58,17 @@ static int setup_mapping(const char *cipher, const char *name,
{ {
int device_sector_size = sector_size_for_device(device); int device_sector_size = sector_size_for_device(device);
struct crypt_dm_active_device dmd = { struct crypt_dm_active_device dmd = {
.device = device, .target = DM_CRYPT,
.cipher = cipher,
.uuid = NULL, .uuid = NULL,
.vk = vk,
.offset = sector,
.iv_offset = 0,
.size = 0, .size = 0,
.flags = 0 .flags = 0,
.u.crypt = {
.device = device,
.cipher = cipher,
.vk = vk,
.offset = sector,
.iv_offset = 0,
}
}; };
dmd.flags = CRYPT_ACTIVATE_PRIVATE; dmd.flags = CRYPT_ACTIVATE_PRIVATE;

View File

@@ -1033,14 +1033,17 @@ int LUKS1_activate(struct crypt_device *cd,
char *dm_cipher = NULL; char *dm_cipher = NULL;
enum devcheck device_check; enum devcheck device_check;
struct crypt_dm_active_device dmd = { struct crypt_dm_active_device dmd = {
.device = crypt_get_device_name(cd), .target = DM_CRYPT,
.cipher = NULL,
.uuid = crypt_get_uuid(cd), .uuid = crypt_get_uuid(cd),
.vk = vk, .flags = flags,
.offset = crypt_get_data_offset(cd),
.iv_offset = 0,
.size = 0, .size = 0,
.flags = flags .u.crypt = {
.device = crypt_get_device_name(cd),
.cipher = NULL,
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = 0,
}
}; };
if (dmd.flags & CRYPT_ACTIVATE_SHARED) if (dmd.flags & CRYPT_ACTIVATE_SHARED)
@@ -1048,8 +1051,9 @@ int LUKS1_activate(struct crypt_device *cd,
else else
device_check = DEV_EXCL; device_check = DEV_EXCL;
r = device_check_and_adjust(cd, dmd.device, device_check, r = device_check_and_adjust(cd, dmd.u.crypt.device, device_check,
&dmd.size, &dmd.offset, &dmd.flags); &dmd.size, &dmd.u.crypt.offset,
&dmd.flags);
if (r) if (r)
return r; return r;
@@ -1057,7 +1061,7 @@ int LUKS1_activate(struct crypt_device *cd,
if (r < 0) if (r < 0)
return -ENOMEM; return -ENOMEM;
dmd.cipher = dm_cipher; dmd.u.crypt.cipher = dm_cipher;
r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0); r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0);
free(dm_cipher); free(dm_cipher);

View File

@@ -301,14 +301,17 @@ int PLAIN_activate(struct crypt_device *cd,
char *dm_cipher = NULL; char *dm_cipher = NULL;
enum devcheck device_check; enum devcheck device_check;
struct crypt_dm_active_device dmd = { struct crypt_dm_active_device dmd = {
.device = crypt_get_device_name(cd), .target = DM_CRYPT,
.cipher = NULL,
.uuid = crypt_get_uuid(cd), .uuid = crypt_get_uuid(cd),
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = crypt_get_iv_offset(cd),
.size = size, .size = size,
.flags = flags .flags = flags,
.u.crypt = {
.device = crypt_get_device_name(cd),
.cipher = NULL,
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = crypt_get_iv_offset(cd),
}
}; };
if (dmd.flags & CRYPT_ACTIVATE_SHARED) if (dmd.flags & CRYPT_ACTIVATE_SHARED)
@@ -316,8 +319,8 @@ int PLAIN_activate(struct crypt_device *cd,
else else
device_check = DEV_EXCL; device_check = DEV_EXCL;
r = device_check_and_adjust(cd, dmd.device, device_check, r = device_check_and_adjust(cd, dmd.u.crypt.device, device_check,
&dmd.size, &dmd.offset, &flags); &dmd.size, &dmd.u.crypt.offset, &dmd.flags);
if (r) if (r)
return r; return r;
@@ -328,8 +331,9 @@ int PLAIN_activate(struct crypt_device *cd,
if (r < 0) if (r < 0)
return -ENOMEM; return -ENOMEM;
dmd.cipher = dm_cipher; dmd.u.crypt.cipher = dm_cipher;
log_dbg("Trying to activate PLAIN device %s using cipher %s.", name, dmd.cipher); log_dbg("Trying to activate PLAIN device %s using cipher %s.",
name, dmd.u.crypt.cipher);
r = dm_create_device(name, CRYPT_PLAIN, &dmd, 0); r = dm_create_device(name, CRYPT_PLAIN, &dmd, 0);
@@ -704,17 +708,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.device); r = crypt_init(cd, dmd.u.crypt.device);
/* Underlying device disappeared but mapping still active */ /* Underlying device disappeared but mapping still active */
if (!dmd.device || r == -ENOTBLK) if (!dmd.u.crypt.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.device); free(CONST_CAST(void*)dmd.u.crypt.device);
dmd.device = NULL; dmd.u.crypt.device = NULL;
r = crypt_init(cd, NULL); r = crypt_init(cd, NULL);
} }
} }
@@ -735,15 +739,16 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
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.device); r = crypt_set_data_device(*cd, dmd.u.crypt.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.device && crypt_loop_device(dmd.device) && if (!(*cd)->backing_file && dmd.u.crypt.device &&
!((*cd)->backing_file = crypt_loop_backing_file(dmd.device))) { crypt_loop_device(dmd.u.crypt.device) &&
!((*cd)->backing_file = crypt_loop_backing_file(dmd.u.crypt.device))) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
} }
@@ -751,28 +756,28 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
if (isPLAIN((*cd)->type)) { if (isPLAIN((*cd)->type)) {
(*cd)->plain_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL; (*cd)->plain_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
(*cd)->plain_hdr.hash = NULL; /* no way to get this */ (*cd)->plain_hdr.hash = NULL; /* no way to get this */
(*cd)->plain_hdr.offset = dmd.offset; (*cd)->plain_hdr.offset = dmd.u.crypt.offset;
(*cd)->plain_hdr.skip = dmd.iv_offset; (*cd)->plain_hdr.skip = dmd.u.crypt.iv_offset;
(*cd)->plain_key_size = dmd.vk->keylength; (*cd)->plain_key_size = dmd.u.crypt.vk->keylength;
r = crypt_parse_name_and_mode(dmd.cipher, cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher, NULL, cipher_mode);
if (!r) { if (!r) {
(*cd)->plain_cipher = strdup(cipher); (*cd)->plain_cipher = strdup(cipher);
(*cd)->plain_cipher_mode = strdup(cipher_mode); (*cd)->plain_cipher_mode = strdup(cipher_mode);
} }
} else if (isLOOPAES((*cd)->type)) { } else if (isLOOPAES((*cd)->type)) {
(*cd)->loopaes_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL; (*cd)->loopaes_uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
(*cd)->loopaes_hdr.offset = dmd.offset; (*cd)->loopaes_hdr.offset = dmd.u.crypt.offset;
r = crypt_parse_name_and_mode(dmd.cipher, cipher, r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher,
&key_nums, cipher_mode); &key_nums, cipher_mode);
if (!r) { if (!r) {
(*cd)->loopaes_cipher = strdup(cipher); (*cd)->loopaes_cipher = strdup(cipher);
(*cd)->loopaes_cipher_mode = strdup(cipher_mode); (*cd)->loopaes_cipher_mode = strdup(cipher_mode);
/* version 3 uses last key for IV */ /* version 3 uses last key for IV */
if (dmd.vk->keylength % key_nums) if (dmd.u.crypt.vk->keylength % key_nums)
key_nums++; key_nums++;
(*cd)->loopaes_key_size = dmd.vk->keylength / key_nums; (*cd)->loopaes_key_size = dmd.u.crypt.vk->keylength / key_nums;
} }
} else if (isLUKS((*cd)->type)) { } else if (isLUKS((*cd)->type)) {
if (mdata_device(*cd)) { if (mdata_device(*cd)) {
@@ -802,9 +807,9 @@ out:
crypt_free(*cd); crypt_free(*cd);
*cd = NULL; *cd = NULL;
} }
crypt_free_volume_key(dmd.vk); crypt_free_volume_key(dmd.u.crypt.vk);
free(CONST_CAST(void*)dmd.device); free(CONST_CAST(void*)dmd.u.crypt.device);
free(CONST_CAST(void*)dmd.cipher); free(CONST_CAST(void*)dmd.u.crypt.cipher);
free(CONST_CAST(void*)dmd.uuid); free(CONST_CAST(void*)dmd.uuid);
return r; return r;
} }
@@ -1179,7 +1184,8 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
goto out; goto out;
} }
r = device_check_and_adjust(cd, dmd.device, DEV_OK, &new_size, &dmd.offset, &dmd.flags); r = device_check_and_adjust(cd, dmd.u.crypt.device, DEV_OK, &new_size,
&dmd.u.crypt.offset, &dmd.flags);
if (r) if (r)
goto out; goto out;
@@ -1192,9 +1198,9 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
r = dm_create_device(name, cd->type, &dmd, 1); r = dm_create_device(name, cd->type, &dmd, 1);
} }
out: out:
crypt_free_volume_key(dmd.vk); crypt_free_volume_key(dmd.u.crypt.vk);
free(CONST_CAST(void*)dmd.cipher); free(CONST_CAST(void*)dmd.u.crypt.cipher);
free(CONST_CAST(void*)dmd.device); free(CONST_CAST(void*)dmd.u.crypt.device);
free(CONST_CAST(void*)dmd.uuid); free(CONST_CAST(void*)dmd.uuid);
return r; return r;
@@ -2336,8 +2342,8 @@ int crypt_get_active_device(struct crypt_device *cd __attribute__((unused)),
if (r < 0) if (r < 0)
return r; return r;
cad->offset = dmd.offset; cad->offset = dmd.u.crypt.offset;
cad->iv_offset = dmd.iv_offset; cad->iv_offset = dmd.u.crypt.iv_offset;
cad->size = dmd.size; cad->size = dmd.size;
cad->flags = dmd.flags; cad->flags = dmd.flags;

View File

@@ -45,18 +45,32 @@ uint32_t dm_flags(void);
#define DM_ACTIVE_KEY (1 << 4) #define DM_ACTIVE_KEY (1 << 4)
struct crypt_dm_active_device { struct crypt_dm_active_device {
const char *device; enum { DM_CRYPT = 0, DM_VERITY } target;
const char *cipher;
const char *uuid;
/* Active key for device */
struct volume_key *vk;
/* struct crypt_active_device */
uint64_t offset; /* offset in sectors */
uint64_t iv_offset; /* IV initilisation sector */
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;
union {
struct {
const char *device;
const char *cipher;
/* Active key for device */
struct volume_key *vk;
/* struct crypt_active_device */
uint64_t offset; /* offset in sectors */
uint64_t iv_offset; /* IV initilisation sector */
} crypt;
struct {
const char *data_device;
const char *hash_device;
const char *root_hash;
size_t root_hash_size;
uint64_t hash_offset; /* hash offset (not header) */
} verity;
} u;
}; };
struct crypt_dm_active_verity { struct crypt_dm_active_verity {