mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-16 05:10:03 +01:00
* Add --header option for detached metadata (on-disk LUKS header) device.
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API. git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@575 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
* Do not allow key retrieval while suspended (key could be wiped).
|
* Do not allow key retrieval while suspended (key could be wiped).
|
||||||
* Do not allow suspend for non-LUKS devices.
|
* Do not allow suspend for non-LUKS devices.
|
||||||
* Support retries and timeout parameters for luksSuspend.
|
* Support retries and timeout parameters for luksSuspend.
|
||||||
|
* Add --header option for detached metadata (on-disk LUKS header) device.
|
||||||
|
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API.
|
||||||
|
|
||||||
2011-07-07 Milan Broz <mbroz@redhat.com>
|
2011-07-07 Milan Broz <mbroz@redhat.com>
|
||||||
* Remove old API functions (all functions using crypt_options).
|
* Remove old API functions (all functions using crypt_options).
|
||||||
|
|||||||
@@ -22,14 +22,23 @@ struct crypt_device; /* crypt device handle */
|
|||||||
int crypt_init(struct crypt_device **cd, const char *device);
|
int crypt_init(struct crypt_device **cd, const char *device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise crypt device handle from provided active device name
|
* Initialise crypt device handle from provided active device name,
|
||||||
|
* and, optionally, from separate metadata (header) device
|
||||||
* and check if provided device exists.
|
* and check if provided device exists.
|
||||||
*
|
*
|
||||||
* Returns 0 on success or negative errno value otherwise.
|
* Returns 0 on success or negative errno value otherwise.
|
||||||
*
|
*
|
||||||
* @cd - crypt device handle
|
* @cd - crypt device handle
|
||||||
* @name - name of active crypt device
|
* @name - name of active crypt device
|
||||||
|
* @header_device - optional device containing on-disk header
|
||||||
|
* (NULL if it the same as underlying device on there is no on-disk header)
|
||||||
|
*
|
||||||
|
* crypt_init_by_name is quivalent to calling
|
||||||
|
* crypt_init_by_name_and_header(cd, name, NULL);
|
||||||
*/
|
*/
|
||||||
|
int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||||
|
const char *name,
|
||||||
|
const char *header_device);
|
||||||
int crypt_init_by_name(struct crypt_device **cd, const char *name);
|
int crypt_init_by_name(struct crypt_device **cd, const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,6 +121,13 @@ void crypt_set_password_retry(struct crypt_device *cd, int tries);
|
|||||||
void crypt_set_iterarion_time(struct crypt_device *cd, uint64_t iteration_time_ms);
|
void crypt_set_iterarion_time(struct crypt_device *cd, uint64_t iteration_time_ms);
|
||||||
void crypt_set_password_verify(struct crypt_device *cd, int password_verify);
|
void crypt_set_password_verify(struct crypt_device *cd, int password_verify);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set data device (ciphertext device) if LUKS header is separated
|
||||||
|
* @cd - crypt device handle
|
||||||
|
* @device - path to device
|
||||||
|
*/
|
||||||
|
int crypt_set_data_device(struct crypt_device *cd, const char *device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set which RNG (random number generator) is used for generating long term key
|
* Set which RNG (random number generator) is used for generating long term key
|
||||||
* @cd - crypt device handle
|
* @cd - crypt device handle
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ CRYPTSETUP_1.0 {
|
|||||||
global:
|
global:
|
||||||
crypt_init;
|
crypt_init;
|
||||||
crypt_init_by_name;
|
crypt_init_by_name;
|
||||||
|
crypt_init_by_name_and_header;
|
||||||
crypt_set_log_callback;
|
crypt_set_log_callback;
|
||||||
crypt_set_confirm_callback;
|
crypt_set_confirm_callback;
|
||||||
crypt_set_password_callback;
|
crypt_set_password_callback;
|
||||||
@@ -10,6 +11,7 @@ CRYPTSETUP_1.0 {
|
|||||||
crypt_set_iterarion_time;
|
crypt_set_iterarion_time;
|
||||||
crypt_set_password_verify;
|
crypt_set_password_verify;
|
||||||
crypt_set_uuid;
|
crypt_set_uuid;
|
||||||
|
crypt_set_data_device;
|
||||||
|
|
||||||
crypt_memory_lock;
|
crypt_memory_lock;
|
||||||
crypt_format;
|
crypt_format;
|
||||||
|
|||||||
235
lib/setup.c
235
lib/setup.c
@@ -36,6 +36,8 @@ struct crypt_device {
|
|||||||
char *type;
|
char *type;
|
||||||
|
|
||||||
char *device;
|
char *device;
|
||||||
|
char *metadata_device;
|
||||||
|
|
||||||
char *backing_file;
|
char *backing_file;
|
||||||
int loop_fd;
|
int loop_fd;
|
||||||
struct volume_key *volume_key;
|
struct volume_key *volume_key;
|
||||||
@@ -118,6 +120,11 @@ void logger(struct crypt_device *cd, int level, const char *file,
|
|||||||
free(target);
|
free(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *mdata_device(struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
return cd->metadata_device ?: cd->device;
|
||||||
|
}
|
||||||
|
|
||||||
static int init_crypto(struct crypt_device *ctx)
|
static int init_crypto(struct crypt_device *ctx)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@@ -273,7 +280,7 @@ static int key_from_terminal(struct crypt_device *cd, char *msg, char **key,
|
|||||||
|
|
||||||
*key = NULL;
|
*key = NULL;
|
||||||
if(!msg && asprintf(&prompt, _("Enter passphrase for %s: "),
|
if(!msg && asprintf(&prompt, _("Enter passphrase for %s: "),
|
||||||
cd->backing_file ?: cd->device) < 0)
|
cd->backing_file ?: crypt_get_device_name(cd)) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@@ -317,7 +324,7 @@ static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslo
|
|||||||
if(r < 0)
|
if(r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
|
||||||
passphrase_size_read, &cd->hdr, vk, cd);
|
passphrase_size_read, &cd->hdr, vk, cd);
|
||||||
if (r == -EPERM)
|
if (r == -EPERM)
|
||||||
eperm = 1;
|
eperm = 1;
|
||||||
@@ -469,7 +476,42 @@ bad:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypt_init_by_name(struct crypt_device **cd, const char *name)
|
int crypt_set_data_device(struct crypt_device *cd, const char *device)
|
||||||
|
{
|
||||||
|
char *data_device;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
log_dbg("Setting ciphertext data device to %s.", device ?: "(none)");
|
||||||
|
|
||||||
|
if (!isLUKS(cd->type)) {
|
||||||
|
log_err(cd, _("This operation is not supported for this device type.\n"));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* metadata device must be set */
|
||||||
|
if (!cd->device)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = device_ready(NULL, device, O_RDONLY);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (!(data_device = strdup(device)))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!cd->metadata_device)
|
||||||
|
cd->metadata_device = cd->device;
|
||||||
|
else
|
||||||
|
free(cd->device);
|
||||||
|
|
||||||
|
cd->device = data_device;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||||
|
const char *name,
|
||||||
|
const char *header_device)
|
||||||
{
|
{
|
||||||
crypt_status_info ci;
|
crypt_status_info ci;
|
||||||
struct crypt_dm_active_device dmd;
|
struct crypt_dm_active_device dmd;
|
||||||
@@ -494,23 +536,46 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
*cd = NULL;
|
*cd = NULL;
|
||||||
r = crypt_init(cd, dmd.device);
|
|
||||||
|
|
||||||
/* Underlying device disappeared but mapping still active */
|
if (header_device) {
|
||||||
if (!dmd.device || r == -ENOTBLK)
|
r = crypt_init(cd, header_device);
|
||||||
log_verbose(NULL, _("Underlying device for crypt device %s disappeared.\n"),
|
} else {
|
||||||
name);
|
r = crypt_init(cd, dmd.device);
|
||||||
|
|
||||||
/* Underlying device is not readable but crypt mapping exists */
|
/* Underlying device disappeared but mapping still active */
|
||||||
if (r == -ENOTBLK) {
|
if (!dmd.device || r == -ENOTBLK)
|
||||||
free((char*)dmd.device);
|
log_verbose(NULL, _("Underlying device for crypt device %s disappeared.\n"),
|
||||||
dmd.device = NULL;
|
name);
|
||||||
r = crypt_init(cd, NULL);
|
|
||||||
|
/* Underlying device is not readable but crypt mapping exists */
|
||||||
|
if (r == -ENOTBLK) {
|
||||||
|
free((char*)dmd.device);
|
||||||
|
dmd.device = NULL;
|
||||||
|
r = crypt_init(cd, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (dmd.uuid) {
|
||||||
|
if (!strncmp(CRYPT_PLAIN, dmd.uuid, sizeof(CRYPT_PLAIN)-1))
|
||||||
|
(*cd)->type = strdup(CRYPT_PLAIN);
|
||||||
|
else if (!strncmp(CRYPT_LOOPAES, dmd.uuid, sizeof(CRYPT_LOOPAES)-1))
|
||||||
|
(*cd)->type = strdup(CRYPT_LOOPAES);
|
||||||
|
else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1))
|
||||||
|
(*cd)->type = strdup(CRYPT_LUKS1);
|
||||||
|
else
|
||||||
|
log_dbg("Unknown UUID set, some parameters are not set.");
|
||||||
|
} else
|
||||||
|
log_dbg("Active device has no UUID set, some parameters are not set.");
|
||||||
|
|
||||||
|
if (header_device) {
|
||||||
|
r = crypt_set_data_device(*cd, dmd.device);
|
||||||
|
if (r < 0)
|
||||||
|
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.device && crypt_loop_device(dmd.device) &&
|
||||||
@@ -519,46 +584,45 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dmd.uuid) {
|
if (isPLAIN((*cd)->type)) {
|
||||||
if (!strncmp(CRYPT_PLAIN, dmd.uuid, sizeof(CRYPT_PLAIN)-1)) {
|
(*cd)->type = strdup(CRYPT_PLAIN);
|
||||||
(*cd)->type = strdup(CRYPT_PLAIN);
|
(*cd)->plain_uuid = strdup(dmd.uuid);
|
||||||
(*cd)->plain_uuid = strdup(dmd.uuid);
|
(*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.offset;
|
(*cd)->plain_hdr.skip = dmd.iv_offset;
|
||||||
(*cd)->plain_hdr.skip = dmd.iv_offset;
|
|
||||||
|
|
||||||
r = crypt_parse_name_and_mode(dmd.cipher, cipher, NULL, cipher_mode);
|
r = crypt_parse_name_and_mode(dmd.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 (!strncmp(CRYPT_LOOPAES, dmd.uuid, sizeof(CRYPT_LOOPAES)-1)) {
|
} else if (isLOOPAES((*cd)->type)) {
|
||||||
(*cd)->type = strdup(CRYPT_LOOPAES);
|
(*cd)->type = strdup(CRYPT_LOOPAES);
|
||||||
(*cd)->loopaes_uuid = strdup(dmd.uuid);
|
(*cd)->loopaes_uuid = strdup(dmd.uuid);
|
||||||
(*cd)->loopaes_hdr.offset = dmd.offset;
|
(*cd)->loopaes_hdr.offset = dmd.offset;
|
||||||
|
|
||||||
r = crypt_parse_name_and_mode(dmd.cipher, cipher,
|
r = crypt_parse_name_and_mode(dmd.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.vk->keylength % key_nums)
|
||||||
key_nums++;
|
key_nums++;
|
||||||
(*cd)->loopaes_key_size = dmd.vk->keylength / key_nums;
|
(*cd)->loopaes_key_size = dmd.vk->keylength / key_nums;
|
||||||
}
|
}
|
||||||
} else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1)) {
|
} else if (isLUKS((*cd)->type)) {
|
||||||
if (dmd.device) {
|
if (mdata_device(*cd)) {
|
||||||
r = crypt_load(*cd, CRYPT_LUKS1, NULL);
|
r = crypt_load(*cd, CRYPT_LUKS1, NULL);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_dbg("LUKS device header does not match active device.");
|
log_dbg("LUKS device header does not match active device.");
|
||||||
/* initialise empty context */
|
free((*cd)->type);
|
||||||
r = 0;
|
(*cd)->type = NULL;
|
||||||
}
|
r = 0;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
log_dbg("Active device has no UUID set, some parameters are not set.");
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -572,6 +636,11 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int crypt_init_by_name(struct crypt_device **cd, const char *name)
|
||||||
|
{
|
||||||
|
return crypt_init_by_name_and_header(cd, name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int _crypt_format_plain(struct crypt_device *cd,
|
static int _crypt_format_plain(struct crypt_device *cd,
|
||||||
const char *cipher,
|
const char *cipher,
|
||||||
const char *cipher_mode,
|
const char *cipher_mode,
|
||||||
@@ -624,7 +693,7 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
|||||||
unsigned long required_alignment = DEFAULT_DISK_ALIGNMENT;
|
unsigned long required_alignment = DEFAULT_DISK_ALIGNMENT;
|
||||||
unsigned long alignment_offset = 0;
|
unsigned long alignment_offset = 0;
|
||||||
|
|
||||||
if (!cd->device) {
|
if (!mdata_device(cd)) {
|
||||||
log_err(cd, _("Can't format LUKS without device.\n"));
|
log_err(cd, _("Can't format LUKS without device.\n"));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -638,6 +707,7 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
|||||||
if(!cd->volume_key)
|
if(!cd->volume_key)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
//FIXME: external metadata, ignore alignment
|
||||||
if (params && params->data_alignment)
|
if (params && params->data_alignment)
|
||||||
required_alignment = params->data_alignment * SECTOR_SIZE;
|
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||||
else
|
else
|
||||||
@@ -654,19 +724,19 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* Wipe first 8 sectors - fs magic numbers etc. */
|
/* Wipe first 8 sectors - fs magic numbers etc. */
|
||||||
r = wipe_device_header(cd->device, 8);
|
r = wipe_device_header(mdata_device(cd), 8);
|
||||||
if(r < 0) {
|
if(r < 0) {
|
||||||
if (r == -EBUSY)
|
if (r == -EBUSY)
|
||||||
log_err(cd, _("Cannot format device %s which is still in use.\n"),
|
log_err(cd, _("Cannot format device %s which is still in use.\n"),
|
||||||
cd->device);
|
mdata_device(cd));
|
||||||
else
|
else
|
||||||
log_err(cd, _("Cannot wipe header on device %s.\n"),
|
log_err(cd, _("Cannot wipe header on device %s.\n"),
|
||||||
cd->device);
|
mdata_device(cd));
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = LUKS_write_phdr(cd->device, &cd->hdr, cd);
|
r = LUKS_write_phdr(mdata_device(cd), &cd->hdr, cd);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -677,7 +747,7 @@ static int _crypt_format_loopaes(struct crypt_device *cd,
|
|||||||
size_t volume_key_size,
|
size_t volume_key_size,
|
||||||
struct crypt_params_loopaes *params)
|
struct crypt_params_loopaes *params)
|
||||||
{
|
{
|
||||||
if (!cd->device) {
|
if (!mdata_device(cd)) {
|
||||||
log_err(cd, _("Can't format LOOPAES without device.\n"));
|
log_err(cd, _("Can't format LOOPAES without device.\n"));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -717,7 +787,7 @@ int crypt_format(struct crypt_device *cd,
|
|||||||
if (!type)
|
if (!type)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
log_dbg("Formatting device %s as type %s.", cd->device ?: "(none)", type);
|
log_dbg("Formatting device %s as type %s.", mdata_device(cd) ?: "(none)", type);
|
||||||
|
|
||||||
r = init_crypto(cd);
|
r = init_crypto(cd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -756,9 +826,9 @@ int crypt_load(struct crypt_device *cd,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
log_dbg("Trying to load %s crypt type from device %s.",
|
log_dbg("Trying to load %s crypt type from device %s.",
|
||||||
requested_type ?: "any", cd->device ?: "(none)");
|
requested_type ?: "any", mdata_device(cd) ?: "(none)");
|
||||||
|
|
||||||
if (!cd->device)
|
if (!mdata_device(cd))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (requested_type && !isLUKS(requested_type))
|
if (requested_type && !isLUKS(requested_type))
|
||||||
@@ -768,10 +838,11 @@ int crypt_load(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = LUKS_read_phdr(cd->device, &hdr, 1, cd);
|
r = LUKS_read_phdr(mdata_device(cd), &hdr, 1, cd);
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
memcpy(&cd->hdr, &hdr, sizeof(hdr));
|
memcpy(&cd->hdr, &hdr, sizeof(hdr));
|
||||||
|
free(cd->type);
|
||||||
cd->type = strdup(CRYPT_LUKS1);
|
cd->type = strdup(CRYPT_LUKS1);
|
||||||
if (!cd->type)
|
if (!cd->type)
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
@@ -834,19 +905,19 @@ int crypt_set_uuid(struct crypt_device *cd, const char *uuid)
|
|||||||
|
|
||||||
if (uuid && !strncmp(uuid, cd->hdr.uuid, sizeof(cd->hdr.uuid))) {
|
if (uuid && !strncmp(uuid, cd->hdr.uuid, sizeof(cd->hdr.uuid))) {
|
||||||
log_dbg("UUID is the same as requested (%s) for device %s.",
|
log_dbg("UUID is the same as requested (%s) for device %s.",
|
||||||
uuid, cd->device);
|
uuid, mdata_device(cd));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uuid)
|
if (uuid)
|
||||||
log_dbg("Requested new UUID change to %s for %s.", uuid, cd->device);
|
log_dbg("Requested new UUID change to %s for %s.", uuid, mdata_device(cd));
|
||||||
else
|
else
|
||||||
log_dbg("Requested new UUID refresh for %s.", cd->device);
|
log_dbg("Requested new UUID refresh for %s.", mdata_device(cd));
|
||||||
|
|
||||||
if (!crypt_confirm(cd, _("Do you really want to change UUID of device?")))
|
if (!crypt_confirm(cd, _("Do you really want to change UUID of device?")))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
return LUKS_hdr_uuid_set(cd->device, &cd->hdr, uuid, cd);
|
return LUKS_hdr_uuid_set(mdata_device(cd), &cd->hdr, uuid, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypt_header_backup(struct crypt_device *cd,
|
int crypt_header_backup(struct crypt_device *cd,
|
||||||
@@ -863,9 +934,9 @@ int crypt_header_backup(struct crypt_device *cd,
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
log_dbg("Requested header backup of device %s (%s) to "
|
log_dbg("Requested header backup of device %s (%s) to "
|
||||||
"file %s.", cd->device, requested_type, backup_file);
|
"file %s.", mdata_device(cd), requested_type, backup_file);
|
||||||
|
|
||||||
return LUKS_hdr_backup(backup_file, cd->device, &cd->hdr, cd);
|
return LUKS_hdr_backup(backup_file, mdata_device(cd), &cd->hdr, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypt_header_restore(struct crypt_device *cd,
|
int crypt_header_restore(struct crypt_device *cd,
|
||||||
@@ -883,15 +954,15 @@ int crypt_header_restore(struct crypt_device *cd,
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
log_dbg("Requested header restore to device %s (%s) from "
|
log_dbg("Requested header restore to device %s (%s) from "
|
||||||
"file %s.", cd->device, requested_type, backup_file);
|
"file %s.", mdata_device(cd), requested_type, backup_file);
|
||||||
|
|
||||||
return LUKS_hdr_restore(backup_file, cd->device, &cd->hdr, cd);
|
return LUKS_hdr_restore(backup_file, mdata_device(cd), &cd->hdr, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void crypt_free(struct crypt_device *cd)
|
void crypt_free(struct crypt_device *cd)
|
||||||
{
|
{
|
||||||
if (cd) {
|
if (cd) {
|
||||||
log_dbg("Releasing crypt device %s context.", cd->device);
|
log_dbg("Releasing crypt device %s context.", mdata_device(cd));
|
||||||
|
|
||||||
if (cd->loop_fd != -1)
|
if (cd->loop_fd != -1)
|
||||||
close(cd->loop_fd);
|
close(cd->loop_fd);
|
||||||
@@ -900,6 +971,7 @@ void crypt_free(struct crypt_device *cd)
|
|||||||
crypt_free_volume_key(cd->volume_key);
|
crypt_free_volume_key(cd->volume_key);
|
||||||
|
|
||||||
free(cd->device);
|
free(cd->device);
|
||||||
|
free(cd->metadata_device);
|
||||||
free(cd->backing_file);
|
free(cd->backing_file);
|
||||||
free(cd->type);
|
free(cd->type);
|
||||||
|
|
||||||
@@ -989,7 +1061,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (passphrase) {
|
if (passphrase) {
|
||||||
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase,
|
||||||
passphrase_size, &cd->hdr, &vk, cd);
|
passphrase_size, &cd->hdr, &vk, cd);
|
||||||
} else
|
} else
|
||||||
r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
|
r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
|
||||||
@@ -1044,7 +1116,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
|
||||||
passphrase_size_read, &cd->hdr, &vk, cd);
|
passphrase_size_read, &cd->hdr, &vk, cd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1096,7 +1168,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
} else if (passphrase) {
|
} else if (passphrase) {
|
||||||
/* Passphrase provided, use it to unlock existing keyslot */
|
/* Passphrase provided, use it to unlock existing keyslot */
|
||||||
r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, passphrase,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), CRYPT_ANY_SLOT, passphrase,
|
||||||
passphrase_size, &cd->hdr, &vk, cd);
|
passphrase_size, &cd->hdr, &vk, cd);
|
||||||
} else {
|
} else {
|
||||||
/* Passphrase not provided, ask first and use it to unlock existing keyslot */
|
/* Passphrase not provided, ask first and use it to unlock existing keyslot */
|
||||||
@@ -1105,7 +1177,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), CRYPT_ANY_SLOT, password,
|
||||||
passwordLen, &cd->hdr, &vk, cd);
|
passwordLen, &cd->hdr, &vk, cd);
|
||||||
crypt_safe_free(password);
|
crypt_safe_free(password);
|
||||||
}
|
}
|
||||||
@@ -1123,7 +1195,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = LUKS_set_key(cd->device, keyslot, new_password, new_passwordLen,
|
r = LUKS_set_key(mdata_device(cd), keyslot, new_password, new_passwordLen,
|
||||||
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
||||||
if(r < 0) goto out;
|
if(r < 0) goto out;
|
||||||
|
|
||||||
@@ -1180,7 +1252,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, passwordLen,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), CRYPT_ANY_SLOT, password, passwordLen,
|
||||||
&cd->hdr, &vk, cd);
|
&cd->hdr, &vk, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1197,7 +1269,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = LUKS_set_key(cd->device, keyslot, new_password, new_passwordLen,
|
r = LUKS_set_key(mdata_device(cd), keyslot, new_password, new_passwordLen,
|
||||||
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
||||||
out:
|
out:
|
||||||
crypt_safe_free(password);
|
crypt_safe_free(password);
|
||||||
@@ -1251,7 +1323,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
|
|||||||
passphrase_size = new_passwordLen;
|
passphrase_size = new_passwordLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = LUKS_set_key(cd->device, keyslot, passphrase, passphrase_size,
|
r = LUKS_set_key(mdata_device(cd), keyslot, passphrase, passphrase_size,
|
||||||
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
||||||
out:
|
out:
|
||||||
crypt_safe_free(new_password);
|
crypt_safe_free(new_password);
|
||||||
@@ -1281,7 +1353,7 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LUKS_del_key(cd->device, keyslot, &cd->hdr, cd);
|
return LUKS_del_key(mdata_device(cd), keyslot, &cd->hdr, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// activation/deactivation of device mapping
|
// activation/deactivation of device mapping
|
||||||
@@ -1337,7 +1409,7 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
|
|||||||
} else if (isLUKS(cd->type)) {
|
} else if (isLUKS(cd->type)) {
|
||||||
/* provided passphrase, do not retry */
|
/* provided passphrase, do not retry */
|
||||||
if (passphrase) {
|
if (passphrase) {
|
||||||
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase,
|
||||||
passphrase_size, &cd->hdr, &vk, cd);
|
passphrase_size, &cd->hdr, &vk, cd);
|
||||||
} else
|
} else
|
||||||
r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
|
r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
|
||||||
@@ -1408,7 +1480,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
|
|||||||
&passphrase_size_read, keyfile, keyfile_size);
|
&passphrase_size_read, keyfile, keyfile_size);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
|
||||||
passphrase_size_read, &cd->hdr, &vk, cd);
|
passphrase_size_read, &cd->hdr, &vk, cd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1567,7 +1639,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_err(cd, _("Cannot retrieve volume key for plain device.\n"));
|
log_err(cd, _("Cannot retrieve volume key for plain device.\n"));
|
||||||
} else if (isLUKS(cd->type)) {
|
} else if (isLUKS(cd->type)) {
|
||||||
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
|
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase,
|
||||||
passphrase_size, &cd->hdr, &vk, cd);
|
passphrase_size, &cd->hdr, &vk, cd);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
@@ -1695,7 +1767,7 @@ int crypt_dump(struct crypt_device *cd)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_std(cd, "LUKS header information for %s\n\n", cd->device);
|
log_std(cd, "LUKS header information for %s\n\n", mdata_device(cd));
|
||||||
log_std(cd, "Version: \t%d\n", cd->hdr.version);
|
log_std(cd, "Version: \t%d\n", cd->hdr.version);
|
||||||
log_std(cd, "Cipher name: \t%s\n", cd->hdr.cipherName);
|
log_std(cd, "Cipher name: \t%s\n", cd->hdr.cipherName);
|
||||||
log_std(cd, "Cipher mode: \t%s\n", cd->hdr.cipherMode);
|
log_std(cd, "Cipher mode: \t%s\n", cd->hdr.cipherMode);
|
||||||
@@ -1784,6 +1856,7 @@ const char *crypt_get_device_name(struct crypt_device *cd)
|
|||||||
return cd->device;
|
return cd->device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int crypt_get_volume_key_size(struct crypt_device *cd)
|
int crypt_get_volume_key_size(struct crypt_device *cd)
|
||||||
{
|
{
|
||||||
if (isPLAIN(cd->type) && cd->volume_key)
|
if (isPLAIN(cd->type) && cd->volume_key)
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ opens the LUKS partition <device> and sets up a mapping <name> after
|
|||||||
successful verification of the supplied key material
|
successful verification of the supplied key material
|
||||||
(either via key file by \-\-key-file, or via prompting).
|
(either via key file by \-\-key-file, or via prompting).
|
||||||
|
|
||||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-readonly, \-\-allow-discards].
|
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-readonly, \-\-allow-discards,
|
||||||
|
\-\-header].
|
||||||
.PP
|
.PP
|
||||||
\fIluksClose\fR <name>
|
\fIluksClose\fR <name>
|
||||||
.IP
|
.IP
|
||||||
@@ -67,13 +68,15 @@ After that operation you have to use \fIluksResume\fR to reinstate
|
|||||||
encryption key (and resume device) or \fIluksClose\fR to remove mapped device.
|
encryption key (and resume device) or \fIluksClose\fR to remove mapped device.
|
||||||
|
|
||||||
\fBWARNING:\fR never try to suspend device where is the cryptsetup binary itself.
|
\fBWARNING:\fR never try to suspend device where is the cryptsetup binary itself.
|
||||||
|
|
||||||
|
\fB<options>\fR can be [\-\-header].
|
||||||
.PP
|
.PP
|
||||||
\fIluksResume\fR <name>
|
\fIluksResume\fR <name>
|
||||||
.IP
|
.IP
|
||||||
Resumes suspended device and reinstates encryption key. You will need provide passphrase
|
Resumes suspended device and reinstates encryption key. You will need provide passphrase
|
||||||
identical to \fIluksOpen\fR command (using prompting or key file).
|
identical to \fIluksOpen\fR command (using prompting or key file).
|
||||||
|
|
||||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size]
|
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-header]
|
||||||
.PP
|
.PP
|
||||||
\fIluksAddKey\fR <device> [<new key file>]
|
\fIluksAddKey\fR <device> [<new key file>]
|
||||||
.IP
|
.IP
|
||||||
@@ -374,6 +377,20 @@ if the discarded blocks can be located easily on the device later.
|
|||||||
Kernel version 3.1 or more recent is required.
|
Kernel version 3.1 or more recent is required.
|
||||||
For older versions is the option ignored.
|
For older versions is the option ignored.
|
||||||
.TP
|
.TP
|
||||||
|
.B "\-\-header\fR"
|
||||||
|
Set detached (separated) metadata device or file with LUKS header.
|
||||||
|
|
||||||
|
This options allows separation of ciphertext device and on-disk metadata header.
|
||||||
|
|
||||||
|
This option is only relevant for LUKS devices and can be used in \fIluksOpen\fR,
|
||||||
|
\fIluksSuspend\fR, \fIluksResume\fR and \fIresize\fR commands.
|
||||||
|
|
||||||
|
For other commands with separated metadata device you have to always specify
|
||||||
|
path to metadata device (not to the ciphertext device).
|
||||||
|
|
||||||
|
\fBWARNING:\fR There is no possible check that specified ciphertext device
|
||||||
|
is correct if on-disk header is detached. Use with care.
|
||||||
|
.TP
|
||||||
.B "\-\-version"
|
.B "\-\-version"
|
||||||
Show the version.
|
Show the version.
|
||||||
.SH RETURN CODES
|
.SH RETURN CODES
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ static const char *opt_key_file = NULL;
|
|||||||
static const char *opt_master_key_file = NULL;
|
static const char *opt_master_key_file = NULL;
|
||||||
static const char *opt_header_backup_file = NULL;
|
static const char *opt_header_backup_file = NULL;
|
||||||
static const char *opt_uuid = NULL;
|
static const char *opt_uuid = NULL;
|
||||||
|
static const char *opt_header_device = NULL;
|
||||||
static int opt_key_size = 0;
|
static int opt_key_size = 0;
|
||||||
static long opt_keyfile_size = 0;
|
static long opt_keyfile_size = 0;
|
||||||
static long opt_new_keyfile_size = 0;
|
static long opt_new_keyfile_size = 0;
|
||||||
@@ -356,7 +357,7 @@ static int action_resize(int arg __attribute__((unused)))
|
|||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = crypt_init_by_name(&cd, action_argv[0]);
|
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
r = crypt_resize(cd, action_argv[0], opt_size);
|
r = crypt_resize(cd, action_argv[0], opt_size);
|
||||||
|
|
||||||
@@ -520,15 +521,28 @@ out:
|
|||||||
static int action_luksOpen(int arg __attribute__((unused)))
|
static int action_luksOpen(int arg __attribute__((unused)))
|
||||||
{
|
{
|
||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
|
const char *data_device, *header_device;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if ((r = crypt_init(&cd, action_argv[0])))
|
if (opt_header_device) {
|
||||||
|
header_device = opt_header_device;
|
||||||
|
data_device = action_argv[0];
|
||||||
|
} else {
|
||||||
|
header_device = action_argv[0];
|
||||||
|
data_device = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((r = crypt_init(&cd, header_device)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (data_device &&
|
||||||
|
(r = crypt_set_data_device(cd, data_device)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
crypt_set_timeout(cd, opt_timeout);
|
crypt_set_timeout(cd, opt_timeout);
|
||||||
crypt_set_password_retry(cd, opt_tries);
|
crypt_set_password_retry(cd, opt_tries);
|
||||||
|
|
||||||
@@ -942,7 +956,7 @@ static int action_luksSuspend(int arg __attribute__((unused)))
|
|||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = crypt_init_by_name(&cd, action_argv[0]);
|
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
|
||||||
if (!r)
|
if (!r)
|
||||||
r = crypt_suspend(cd, action_argv[0]);
|
r = crypt_suspend(cd, action_argv[0]);
|
||||||
|
|
||||||
@@ -955,7 +969,7 @@ static int action_luksResume(int arg __attribute__((unused)))
|
|||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if ((r = crypt_init_by_name(&cd, action_argv[0])))
|
if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
crypt_set_timeout(cd, opt_timeout);
|
crypt_set_timeout(cd, opt_timeout);
|
||||||
@@ -1156,6 +1170,7 @@ int main(int argc, const char **argv)
|
|||||||
{ "shared", '\0', POPT_ARG_NONE, &opt_shared, 0, N_("Share device with another non-overlapping crypt segment."), NULL },
|
{ "shared", '\0', POPT_ARG_NONE, &opt_shared, 0, N_("Share device with another non-overlapping crypt segment."), NULL },
|
||||||
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
|
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
|
||||||
{ "allow-discards", '\0', POPT_ARG_NONE, &opt_allow_discards, 0, N_("Allow discards (aka TRIM) requests for device."), NULL },
|
{ "allow-discards", '\0', POPT_ARG_NONE, &opt_allow_discards, 0, N_("Allow discards (aka TRIM) requests for device."), NULL },
|
||||||
|
{ "header", '\0', POPT_ARG_STRING, &opt_header_device, 0, N_("Device or file with separated LUKS header."), NULL },
|
||||||
POPT_TABLEEND
|
POPT_TABLEEND
|
||||||
};
|
};
|
||||||
poptContext popt_context;
|
poptContext popt_context;
|
||||||
|
|||||||
Reference in New Issue
Block a user