From b016e65daa093a07d43890faee901e582b1219fa Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 8 Jun 2012 08:58:35 +0200 Subject: [PATCH] Use union in dm (crypt/verity) query structure. --- lib/libdevmapper.c | 41 +++++++++++++------------- lib/loopaes/loopaes.c | 23 +++++++++------ lib/luks1/keyencryption.c | 15 ++++++---- lib/luks1/keymanage.c | 22 ++++++++------ lib/setup.c | 74 +++++++++++++++++++++++++---------------------- lib/utils_dm.h | 32 ++++++++++++++------ 6 files changed, 120 insertions(+), 87 deletions(-) diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index 4ec5abd..88c529a 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -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."); } - if (!strncmp(dmd->cipher, "cipher_null-", 12)) + if (!strncmp(dmd->u.crypt.cipher, "cipher_null-", 12)) 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) return NULL; if (null_cipher) strncpy(hexkey, "-", 2); 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) + - strlen(dmd->device) + strlen(features) + 64; + max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) + + strlen(dmd->u.crypt.device) + strlen(features) + 64; params = crypt_safe_alloc(max_size); if (!params) goto out; r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s", - dmd->cipher, hexkey, dmd->iv_offset, dmd->device, - dmd->offset, features); + dmd->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset, + dmd->u.crypt.device, dmd->u.crypt.offset, features); if (r < 0 || r >= max_size) { crypt_safe_free(params); params = NULL; @@ -587,7 +587,7 @@ int dm_create_device(const char *name, if (!table_params) 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); } @@ -737,7 +737,7 @@ int dm_query_device(const char *name, uint32_t get_flags, rcipher = strsep(¶ms, " "); /* cipher */ if (get_flags & DM_ACTIVE_CIPHER) - dmd->cipher = strdup(rcipher); + dmd->u.crypt.cipher = strdup(rcipher); /* skip */ key_ = strsep(¶ms, " "); @@ -748,18 +748,18 @@ int dm_query_device(const char *name, uint32_t get_flags, goto out; params++; - dmd->iv_offset = val64; + dmd->u.crypt.iv_offset = val64; /* device */ rdevice = strsep(¶ms, " "); if (get_flags & DM_ACTIVE_DEVICE) - dmd->device = crypt_lookup_dev(rdevice); + dmd->u.crypt.device = crypt_lookup_dev(rdevice); /*offset */ if (!params) goto out; val64 = strtoull(params, ¶ms, 10); - dmd->offset = val64; + dmd->u.crypt.offset = val64; /* Features section, available since crypt target version 1.11 */ if (*params) { @@ -796,20 +796,20 @@ int dm_query_device(const char *name, uint32_t get_flags, } if (get_flags & DM_ACTIVE_KEYSIZE) { - dmd->vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL); - if (!dmd->vk) { + dmd->u.crypt.vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL); + if (!dmd->u.crypt.vk) { r = -ENOMEM; goto out; } if (get_flags & DM_ACTIVE_KEY) { 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); - dmd->vk->key[i] = strtoul(buffer, &endp, 16); + dmd->u.crypt.vk->key[i] = strtoul(buffer, &endp, 16); if (endp != &buffer[2]) { - crypt_free_volume_key(dmd->vk); - dmd->vk = NULL; + crypt_free_volume_key(dmd->u.crypt.vk); + dmd->u.crypt.vk = NULL; r = -EINVAL; goto out; } @@ -946,13 +946,14 @@ int dm_check_segment(const char *name, uint64_t offset, uint64_t size) if (r < 0) 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; else r = -EBUSY; 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)"); return r; diff --git a/lib/loopaes/loopaes.c b/lib/loopaes/loopaes.c index 298ff9f..0dd5e11 100644 --- a/lib/loopaes/loopaes.c +++ b/lib/loopaes/loopaes.c @@ -192,18 +192,22 @@ int LOOPAES_activate(struct crypt_device *cd, uint32_t req_flags; int r; struct crypt_dm_active_device dmd = { - .device = crypt_get_device_name(cd), - .cipher = NULL, + .target = DM_CRYPT, .uuid = crypt_get_uuid(cd), - .vk = vk, - .offset = crypt_get_data_offset(cd), - .iv_offset = crypt_get_iv_offset(cd), .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) return r; @@ -217,8 +221,9 @@ int LOOPAES_activate(struct crypt_device *cd, if (r < 0) return -ENOMEM; - dmd.cipher = cipher; - log_dbg("Trying to activate loop-AES device %s using cipher %s.", name, dmd.cipher); + dmd.u.crypt.cipher = 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); diff --git a/lib/luks1/keyencryption.c b/lib/luks1/keyencryption.c index 7040b82..3b3cef8 100644 --- a/lib/luks1/keyencryption.c +++ b/lib/luks1/keyencryption.c @@ -58,14 +58,17 @@ static int setup_mapping(const char *cipher, const char *name, { int device_sector_size = sector_size_for_device(device); struct crypt_dm_active_device dmd = { - .device = device, - .cipher = cipher, + .target = DM_CRYPT, .uuid = NULL, - .vk = vk, - .offset = sector, - .iv_offset = 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; diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 753a06c..e8b277e 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -1033,14 +1033,17 @@ int LUKS1_activate(struct crypt_device *cd, char *dm_cipher = NULL; enum devcheck device_check; struct crypt_dm_active_device dmd = { - .device = crypt_get_device_name(cd), - .cipher = NULL, + .target = DM_CRYPT, .uuid = crypt_get_uuid(cd), - .vk = vk, - .offset = crypt_get_data_offset(cd), - .iv_offset = 0, + .flags = flags, .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) @@ -1048,8 +1051,9 @@ int LUKS1_activate(struct crypt_device *cd, else device_check = DEV_EXCL; - r = device_check_and_adjust(cd, dmd.device, device_check, - &dmd.size, &dmd.offset, &dmd.flags); + r = device_check_and_adjust(cd, dmd.u.crypt.device, device_check, + &dmd.size, &dmd.u.crypt.offset, + &dmd.flags); if (r) return r; @@ -1057,7 +1061,7 @@ int LUKS1_activate(struct crypt_device *cd, if (r < 0) return -ENOMEM; - dmd.cipher = dm_cipher; + dmd.u.crypt.cipher = dm_cipher; r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0); free(dm_cipher); diff --git a/lib/setup.c b/lib/setup.c index 3e6f4cb..115d558 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -301,14 +301,17 @@ int PLAIN_activate(struct crypt_device *cd, char *dm_cipher = NULL; enum devcheck device_check; struct crypt_dm_active_device dmd = { - .device = crypt_get_device_name(cd), - .cipher = NULL, + .target = DM_CRYPT, .uuid = crypt_get_uuid(cd), - .vk = vk, - .offset = crypt_get_data_offset(cd), - .iv_offset = crypt_get_iv_offset(cd), .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) @@ -316,8 +319,8 @@ int PLAIN_activate(struct crypt_device *cd, else device_check = DEV_EXCL; - r = device_check_and_adjust(cd, dmd.device, device_check, - &dmd.size, &dmd.offset, &flags); + r = device_check_and_adjust(cd, dmd.u.crypt.device, device_check, + &dmd.size, &dmd.u.crypt.offset, &dmd.flags); if (r) return r; @@ -328,8 +331,9 @@ int PLAIN_activate(struct crypt_device *cd, if (r < 0) return -ENOMEM; - dmd.cipher = dm_cipher; - log_dbg("Trying to activate PLAIN device %s using cipher %s.", name, dmd.cipher); + dmd.u.crypt.cipher = dm_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); @@ -704,17 +708,17 @@ int crypt_init_by_name_and_header(struct crypt_device **cd, if (header_device) { r = crypt_init(cd, header_device); } else { - r = crypt_init(cd, dmd.device); + r = crypt_init(cd, dmd.u.crypt.device); /* 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"), name); /* Underlying device is not readable but crypt mapping exists */ if (r == -ENOTBLK) { - free(CONST_CAST(void*)dmd.device); - dmd.device = NULL; + free(CONST_CAST(void*)dmd.u.crypt.device); + dmd.u.crypt.device = 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."); if (header_device) { - r = crypt_set_data_device(*cd, dmd.device); + r = crypt_set_data_device(*cd, dmd.u.crypt.device); if (r < 0) goto out; } /* Try to initialise basic parameters from active device */ - if (!(*cd)->backing_file && dmd.device && crypt_loop_device(dmd.device) && - !((*cd)->backing_file = crypt_loop_backing_file(dmd.device))) { + if (!(*cd)->backing_file && dmd.u.crypt.device && + crypt_loop_device(dmd.u.crypt.device) && + !((*cd)->backing_file = crypt_loop_backing_file(dmd.u.crypt.device))) { r = -ENOMEM; goto out; } @@ -751,28 +756,28 @@ int crypt_init_by_name_and_header(struct crypt_device **cd, 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.offset; - (*cd)->plain_hdr.skip = dmd.iv_offset; - (*cd)->plain_key_size = dmd.vk->keylength; + (*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.cipher, cipher, NULL, cipher_mode); + 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.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); if (!r) { (*cd)->loopaes_cipher = strdup(cipher); (*cd)->loopaes_cipher_mode = strdup(cipher_mode); /* version 3 uses last key for IV */ - if (dmd.vk->keylength % key_nums) + if (dmd.u.crypt.vk->keylength % 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)) { if (mdata_device(*cd)) { @@ -802,9 +807,9 @@ out: crypt_free(*cd); *cd = NULL; } - crypt_free_volume_key(dmd.vk); - free(CONST_CAST(void*)dmd.device); - free(CONST_CAST(void*)dmd.cipher); + crypt_free_volume_key(dmd.u.crypt.vk); + free(CONST_CAST(void*)dmd.u.crypt.device); + free(CONST_CAST(void*)dmd.u.crypt.cipher); free(CONST_CAST(void*)dmd.uuid); return r; } @@ -1179,7 +1184,8 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) 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) 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); } out: - crypt_free_volume_key(dmd.vk); - free(CONST_CAST(void*)dmd.cipher); - free(CONST_CAST(void*)dmd.device); + crypt_free_volume_key(dmd.u.crypt.vk); + free(CONST_CAST(void*)dmd.u.crypt.cipher); + free(CONST_CAST(void*)dmd.u.crypt.device); free(CONST_CAST(void*)dmd.uuid); return r; @@ -2336,8 +2342,8 @@ int crypt_get_active_device(struct crypt_device *cd __attribute__((unused)), if (r < 0) return r; - cad->offset = dmd.offset; - cad->iv_offset = dmd.iv_offset; + cad->offset = dmd.u.crypt.offset; + cad->iv_offset = dmd.u.crypt.iv_offset; cad->size = dmd.size; cad->flags = dmd.flags; diff --git a/lib/utils_dm.h b/lib/utils_dm.h index 39fcf68..6eb24c1 100644 --- a/lib/utils_dm.h +++ b/lib/utils_dm.h @@ -45,18 +45,32 @@ uint32_t dm_flags(void); #define DM_ACTIVE_KEY (1 << 4) struct crypt_dm_active_device { - const char *device; - const char *cipher; + enum { DM_CRYPT = 0, DM_VERITY } target; + uint64_t size; /* active device size */ + uint32_t flags; /* activation flags */ const char *uuid; + union { + struct { + const char *device; + const char *cipher; - /* Active key for device */ - struct volume_key *vk; + /* 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 */ - uint32_t flags; /* activation flags */ + /* 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 { -- 2.7.4