}
int dm_create_device(const char *name,
- const char *device,
- const char *cipher,
const char *type,
- const char *uuid,
- uint64_t size,
- uint64_t skip,
- uint64_t offset,
- size_t key_size,
- const char *key,
- int read_only,
+ struct crypt_dm_active_device *dmd,
int reload)
{
struct dm_task *dmt = NULL;
uint32_t cookie = 0;
uint16_t udev_flags = 0;
- params = get_params(device, skip, offset, cipher, key_size, key);
+ params = get_params(dmd->device, dmd->iv_offset, dmd->offset,
+ dmd->cipher, dmd->key_size, dmd->key);
if (!params)
goto out_no_removal;
if (!dm_task_set_name(dmt, name))
goto out_no_removal;
} else {
- dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
+ dm_prepare_uuid(name, type, dmd->uuid, dev_uuid, sizeof(dev_uuid));
if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
goto out_no_removal;
if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
goto out_no_removal;
- if (read_only && !dm_task_set_ro(dmt))
+ if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
goto out_no_removal;
- if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
+ if (!dm_task_add_target(dmt, 0, dmd->size, DM_CRYPT_TARGET, params))
goto out_no_removal;
#ifdef DM_READ_AHEAD_MINIMUM_FLAG
- if (device_read_ahead(device, &read_ahead) &&
+ if (device_read_ahead(dmd->device, &read_ahead) &&
!dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
goto out_no_removal;
#endif
goto out;
if (!dm_task_set_name(dmt, name))
goto out;
- if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
+ if (dmd->uuid && !dm_task_set_uuid(dmt, dev_uuid))
goto out;
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
goto out;
return r;
}
-int dm_status_device(const char *name)
+static int dm_status_dmi(const char *name, struct dm_info *dmi)
{
struct dm_task *dmt;
- struct dm_info dmi;
uint64_t start, length;
char *target_type, *params;
void *next = NULL;
if (!dm_task_run(dmt))
goto out;
- if (!dm_task_get_info(dmt, &dmi))
+ if (!dm_task_get_info(dmt, dmi))
goto out;
- if (!dmi.exists) {
+ if (!dmi->exists) {
r = -ENODEV;
goto out;
}
start != 0 || next)
r = -EINVAL;
else
- r = (dmi.open_count > 0);
+ r = 0;
out:
if (dmt)
dm_task_destroy(dmt);
return r;
}
-int dm_query_device(const char *name,
- char **device,
- uint64_t *size,
- uint64_t *skip,
- uint64_t *offset,
- char **cipher,
- int *key_size,
- char **key,
- int *read_only,
- int *suspended,
- char **uuid)
+int dm_status_device(const char *name)
+{
+ int r;
+ struct dm_info dmi;
+
+ r = dm_status_dmi(name, &dmi);
+ if (r < 0)
+ return r;
+
+ return (dmi.open_count > 0);
+}
+
+int dm_status_suspended(const char *name)
+{
+ int r;
+ struct dm_info dmi;
+
+ r = dm_status_dmi(name, &dmi);
+ if (r < 0)
+ return r;
+
+ return dmi.suspended ? 1 : 0;
+}
+
+int dm_query_device(const char *name, uint32_t get_flags,
+ struct crypt_dm_active_device *dmd)
{
struct dm_task *dmt;
struct dm_info dmi;
char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3];
const char *tmp_uuid;
void *next = NULL;
- int i, r = -EINVAL;
+ unsigned int i;
+ int r = -EINVAL;
+
+ memset(dmd, 0, sizeof(*dmd));
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
goto out;
goto out;
}
+ tmp_uuid = dm_task_get_uuid(dmt);
+
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, ¶ms);
if (!target_type || strcmp(target_type, DM_CRYPT_TARGET) != 0 ||
start != 0 || next)
goto out;
- if (size)
- *size = length;
+ dmd->size = length;
rcipher = strsep(¶ms, " ");
/* cipher */
- if (cipher)
- *cipher = strdup(rcipher);
+ if (get_flags & DM_ACTIVE_CIPHER)
+ dmd->cipher = strdup(rcipher);
/* skip */
key_ = strsep(¶ms, " ");
if (*params != ' ')
goto out;
params++;
- if (skip)
- *skip = val64;
+
+ dmd->iv_offset = val64;
/* device */
rdevice = strsep(¶ms, " ");
- if (device)
- *device = crypt_lookup_dev(rdevice);
+ if (get_flags & DM_ACTIVE_DEVICE)
+ dmd->device = crypt_lookup_dev(rdevice);
/*offset */
if (!params)
val64 = strtoull(params, ¶ms, 10);
if (*params)
goto out;
- if (offset)
- *offset = val64;
+ dmd->offset = val64;
/* key_size */
- if (key_size)
- *key_size = strlen(key_) / 2;
+ dmd->key_size = strlen(key_) / 2;
/* key */
- if (key_size && key) {
- *key = crypt_safe_alloc(*key_size);
- if (!*key) {
+ if (dmd->key_size && (get_flags & DM_ACTIVE_KEY)) {
+ dmd->key = crypt_safe_alloc(dmd->key_size);
+ if (!dmd->key) {
r = -ENOMEM;
goto out;
}
buffer[2] = '\0';
- for(i = 0; i < *key_size; i++) {
+ for(i = 0; i < dmd->key_size; i++) {
memcpy(buffer, &key_[i * 2], 2);
- (*key)[i] = strtoul(buffer, &endp, 16);
+ dmd->key[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) {
- crypt_safe_free(key);
- *key = NULL;
+ crypt_safe_free(dmd->key);
+ dmd->key = NULL;
goto out;
}
}
}
memset(key_, 0, strlen(key_));
- if (read_only)
- *read_only = dmi.read_only;
-
- if (suspended)
- *suspended = dmi.suspended;
+ if (dmi.read_only)
+ dmd->flags |= CRYPT_ACTIVATE_READONLY;
- if (uuid && (tmp_uuid = dm_task_get_uuid(dmt)) &&
- !strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
- *uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
+ if (!tmp_uuid)
+ dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
+ else if (get_flags & DM_ACTIVE_UUID) {
+ if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
+ dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
+ }
r = (dmi.open_count > 0);
out:
int dm_check_segment(const char *name, uint64_t offset, uint64_t size)
{
- uint64_t seg_size, seg_offset;
+ struct crypt_dm_active_device dmd;
int r;
log_dbg("Checking segments for device %s.", name);
- r = dm_query_device(name, NULL, &seg_size, NULL, &seg_offset,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ r = dm_query_device(name, 0, &dmd);
if (r < 0)
return r;
- if (offset >= (seg_offset + seg_size) || (offset + size) <= seg_offset)
+ if (offset >= (dmd.offset + dmd.size) || (offset + size) <= dmd.offset)
r = 0;
else
r = -EBUSY;
log_dbg("seg: %" PRIu64 " - %" PRIu64 ", new %" PRIu64 " - %" PRIu64 "%s",
- seg_offset, seg_offset + seg_size, offset, offset + size,
+ dmd.offset, dmd.offset + dmd.size, offset, offset + size,
r ? " (overlapping)" : " (ok)");
return r;
return r;
}
-/*
- * Password processing behaviour matrix of process_key
- *
- * from binary file: check if there is sufficently large key material
- * interactive & from fd: hash if requested, otherwise crop or pad with '0'
- */
-static char *process_key(struct crypt_device *cd, const char *hash_name,
- const char *key_file, size_t key_size,
- const char *pass, size_t passLen)
+static int process_key(struct crypt_device *cd, const char *hash_name,
+ size_t key_size, const char *pass, size_t passLen,
+ struct volume_key **vk)
{
- char *key;
int r;
if (!key_size)
- return NULL;
-
- key = crypt_safe_alloc(key_size);
- if (!key)
- return NULL;
- memset(key, 0, key_size);
-
- /* key is coming from binary file */
- if (key_file && strcmp(key_file, "-")) {
- if(passLen < key_size) {
- log_err(cd, ngettext("Cannot read %d byte from key file %s.\n",
- "Cannot read %d bytes from key file %s.\n", key_size),
- (int)key_size, key_file);
- crypt_safe_free(key);
- return NULL;
- }
- memcpy(key, pass, key_size);
- return key;
- }
+ return -EINVAL;
+
+ *vk = crypt_alloc_volume_key(key_size, NULL);
+ if (!*vk)
+ return -ENOMEM;
- /* key is coming from tty, fd or binary stdin */
if (hash_name) {
- r = crypt_plain_hash(cd, hash_name, key, key_size, pass, passLen);
+ r = crypt_plain_hash(cd, hash_name, (*vk)->key, key_size, pass, passLen);
if (r < 0) {
if (r == -ENOENT)
log_err(cd, _("Hash algorithm %s not supported.\n"),
else
log_err(cd, _("Key processing error (using hash %s).\n"),
hash_name);
- crypt_safe_free(key);
- return NULL;
+ crypt_free_volume_key(*vk);
+ *vk = NULL;
+ return -EINVAL;
}
} else if (passLen > key_size) {
- memcpy(key, pass, key_size);
+ memcpy((*vk)->key, pass, key_size);
} else {
- memcpy(key, pass, passLen);
+ memcpy((*vk)->key, pass, passLen);
}
- return key;
+ return 0;
}
static int isPLAIN(const char *type)
return 0;
}
-static int create_device_helper(struct crypt_device *cd,
- const char *name,
- const char *hash,
- const char *cipher,
- const char *cipher_mode,
- const char *key_file,
- const char *passphrase,
- size_t passphrase_size,
- size_t key_size,
- uint64_t size,
- uint64_t skip,
- uint64_t offset,
- const char *uuid,
- uint32_t activation_flags,
- int reload)
+int PLAIN_activate(struct crypt_device *cd,
+ const char *name,
+ struct volume_key *vk,
+ uint64_t size,
+ uint64_t iv_offset,
+ uint32_t flags)
{
- crypt_status_info ci;
+ int r;
char *dm_cipher = NULL;
- char *processed_key = NULL;
- enum devcheck device_check;
- int r, read_only;
-
- if (!name)
- return -EINVAL;
-
- read_only = activation_flags & CRYPT_ACTIVATE_READONLY ? 1 : 0;
- if (reload)
- device_check = DEV_OK;
- else if (activation_flags & CRYPT_ACTIVATE_SHARED)
- device_check = DEV_SHARED;
- else
- device_check = DEV_EXCL;
-
- ci = crypt_status(cd, name);
- if (ci == CRYPT_INVALID)
- return -EINVAL;
-
- if (reload && ci < CRYPT_ACTIVE)
- return -EINVAL;
-
- if (!reload && ci >= CRYPT_ACTIVE) {
- log_err(cd, _("Device %s already exists.\n"), name);
- return -EEXIST;
- }
-
- if (key_size > 1024) {
- log_err(cd, _("Invalid key size %d.\n"), (int)key_size);
- return -EINVAL;
- }
-
- r = device_check_and_adjust(cd, cd->device, device_check, &size, &offset, &read_only);
+ struct crypt_dm_active_device dmd = {
+ .device = crypt_get_device_name(cd),
+ .cipher = NULL,
+ .uuid = crypt_get_uuid(cd),
+ .key = vk->key,
+ .key_size = vk->keylength,
+ .offset = crypt_get_data_offset(cd),
+ .iv_offset = iv_offset,
+ .size = size,
+ .flags = flags
+ };
+
+ r = device_check_and_adjust(cd, dmd.device,
+ (dmd.flags & CRYPT_ACTIVATE_SHARED) ? DEV_SHARED : DEV_EXCL,
+ &dmd.size, &dmd.offset, &flags);
if (r)
return r;
- if (cipher_mode && asprintf(&dm_cipher, "%s-%s", cipher, cipher_mode) < 0)
+ if (crypt_get_cipher_mode(cd))
+ r = asprintf(&dm_cipher, "%s-%s", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
+ else
+ r = asprintf(&dm_cipher, "%s", crypt_get_cipher(cd));
+ if (r < 0)
return -ENOMEM;
- processed_key = process_key(cd, hash, key_file, key_size, passphrase, passphrase_size);
- if (!processed_key) {
- r = -ENOENT;
- goto out;
- }
-
- r = dm_create_device(name, cd->device, dm_cipher ?: cipher, cd->type, uuid, size, skip, offset,
- key_size, processed_key, read_only, reload);
+ dmd.cipher = dm_cipher;
+ log_dbg("Trying to activate PLAIN device %s using cipher %s.", name, dmd.cipher);
- if (isPLAIN(cd->type) && !uuid)
- (void)dm_query_device(name, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, &cd->plain_uuid);
-out:
- free(dm_cipher);
- crypt_safe_free(processed_key);
- return r;
-}
+ r = dm_create_device(name, CRYPT_PLAIN, &dmd, 0);
-static int open_from_hdr_and_vk(struct crypt_device *cd,
- struct volume_key *vk,
- const char *name,
- uint32_t flags)
-{
- uint64_t size, offset;
- char *cipher;
- int read_only, no_uuid, r;
-
- size = 0;
- offset = crypt_get_data_offset(cd);
- read_only = flags & CRYPT_ACTIVATE_READONLY;
- no_uuid = flags & CRYPT_ACTIVATE_NO_UUID;
-
- r = device_check_and_adjust(cd, cd->device, DEV_EXCL, &size, &offset, &read_only);
- if (r)
- return r;
+ // FIXME
+ if (!cd->plain_uuid && dm_query_device(name, DM_ACTIVE_UUID, &dmd) >= 0)
+ cd->plain_uuid = (char*)dmd.uuid;
- if (asprintf(&cipher, "%s-%s", crypt_get_cipher(cd),
- crypt_get_cipher_mode(cd)) < 0)
- r = -ENOMEM;
- else
- r = dm_create_device(name, cd->device, cipher, cd->type,
- no_uuid ? NULL : crypt_get_uuid(cd),
- size, 0, offset, vk->keylength, vk->key,
- read_only, 0);
- free(cipher);
+ free(dm_cipher);
return r;
}
return dm_get_dir();
}
-/////////////////////////////////
-//
-// New API
-//
-
int crypt_init(struct crypt_device **cd, const char *device)
{
struct crypt_device *h = NULL;
int crypt_init_by_name(struct crypt_device **cd, const char *name)
{
crypt_status_info ci;
- struct crypt_active_device cad;
- char *device = NULL, *cipher_full = NULL, *device_uuid = NULL;
+ struct crypt_dm_active_device dmd;
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
- char *key = NULL;
- int key_size = 0, key_nums, r;
+ int key_nums, r;
log_dbg("Allocating crypt device context by device %s.", name);
return -ENODEV;
}
- r = dm_query_device(name, &device, &cad.size, &cad.iv_offset, &cad.offset,
- &cipher_full, &key_size, &key, NULL, NULL,
- &device_uuid);
+ r = dm_query_device(name, DM_ACTIVE_ALL, &dmd);
if (r < 0)
goto out;
*cd = NULL;
- r = crypt_init(cd, device);
+ r = crypt_init(cd, dmd.device);
/* Underlying device disappeared but mapping still active */
- if (!device || r == -ENOTBLK)
+ if (!dmd.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(device);
- device = NULL;
+ free((char*)dmd.device);
+ dmd.device = NULL;
r = crypt_init(cd, NULL);
}
/* Try to initialise basic parameters from active device */
- if (!(*cd)->backing_file && device && crypt_loop_device(device) &&
- !((*cd)->backing_file = crypt_loop_backing_file(device))) {
+ if (!(*cd)->backing_file && dmd.device && crypt_loop_device(dmd.device) &&
+ !((*cd)->backing_file = crypt_loop_backing_file(dmd.device))) {
r = -ENOMEM;
goto out;
}
- if (device_uuid) {
- if (!strncmp(CRYPT_PLAIN, device_uuid, sizeof(CRYPT_PLAIN)-1)) {
+ if (dmd.uuid) {
+ if (!strncmp(CRYPT_PLAIN, dmd.uuid, sizeof(CRYPT_PLAIN)-1)) {
(*cd)->type = strdup(CRYPT_PLAIN);
- (*cd)->plain_uuid = strdup(device_uuid);
+ (*cd)->plain_uuid = strdup(dmd.uuid);
(*cd)->plain_hdr.hash = NULL; /* no way to get this */
- (*cd)->plain_hdr.offset = cad.offset;
- (*cd)->plain_hdr.skip = cad.iv_offset;
- (*cd)->volume_key = crypt_alloc_volume_key(key_size, key);
+ (*cd)->plain_hdr.offset = dmd.offset;
+ (*cd)->plain_hdr.skip = dmd.iv_offset;
+ (*cd)->volume_key = crypt_alloc_volume_key(dmd.key_size, dmd.key);
if (!(*cd)->volume_key) {
r = -ENOMEM;
goto out;
}
- r = crypt_parse_name_and_mode(cipher_full, cipher, NULL, cipher_mode);
+ r = crypt_parse_name_and_mode(dmd.cipher, cipher, NULL, cipher_mode);
if (!r) {
(*cd)->plain_cipher = strdup(cipher);
(*cd)->plain_cipher_mode = strdup(cipher_mode);
}
- } else if (!strncmp(CRYPT_LOOPAES, device_uuid, sizeof(CRYPT_LOOPAES)-1)) {
+ } else if (!strncmp(CRYPT_LOOPAES, dmd.uuid, sizeof(CRYPT_LOOPAES)-1)) {
(*cd)->type = strdup(CRYPT_LOOPAES);
- (*cd)->loopaes_uuid = strdup(device_uuid);
- (*cd)->loopaes_hdr.offset = cad.offset;
+ (*cd)->loopaes_uuid = strdup(dmd.uuid);
+ (*cd)->loopaes_hdr.offset = dmd.offset;
- r = crypt_parse_name_and_mode(cipher_full, cipher,
+ r = crypt_parse_name_and_mode(dmd.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 (key_size % key_nums)
+ if (dmd.key_size % key_nums)
key_nums++;
- (*cd)->loopaes_key_size = key_size / key_nums;
+ (*cd)->loopaes_key_size = dmd.key_size / key_nums;
}
- } else if (!strncmp(CRYPT_LUKS1, device_uuid, sizeof(CRYPT_LUKS1)-1)) {
- if (device) {
+ } else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1)) {
+ if (dmd.device) {
if (crypt_load(*cd, CRYPT_LUKS1, NULL) < 0 ||
- crypt_volume_key_verify(*cd, key, key_size) < 0) {
+ crypt_volume_key_verify(*cd, dmd.key, dmd.key_size) < 0) {
log_dbg("LUKS device header does not match active device.");
goto out;
}
- (*cd)->volume_key = crypt_alloc_volume_key(key_size, key);
+ (*cd)->volume_key = crypt_alloc_volume_key(dmd.key_size, dmd.key);
if (!(*cd)->volume_key) {
r = -ENOMEM;
goto out;
crypt_free(*cd);
*cd = NULL;
}
- crypt_safe_free(key);
- free(device);
- free(cipher_full);
- free(device_uuid);
+ crypt_safe_free(dmd.key);
+ free((char*)dmd.device);
+ free((char*)dmd.cipher);
+ free((char*)dmd.uuid);
return r;
}
int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
{
- char *device = NULL, *cipher = NULL, *uuid = NULL, *key = NULL;
- uint64_t size, skip, offset;
- int key_size, read_only, r;
+ struct crypt_dm_active_device dmd;
+ int r;
/* Device context type must be initialised */
if (!cd->type || !crypt_get_uuid(cd))
log_dbg("Resizing device %s to %" PRIu64 " sectors.", name, new_size);
- r = dm_query_device(name, &device, &size, &skip, &offset,
- &cipher, &key_size, &key, &read_only, NULL, &uuid);
+ r = dm_query_device(name, DM_ACTIVE_ALL, &dmd);
if (r < 0) {
log_err(NULL, _("Device %s is not active.\n"), name);
goto out;
}
- if (!uuid) {
+ if (!dmd.uuid) {
r = -EINVAL;
goto out;
}
- r = device_check_and_adjust(cd, device, DEV_OK, &new_size, &offset, &read_only);
+ r = device_check_and_adjust(cd, dmd.device, DEV_OK, &new_size, &dmd.offset, &dmd.flags);
if (r)
goto out;
- if (new_size == size) {
+ if (new_size == dmd.size) {
log_dbg("Device has already requested size %" PRIu64
- " sectors.", size);
+ " sectors.", dmd.size);
r = 0;
- goto out;
+ } else {
+ dmd.size = new_size;
+ r = dm_create_device(name, cd->type, &dmd, 1);
}
-
- r = dm_create_device(name, device, cipher, cd->type,
- crypt_get_uuid(cd), new_size, skip, offset,
- key_size, key, read_only, 1);
out:
- crypt_safe_free(key);
- free(cipher);
- free(device);
- free(uuid);
+ crypt_safe_free(dmd.key);
+ free((char*)dmd.cipher);
+ free((char*)dmd.device);
+ free((char*)dmd.uuid);
return r;
}
const char *name)
{
crypt_status_info ci;
- int r, suspended = 0;
+ int r;
log_dbg("Suspending volume %s.", name);
if (!cd && dm_init(NULL, 1) < 0)
return -ENOSYS;
- r = dm_query_device(name, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, &suspended, NULL);
+ r = dm_status_suspended(name);
if (r < 0)
goto out;
- if (suspended) {
+ if (r) {
log_err(cd, _("Volume %s is already suspended.\n"), name);
r = -EINVAL;
goto out;
size_t passphrase_size)
{
struct volume_key *vk = NULL;
- int r, suspended = 0;
+ int r;
log_dbg("Resuming volume %s.", name);
goto out;
}
- r = dm_query_device(name, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, &suspended, NULL);
+ r = dm_status_suspended(name);
if (r < 0)
return r;
- if (!suspended) {
+ if (!r) {
log_err(cd, _("Volume %s is not suspended.\n"), name);
return -EINVAL;
}
struct volume_key *vk = NULL;
char *passphrase_read = NULL;
size_t passphrase_size_read;
- int r, suspended = 0;
+ int r;
log_dbg("Resuming volume %s.", name);
goto out;
}
- r = dm_query_device(name, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, &suspended, NULL);
+ r = dm_status_suspended(name);
if (r < 0)
return r;
- if (!suspended) {
+ if (!r) {
log_err(cd, _("Volume %s is not suspended.\n"), name);
return -EINVAL;
}
/* plain, use hashed passphrase */
if (isPLAIN(cd->type)) {
+ if (!name)
+ return -EINVAL;
+
if (!passphrase) {
r = key_from_terminal(cd, NULL, &read_passphrase,
&passphraseLen, 0);
passphrase = read_passphrase;
passphrase_size = passphraseLen;
}
- r = create_device_helper(cd, name, cd->plain_hdr.hash,
- cd->plain_cipher, cd->plain_cipher_mode,
- NULL, passphrase, passphrase_size,
- cd->volume_key->keylength, cd->plain_hdr.size,
- cd->plain_hdr.skip, cd->plain_hdr.offset,
- cd->plain_uuid, flags, 0);
+
+ r = process_key(cd, cd->plain_hdr.hash,
+ cd->volume_key->keylength,
+ passphrase, passphrase_size, &vk);
+ if (r < 0)
+ goto out;
+
+ r = PLAIN_activate(cd, name, vk,
+ cd->plain_hdr.size,
+ cd->plain_hdr.skip, flags);
keyslot = 0;
} else if (isLUKS(cd->type)) {
/* provided passphrase, do not retry */
if (r >= 0) {
keyslot = r;
if (name)
- r = open_from_hdr_and_vk(cd, vk, name, flags);
+ r = LUKS1_activate(cd, name, vk, flags);
}
} else
r = -EINVAL;
return -EINVAL;
if (isPLAIN(cd->type)) {
+ if (!name)
+ return -EINVAL;
+
r = key_from_file(cd, _("Enter passphrase: "),
&passphrase_read, &passphrase_size_read,
keyfile, keyfile_size);
if (r < 0)
goto out;
- r = create_device_helper(cd, name, cd->plain_hdr.hash,
- cd->plain_cipher, cd->plain_cipher_mode,
- NULL, passphrase_read, passphrase_size_read,
- cd->volume_key->keylength, cd->plain_hdr.size,
- cd->plain_hdr.skip, cd->plain_hdr.offset,
- cd->plain_uuid, flags, 0);
+
+ r = process_key(cd, cd->plain_hdr.hash,
+ cd->volume_key->keylength,
+ passphrase_read, passphrase_size_read, &vk);
+ if (r < 0)
+ goto out;
+
+ r = PLAIN_activate(cd, name, vk,
+ cd->plain_hdr.size,
+ cd->plain_hdr.skip, flags);
} else if (isLUKS(cd->type)) {
r = key_from_file(cd, _("Enter passphrase: "), &passphrase_read,
&passphrase_size_read, keyfile, keyfile_size);
keyslot = r;
if (name) {
- r = open_from_hdr_and_vk(cd, vk, name, flags);
+ r = LUKS1_activate(cd, name, vk, flags);
if (r < 0)
goto out;
}
if (name)
r = LOOPAES_activate(cd, name, cd->loopaes_cipher,
key_count, vk,
- cd->loopaes_hdr.offset,
cd->loopaes_hdr.skip,
flags);
} else
uint32_t flags)
{
crypt_status_info ci;
- struct volume_key *vk;
- int r;
+ struct volume_key *vk = NULL;
+ int r = -EINVAL;
log_dbg("Activating volume %s by volume key.", name);
- /* use key directly, no hash */
- if (isPLAIN(cd->type)) {
- if (!volume_key || !volume_key_size || !cd->volume_key ||
- volume_key_size != cd->volume_key->keylength) {
- log_err(cd, _("Incorrect volume key specified for plain device.\n"));
- return -EINVAL;
- }
-
- return create_device_helper(cd, name, NULL,
- cd->plain_cipher, cd->plain_cipher_mode, NULL, volume_key, volume_key_size,
- cd->volume_key->keylength, cd->plain_hdr.size, cd->plain_hdr.skip,
- cd->plain_hdr.offset, cd->plain_uuid, flags, 0);
- }
-
- if (!isLUKS(cd->type)) {
- log_err(cd, _("Device type is not properly initialised.\n"));
- return -EINVAL;
- }
-
if (name) {
ci = crypt_status(NULL, name);
if (ci == CRYPT_INVALID)
}
}
- /* If key is not provided, try to use internal key */
- if (!volume_key) {
- if (!cd->volume_key) {
- log_err(cd, _("Volume key does not match the volume.\n"));
+ /* use key directly, no hash */
+ if (isPLAIN(cd->type)) {
+ if (!name)
+ return -EINVAL;
+
+ if (!volume_key || !volume_key_size || !cd->volume_key ||
+ volume_key_size != cd->volume_key->keylength) {
+ log_err(cd, _("Incorrect volume key specified for plain device.\n"));
return -EINVAL;
}
- volume_key_size = cd->volume_key->keylength;
- volume_key = cd->volume_key->key;
- }
- vk = crypt_alloc_volume_key(volume_key_size, volume_key);
- if (!vk)
- return -ENOMEM;
- r = LUKS_verify_volume_key(&cd->hdr, vk);
+ vk = crypt_alloc_volume_key(volume_key_size, volume_key);
+ if (!vk)
+ return -ENOMEM;
- if (r == -EPERM)
- log_err(cd, _("Volume key does not match the volume.\n"));
+ r = PLAIN_activate(cd, name, vk,
+ cd->plain_hdr.size,
+ cd->plain_hdr.skip, flags);
+ } else if (isLUKS(cd->type)) {
+ /* If key is not provided, try to use internal key */
+ if (!volume_key) {
+ if (!cd->volume_key) {
+ log_err(cd, _("Volume key does not match the volume.\n"));
+ return -EINVAL;
+ }
+ volume_key_size = cd->volume_key->keylength;
+ volume_key = cd->volume_key->key;
+ }
- if (!r && name)
- r = open_from_hdr_and_vk(cd, vk, name, flags);
+ vk = crypt_alloc_volume_key(volume_key_size, volume_key);
+ if (!vk)
+ return -ENOMEM;
+ r = LUKS_verify_volume_key(&cd->hdr, vk);
+
+ if (r == -EPERM)
+ log_err(cd, _("Volume key does not match the volume.\n"));
+
+ if (!r && name)
+ r = LUKS1_activate(cd, name, vk, flags);
+ } else
+ log_err(cd, _("Device type is not properly initialised.\n"));
crypt_free_volume_key(vk);
const char *passphrase,
size_t passphrase_size)
{
- struct volume_key *vk;
- char *processed_key = NULL;
+ struct volume_key *vk = NULL;
unsigned key_len;
- int r;
+ int r = -EINVAL;
key_len = crypt_get_volume_key_size(cd);
if (key_len > *volume_key_size) {
}
if (isPLAIN(cd->type) && cd->plain_hdr.hash) {
- processed_key = process_key(cd, cd->plain_hdr.hash, NULL, key_len,
- passphrase, passphrase_size);
- if (!processed_key) {
+ r = process_key(cd, cd->plain_hdr.hash, key_len,
+ passphrase, passphrase_size, &vk);
+ if (r < 0)
log_err(cd, _("Cannot retrieve volume key for plain device.\n"));
- return -EINVAL;
- }
- memcpy(volume_key, processed_key, key_len);
- *volume_key_size = key_len;
- crypt_safe_free(processed_key);
- return 0;
- }
-
- if (isLUKS(cd->type)) {
+ } else if (isLUKS(cd->type)) {
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
passphrase_size, &cd->hdr, &vk, cd);
- if (r >= 0) {
- memcpy(volume_key, vk->key, vk->keylength);
- *volume_key_size = vk->keylength;
- }
+ } else
+ log_err(cd, _("This operation is not supported for %s crypt device.\n"), cd->type ?: "(none)");
- crypt_free_volume_key(vk);
- return r;
+ if (r >= 0) {
+ memcpy(volume_key, vk->key, vk->keylength);
+ *volume_key_size = vk->keylength;
}
- log_err(cd, _("This operation is not supported for %s crypt device.\n"), cd->type ?: "(none)");
- return -EINVAL;
+ crypt_free_volume_key(vk);
+ return r;
}
int crypt_volume_key_verify(struct crypt_device *cd,
const char *name,
struct crypt_active_device *cad)
{
- int r, readonly;
+ struct crypt_dm_active_device dmd;
+ int r;
- r = dm_query_device(name, NULL, &cad->size, &cad->iv_offset, &cad->offset,
- NULL, NULL, NULL, &readonly, NULL, NULL);
+ r = dm_query_device(name, 0, &dmd);
if (r < 0)
return r;
- cad->flags = readonly ? CRYPT_ACTIVATE_READONLY : 0;
+ cad->offset = dmd.offset;
+ cad->iv_offset = dmd.iv_offset;
+ cad->size = dmd.size;
+ cad->flags = dmd.flags;
return 0;
}