mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 16:30:04 +01:00
* Allow different data offset setting for detached header.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@576 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
* 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 --header option for detached metadata (on-disk LUKS header) device.
|
||||||
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API.
|
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API.
|
||||||
|
* Allow different data offset setting for detached header.
|
||||||
|
|
||||||
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).
|
||||||
|
|||||||
1
TODO
1
TODO
@@ -1,4 +1,3 @@
|
|||||||
Version 1.4.0:
|
Version 1.4.0:
|
||||||
- Support separation of metadata device
|
|
||||||
- Wipe device flag
|
- Wipe device flag
|
||||||
- Support K/M suffixes for align payload (new switch?).
|
- Support K/M suffixes for align payload (new switch?).
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ ssize_t write_blockwise(int fd, void *buf, size_t count);
|
|||||||
ssize_t read_blockwise(int fd, void *_buf, size_t count);
|
ssize_t read_blockwise(int fd, void *_buf, size_t count);
|
||||||
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset);
|
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset);
|
||||||
int device_ready(struct crypt_device *cd, const char *device, int mode);
|
int device_ready(struct crypt_device *cd, const char *device, int mode);
|
||||||
|
int device_size(const char *device, uint64_t *size);
|
||||||
|
|
||||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||||
int device_check_and_adjust(struct crypt_device *cd,
|
int device_check_and_adjust(struct crypt_device *cd,
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ struct crypt_params_plain {
|
|||||||
struct crypt_params_luks1 {
|
struct crypt_params_luks1 {
|
||||||
const char *hash; /* hash used in LUKS header */
|
const char *hash; /* hash used in LUKS header */
|
||||||
size_t data_alignment; /* in sectors, data offset is multiple of this */
|
size_t data_alignment; /* in sectors, data offset is multiple of this */
|
||||||
|
const char *data_device; /* detached ciphertext device or NULL */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct crypt_params_loopaes {
|
struct crypt_params_loopaes {
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -313,7 +311,6 @@ int LUKS_read_phdr(const char *device,
|
|||||||
{
|
{
|
||||||
ssize_t hdr_size = sizeof(struct luks_phdr);
|
ssize_t hdr_size = sizeof(struct luks_phdr);
|
||||||
int devfd = 0, r = 0;
|
int devfd = 0, r = 0;
|
||||||
uint64_t size;
|
|
||||||
|
|
||||||
log_dbg("Reading LUKS header of size %d from device %s",
|
log_dbg("Reading LUKS header of size %d from device %s",
|
||||||
hdr_size, device);
|
hdr_size, device);
|
||||||
@@ -329,15 +326,7 @@ int LUKS_read_phdr(const char *device,
|
|||||||
else
|
else
|
||||||
r = _check_and_convert_hdr(device, hdr, require_luks_device, ctx);
|
r = _check_and_convert_hdr(device, hdr, require_luks_device, ctx);
|
||||||
|
|
||||||
#ifdef BLKGETSIZE64
|
|
||||||
if (r == 0 && (ioctl(devfd, BLKGETSIZE64, &size) < 0 ||
|
|
||||||
size < (uint64_t)hdr->payloadOffset)) {
|
|
||||||
log_err(ctx, _("LUKS header detected but device %s is too small.\n"), device);
|
|
||||||
r = -EINVAL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
close(devfd);
|
close(devfd);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +402,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
|||||||
unsigned int alignOffset,
|
unsigned int alignOffset,
|
||||||
uint32_t iteration_time_ms,
|
uint32_t iteration_time_ms,
|
||||||
uint64_t *PBKDF2_per_sec,
|
uint64_t *PBKDF2_per_sec,
|
||||||
|
const char *metadata_device,
|
||||||
struct crypt_device *ctx)
|
struct crypt_device *ctx)
|
||||||
{
|
{
|
||||||
unsigned int i=0;
|
unsigned int i=0;
|
||||||
@@ -422,7 +412,8 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
|||||||
int currentSector;
|
int currentSector;
|
||||||
char luksMagic[] = LUKS_MAGIC;
|
char luksMagic[] = LUKS_MAGIC;
|
||||||
|
|
||||||
if (alignPayload == 0)
|
/* For separate metadata device allow zero alignment */
|
||||||
|
if (alignPayload == 0 && !metadata_device)
|
||||||
alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE;
|
alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE;
|
||||||
|
|
||||||
if (PBKDF2_HMAC_ready(hashSpec) < 0) {
|
if (PBKDF2_HMAC_ready(hashSpec) < 0) {
|
||||||
@@ -486,10 +477,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
|||||||
currentSector = round_up_modulo(currentSector + blocksPerStripeSet,
|
currentSector = round_up_modulo(currentSector + blocksPerStripeSet,
|
||||||
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||||
}
|
}
|
||||||
currentSector = round_up_modulo(currentSector, alignPayload);
|
|
||||||
|
|
||||||
/* alignOffset - offset from natural device alignment provided by topology info */
|
if (metadata_device) {
|
||||||
header->payloadOffset = currentSector + alignOffset;
|
/* for separate metadata device use alignPayload directly */
|
||||||
|
header->payloadOffset = alignPayload;
|
||||||
|
} else {
|
||||||
|
/* alignOffset - offset from natural device alignment provided by topology info */
|
||||||
|
currentSector = round_up_modulo(currentSector, alignPayload);
|
||||||
|
header->payloadOffset = currentSector + alignOffset;
|
||||||
|
}
|
||||||
|
|
||||||
uuid_unparse(partitionUuid, header->uuid);
|
uuid_unparse(partitionUuid, header->uuid);
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ int LUKS_generate_phdr(
|
|||||||
unsigned int alignOffset,
|
unsigned int alignOffset,
|
||||||
uint32_t iteration_time_ms,
|
uint32_t iteration_time_ms,
|
||||||
uint64_t *PBKDF2_per_sec,
|
uint64_t *PBKDF2_per_sec,
|
||||||
|
const char *metadata_device,
|
||||||
struct crypt_device *ctx);
|
struct crypt_device *ctx);
|
||||||
|
|
||||||
int LUKS_read_phdr(
|
int LUKS_read_phdr(
|
||||||
|
|||||||
54
lib/setup.c
54
lib/setup.c
@@ -476,6 +476,27 @@ bad:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int crypt_check_data_device_size(struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
uint64_t size, size_min;
|
||||||
|
|
||||||
|
/* Check data device size, require at least one sector */
|
||||||
|
size_min = crypt_get_data_offset(cd) ?: SECTOR_SIZE;
|
||||||
|
|
||||||
|
r = device_size(crypt_get_device_name(cd), &size);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (size < size_min) {
|
||||||
|
log_err(cd, _("LUKS header detected but device %s is too small.\n"),
|
||||||
|
crypt_get_device_name(cd));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_set_data_device(struct crypt_device *cd, const char *device)
|
int crypt_set_data_device(struct crypt_device *cd, const char *device)
|
||||||
{
|
{
|
||||||
char *data_device;
|
char *data_device;
|
||||||
@@ -506,7 +527,7 @@ int crypt_set_data_device(struct crypt_device *cd, const char *device)
|
|||||||
|
|
||||||
cd->device = data_device;
|
cd->device = data_device;
|
||||||
|
|
||||||
return 0;
|
return crypt_check_data_device_size(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypt_init_by_name_and_header(struct crypt_device **cd,
|
int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||||
@@ -707,10 +728,14 @@ 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_device) {
|
||||||
if (params && params->data_alignment)
|
cd->metadata_device = cd->device;
|
||||||
|
if (!(cd->device = strdup(params->data_device)))
|
||||||
|
return -ENOMEM;
|
||||||
required_alignment = params->data_alignment * SECTOR_SIZE;
|
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||||
else
|
} else if (params && params->data_alignment) {
|
||||||
|
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||||
|
} else
|
||||||
get_topology_alignment(cd->device, &required_alignment,
|
get_topology_alignment(cd->device, &required_alignment,
|
||||||
&alignment_offset, DEFAULT_DISK_ALIGNMENT);
|
&alignment_offset, DEFAULT_DISK_ALIGNMENT);
|
||||||
|
|
||||||
@@ -719,7 +744,8 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
|||||||
uuid, LUKS_STRIPES,
|
uuid, LUKS_STRIPES,
|
||||||
required_alignment / SECTOR_SIZE,
|
required_alignment / SECTOR_SIZE,
|
||||||
alignment_offset / SECTOR_SIZE,
|
alignment_offset / SECTOR_SIZE,
|
||||||
cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
cd->iteration_time, &cd->PBKDF2_per_sec,
|
||||||
|
cd->metadata_device, cd);
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -839,14 +865,18 @@ int crypt_load(struct crypt_device *cd,
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = LUKS_read_phdr(mdata_device(cd), &hdr, 1, cd);
|
r = LUKS_read_phdr(mdata_device(cd), &hdr, 1, cd);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (!r) {
|
r = crypt_check_data_device_size(cd);
|
||||||
memcpy(&cd->hdr, &hdr, sizeof(hdr));
|
if (r < 0)
|
||||||
free(cd->type);
|
return r;
|
||||||
cd->type = strdup(CRYPT_LUKS1);
|
|
||||||
if (!cd->type)
|
memcpy(&cd->hdr, &hdr, sizeof(hdr));
|
||||||
r = -ENOMEM;
|
free(cd->type);
|
||||||
}
|
cd->type = strdup(CRYPT_LUKS1);
|
||||||
|
if (!cd->type)
|
||||||
|
r = -ENOMEM;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
15
lib/utils.c
15
lib/utils.c
@@ -336,6 +336,21 @@ int device_ready(struct crypt_device *cd, const char *device, int mode)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int device_size(const char *device, uint64_t *size)
|
||||||
|
{
|
||||||
|
int devfd, r = 0;
|
||||||
|
|
||||||
|
devfd = open(device, O_RDONLY);
|
||||||
|
if(devfd == -1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (ioctl(devfd, BLKGETSIZE64, size) < 0)
|
||||||
|
r = -EINVAL;
|
||||||
|
|
||||||
|
close(devfd);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_device_infos(const char *device, enum devcheck device_check,
|
static int get_device_infos(const char *device, enum devcheck device_check,
|
||||||
int *readonly, uint64_t *size)
|
int *readonly, uint64_t *size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -357,6 +357,9 @@ If not specified, cryptsetup tries to use topology info provided by kernel
|
|||||||
for underlying device to get optimal alignment.
|
for underlying device to get optimal alignment.
|
||||||
If not available (or calculated value is multiple of default) data is by
|
If not available (or calculated value is multiple of default) data is by
|
||||||
default aligned to 1 MiB boundary (2048 512-byte sectors).
|
default aligned to 1 MiB boundary (2048 512-byte sectors).
|
||||||
|
|
||||||
|
For detached LUKS header it specifies offset on data device.
|
||||||
|
See also \-\-header option.
|
||||||
.TP
|
.TP
|
||||||
.B "\-\-uuid=\fIUUID\fR"
|
.B "\-\-uuid=\fIUUID\fR"
|
||||||
Use provided \fIUUID\fR in \fIluksFormat\fR command instead of generating
|
Use provided \fIUUID\fR in \fIluksFormat\fR command instead of generating
|
||||||
@@ -382,8 +385,11 @@ Set detached (separated) metadata device or file with LUKS header.
|
|||||||
|
|
||||||
This options allows separation of ciphertext device and on-disk metadata 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,
|
This option is only relevant for LUKS devices and can be used in \fIluksFormat\fR,
|
||||||
\fIluksSuspend\fR, \fIluksResume\fR and \fIresize\fR commands.
|
\fIluksOpen\fR, \fIluksSuspend\fR, \fIluksResume\fR and \fIresize\fR commands.
|
||||||
|
|
||||||
|
If used with \fIluksFormat\fR the \-\-align-payload option is taken
|
||||||
|
as absolute sector alignment on ciphertext device and can be zero.
|
||||||
|
|
||||||
For other commands with separated metadata device you have to always specify
|
For other commands with separated metadata device you have to always specify
|
||||||
path to metadata device (not to the ciphertext device).
|
path to metadata device (not to the ciphertext device).
|
||||||
|
|||||||
@@ -449,6 +449,7 @@ fail:
|
|||||||
static int action_luksFormat(int arg __attribute__((unused)))
|
static int action_luksFormat(int arg __attribute__((unused)))
|
||||||
{
|
{
|
||||||
int r = -EINVAL, keysize;
|
int r = -EINVAL, keysize;
|
||||||
|
const char *header_device;
|
||||||
char *msg = NULL, *key = NULL, cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
char *msg = NULL, *key = NULL, cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||||
char *password = NULL;
|
char *password = NULL;
|
||||||
size_t passwordLen;
|
size_t passwordLen;
|
||||||
@@ -456,9 +457,13 @@ static int action_luksFormat(int arg __attribute__((unused)))
|
|||||||
struct crypt_params_luks1 params = {
|
struct crypt_params_luks1 params = {
|
||||||
.hash = opt_hash ?: DEFAULT_LUKS1_HASH,
|
.hash = opt_hash ?: DEFAULT_LUKS1_HASH,
|
||||||
.data_alignment = opt_align_payload,
|
.data_alignment = opt_align_payload,
|
||||||
|
.data_device = opt_header_device ? action_argv[0] : NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]) == -1) {
|
header_device = opt_header_device ?: action_argv[0];
|
||||||
|
|
||||||
|
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."),
|
||||||
|
header_device) == -1) {
|
||||||
log_err(_("memory allocation error in action_luksFormat"));
|
log_err(_("memory allocation error in action_luksFormat"));
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -475,7 +480,7 @@ static int action_luksFormat(int arg __attribute__((unused)))
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = crypt_init(&cd, action_argv[0])))
|
if ((r = crypt_init(&cd, header_device)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8;
|
keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8;
|
||||||
@@ -543,6 +548,12 @@ static int action_luksOpen(int arg __attribute__((unused)))
|
|||||||
(r = crypt_set_data_device(cd, data_device)))
|
(r = crypt_set_data_device(cd, data_device)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (!data_device && (crypt_get_data_offset(cd) < 8)) {
|
||||||
|
log_err(_("Reduced data offset is allowed only for detached LUKS header.\n"));
|
||||||
|
r = -EINVAL;
|
||||||
|
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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user