mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
New device access backend.
Allocate loop device late (only when real block device needed). Rework underlying device/file access functions. Move all device (and ioctl) access to utils_device.c. Allows using file where appropriate without allocation loop device.
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
2012-08-12 Milan Broz <gmazyland@gmail.com>
|
||||
* Allocate loop device late (only when real block device needed).
|
||||
* Rework underlying device/file access functions.
|
||||
|
||||
2012-07-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0.
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ libcryptsetup_la_SOURCES = \
|
||||
utils_wipe.c \
|
||||
utils_fips.c \
|
||||
utils_fips.h \
|
||||
utils_device.c \
|
||||
libdevmapper.c \
|
||||
utils_dm.h \
|
||||
volumekey.c \
|
||||
|
||||
@@ -63,29 +63,43 @@ struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key);
|
||||
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength);
|
||||
void crypt_free_volume_key(struct volume_key *vk);
|
||||
|
||||
/* Device backend */
|
||||
struct device;
|
||||
int device_alloc(struct device **device, const char *path);
|
||||
void device_free(struct device *device);
|
||||
const char *device_path(const struct device *device);
|
||||
const char *device_block_path(const struct device *device);
|
||||
void device_topology_alignment(struct device *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment);
|
||||
int device_block_size(struct device *device);
|
||||
int device_read_ahead(struct device *device, uint32_t *read_ahead);
|
||||
int device_size(struct device *device, uint64_t *size);
|
||||
|
||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||
int device_block_adjust(struct crypt_device *cd,
|
||||
struct device *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t device_offset,
|
||||
uint64_t *size,
|
||||
uint32_t *flags);
|
||||
|
||||
/* Receive backend devices from context helpers */
|
||||
struct device *crypt_metadata_device(struct crypt_device *cd);
|
||||
struct device *crypt_data_device(struct crypt_device *cd);
|
||||
|
||||
int crypt_confirm(struct crypt_device *cd, const char *msg);
|
||||
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
|
||||
|
||||
int sector_size_for_device(const char *device);
|
||||
int device_read_ahead(const char *dev, uint32_t *read_ahead);
|
||||
ssize_t write_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);
|
||||
int device_ready(struct crypt_device *cd, const char *device, int mode);
|
||||
int device_size(const char *device, uint64_t *size);
|
||||
ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count);
|
||||
ssize_t read_blockwise(int fd, int bsize, void *_buf, size_t count);
|
||||
ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset);
|
||||
|
||||
unsigned crypt_getpagesize(void);
|
||||
|
||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||
int device_check_and_adjust(struct crypt_device *cd,
|
||||
const char *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t *size,
|
||||
uint64_t *offset,
|
||||
uint32_t *flags);
|
||||
|
||||
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
||||
#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
|
||||
@@ -98,11 +112,6 @@ int crypt_get_debug_level(void);
|
||||
int crypt_memlock_inc(struct crypt_device *ctx);
|
||||
int crypt_memlock_dec(struct crypt_device *ctx);
|
||||
|
||||
void get_topology_alignment(const char *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment);
|
||||
|
||||
int crypt_random_init(struct crypt_device *ctx);
|
||||
int crypt_random_get(struct crypt_device *ctx, char *buf, size_t len, int quality);
|
||||
void crypt_random_exit(void);
|
||||
@@ -131,7 +140,7 @@ typedef enum {
|
||||
* random algorithm */
|
||||
} crypt_wipe_type;
|
||||
|
||||
int crypt_wipe(const char *device,
|
||||
int crypt_wipe(struct device *device,
|
||||
uint64_t offset,
|
||||
uint64_t sectors,
|
||||
crypt_wipe_type type,
|
||||
|
||||
@@ -287,14 +287,16 @@ static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
|
||||
hex_key(hexkey, dmd->u.crypt.vk->keylength, dmd->u.crypt.vk->key);
|
||||
|
||||
max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) +
|
||||
strlen(dmd->data_device) + strlen(features) + 64;
|
||||
strlen(device_block_path(dmd->data_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->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset,
|
||||
dmd->data_device, dmd->u.crypt.offset, features);
|
||||
device_block_path(dmd->data_device), dmd->u.crypt.offset,
|
||||
features);
|
||||
if (r < 0 || r >= max_size) {
|
||||
crypt_safe_free(params);
|
||||
params = NULL;
|
||||
@@ -328,8 +330,8 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
||||
strncpy(hexsalt, "-", 2);
|
||||
|
||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||
strlen(dmd->data_device) +
|
||||
strlen(dmd->u.verity.hash_device) +
|
||||
strlen(device_block_path(dmd->data_device)) +
|
||||
strlen(device_block_path(dmd->u.verity.hash_device)) +
|
||||
strlen(vp->hash_name) + 128;
|
||||
|
||||
params = crypt_safe_alloc(max_size);
|
||||
@@ -338,8 +340,8 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
||||
|
||||
r = snprintf(params, max_size,
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s",
|
||||
vp->hash_type, dmd->data_device,
|
||||
dmd->u.verity.hash_device,
|
||||
vp->hash_type, device_block_path(dmd->data_device),
|
||||
device_block_path(dmd->u.verity.hash_device),
|
||||
vp->data_block_size, vp->hash_block_size,
|
||||
vp->data_size, dmd->u.verity.hash_offset,
|
||||
vp->hash_name, hexroot, hexsalt);
|
||||
@@ -491,7 +493,7 @@ static void dm_prepare_uuid(const char *name, const char *type, const char *uuid
|
||||
}
|
||||
|
||||
static int _dm_create_device(const char *name, const char *type,
|
||||
const char *device, uint32_t flags,
|
||||
struct device *device, uint32_t flags,
|
||||
const char *uuid, uint64_t size,
|
||||
char *params, int reload)
|
||||
{
|
||||
@@ -708,6 +710,7 @@ static int _dm_query_crypt(uint32_t get_flags,
|
||||
uint64_t val64;
|
||||
char *rcipher, *key_, *rdevice, *endp, buffer[3], *arg;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
memset(dmd, 0, sizeof(*dmd));
|
||||
dmd->target = DM_CRYPT;
|
||||
@@ -730,8 +733,13 @@ static int _dm_query_crypt(uint32_t get_flags,
|
||||
|
||||
/* device */
|
||||
rdevice = strsep(¶ms, " ");
|
||||
if (get_flags & DM_ACTIVE_DEVICE)
|
||||
dmd->data_device = crypt_lookup_dev(rdevice);
|
||||
if (get_flags & DM_ACTIVE_DEVICE) {
|
||||
arg = crypt_lookup_dev(rdevice);
|
||||
r = device_alloc(&dmd->data_device, arg);
|
||||
free(arg);
|
||||
if (r < 0 && r != -ENOTBLK)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*offset */
|
||||
if (!params)
|
||||
@@ -805,6 +813,7 @@ static int _dm_query_verity(uint32_t get_flags,
|
||||
uint64_t val64;
|
||||
ssize_t len;
|
||||
char *str, *str2;
|
||||
int r;
|
||||
|
||||
if (get_flags & DM_ACTIVE_VERITY_PARAMS)
|
||||
vp = dmd->u.verity.vp;
|
||||
@@ -826,15 +835,25 @@ static int _dm_query_verity(uint32_t get_flags,
|
||||
str = strsep(¶ms, " ");
|
||||
if (!params)
|
||||
return -EINVAL;
|
||||
if (get_flags & DM_ACTIVE_DEVICE)
|
||||
dmd->data_device = crypt_lookup_dev(str);
|
||||
if (get_flags & DM_ACTIVE_DEVICE) {
|
||||
str2 = crypt_lookup_dev(str);
|
||||
r = device_alloc(&dmd->data_device, str2);
|
||||
free(str2);
|
||||
if (r < 0 && r != -ENOTBLK)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* hash device */
|
||||
str = strsep(¶ms, " ");
|
||||
if (!params)
|
||||
return -EINVAL;
|
||||
if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE)
|
||||
dmd->u.verity.hash_device = crypt_lookup_dev(str);
|
||||
if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
|
||||
str2 = crypt_lookup_dev(str);
|
||||
r = device_alloc(&dmd->u.verity.hash_device, str2);
|
||||
free(str2);
|
||||
if (r < 0 && r != -ENOTBLK)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* data block size*/
|
||||
val32 = strtoul(params, ¶ms, 10);
|
||||
@@ -1072,27 +1091,3 @@ int dm_is_dm_kernel_name(const char *name)
|
||||
{
|
||||
return strncmp(name, "dm-", 3) ? 0 : 1;
|
||||
}
|
||||
|
||||
int dm_check_segment(const char *name, uint64_t offset, uint64_t size)
|
||||
{
|
||||
struct crypt_dm_active_device dmd;
|
||||
int r;
|
||||
|
||||
log_dbg("Checking segments for device %s.", name);
|
||||
|
||||
r = dm_query_device(name, 0, &dmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
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.u.crypt.offset, dmd.u.crypt.offset + dmd.size, offset, offset + size,
|
||||
r ? " (overlapping)" : " (ok)");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.size = 0,
|
||||
.flags = flags,
|
||||
.data_device = crypt_get_device_name(cd),
|
||||
.data_device = crypt_data_device(cd),
|
||||
.u.crypt = {
|
||||
.cipher = NULL,
|
||||
.vk = vk,
|
||||
@@ -205,9 +205,8 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
&dmd.size, &dmd.u.crypt.offset, &flags);
|
||||
r = device_block_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -51,17 +51,16 @@ static uint64_t cleaner_size = 0;
|
||||
static int devfd=-1;
|
||||
|
||||
static int setup_mapping(const char *cipher, const char *name,
|
||||
const char *device,
|
||||
struct volume_key *vk,
|
||||
int bsize, struct volume_key *vk,
|
||||
unsigned int sector, size_t srcLength,
|
||||
int mode, struct crypt_device *ctx)
|
||||
{
|
||||
int device_sector_size = sector_size_for_device(device);
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.target = DM_CRYPT,
|
||||
.uuid = NULL,
|
||||
.size = 0,
|
||||
.flags = 0,
|
||||
.size = round_up_modulo(srcLength, bsize) / SECTOR_SIZE,
|
||||
.flags = CRYPT_ACTIVATE_PRIVATE,
|
||||
.data_device = device,
|
||||
.u.crypt = {
|
||||
.cipher = cipher,
|
||||
@@ -70,22 +69,17 @@ static int setup_mapping(const char *cipher, const char *name,
|
||||
.iv_offset = 0,
|
||||
}
|
||||
};
|
||||
int r;
|
||||
|
||||
dmd.flags = CRYPT_ACTIVATE_PRIVATE;
|
||||
if (mode == O_RDONLY)
|
||||
dmd.flags |= CRYPT_ACTIVATE_READONLY;
|
||||
/*
|
||||
* we need to round this to nearest multiple of the underlying
|
||||
* device's sector size, otherwise the mapping will be refused.
|
||||
*/
|
||||
if(device_sector_size < 0) {
|
||||
log_err(ctx, _("Unable to obtain sector size for %s"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
|
||||
r = device_block_adjust(ctx, dmd.data_device, DEV_OK,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cleaner_size = dmd.size;
|
||||
|
||||
return dm_create_device(name, "TEMP", &dmd, 0);
|
||||
}
|
||||
|
||||
@@ -116,9 +110,8 @@ static const char *_error_hint(char *cipherMode, size_t keyLength)
|
||||
static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
ssize_t (*func)(int, void *, size_t),
|
||||
ssize_t (*func)(int, int, void *, size_t),
|
||||
int mode,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
@@ -127,6 +120,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
char *dmCipherSpec = NULL;
|
||||
const char *dmDir = dm_get_dir();
|
||||
int r = -1;
|
||||
int bsize = device_block_size(crypt_metadata_device(ctx));
|
||||
|
||||
if(dmDir == NULL) {
|
||||
log_err(ctx, _("Failed to obtain device mapper directory."));
|
||||
@@ -142,12 +136,11 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
signal(SIGINT, sigint_handler);
|
||||
cleaner_name = name;
|
||||
|
||||
r = setup_mapping(dmCipherSpec, name, device,
|
||||
vk, sector, srcLength, mode, ctx);
|
||||
r = setup_mapping(dmCipherSpec, name, bsize, vk, sector, srcLength, mode, ctx);
|
||||
if(r < 0) {
|
||||
log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n"
|
||||
"Check that kernel supports %s cipher (check syslog for more info).\n%s"),
|
||||
device, dmCipherSpec,
|
||||
device_path(crypt_metadata_device(ctx)), dmCipherSpec,
|
||||
_error_hint(hdr->cipherMode, vk->keylength * 8));
|
||||
r = -EIO;
|
||||
goto out1;
|
||||
@@ -160,7 +153,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
goto out2;
|
||||
}
|
||||
|
||||
r = func(devfd,src,srcLength);
|
||||
r = func(devfd, bsize, src, srcLength);
|
||||
if(r < 0) {
|
||||
log_err(ctx, _("Failed to access temporary keystore device.\n"));
|
||||
r = -EIO;
|
||||
@@ -186,21 +179,19 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
return LUKS_endec_template(src,srcLength,hdr,vk, device,
|
||||
sector, write_blockwise, O_RDWR, ctx);
|
||||
return LUKS_endec_template(src, srcLength, hdr, vk, sector,
|
||||
write_blockwise, O_RDWR, ctx);
|
||||
}
|
||||
|
||||
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
return LUKS_endec_template(dst,dstLength,hdr,vk, device,
|
||||
sector, read_blockwise, O_RDONLY, ctx);
|
||||
return LUKS_endec_template(dst, dstLength, hdr, vk, sector,
|
||||
read_blockwise, O_RDONLY, ctx);
|
||||
}
|
||||
|
||||
@@ -63,16 +63,16 @@ static uint64_t LUKS_device_sectors(size_t keyLen)
|
||||
return sector;
|
||||
}
|
||||
|
||||
static int LUKS_check_device_size(struct crypt_device *ctx, const char *device,
|
||||
size_t keyLength)
|
||||
static int LUKS_check_device_size(struct crypt_device *ctx, size_t keyLength)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
uint64_t dev_sectors, hdr_sectors;
|
||||
|
||||
if (!keyLength)
|
||||
return -EINVAL;
|
||||
|
||||
if(device_size(device, &dev_sectors)) {
|
||||
log_dbg("Cannot get device size for device %s.", device);
|
||||
log_dbg("Cannot get device size for device %s.", device_path(device));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ static int LUKS_check_device_size(struct crypt_device *ctx, const char *device,
|
||||
PRIu64 " sectors.",keyLength, dev_sectors, hdr_sectors);
|
||||
|
||||
if (hdr_sectors > dev_sectors) {
|
||||
log_err(ctx, _("Device %s is too small.\n"), device);
|
||||
log_err(ctx, _("Device %s is too small.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -144,10 +144,10 @@ static const char *dbg_slot_state(crypt_keyslot_info ki)
|
||||
|
||||
int LUKS_hdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
int r = 0, devfd = -1;
|
||||
ssize_t buffer_size;
|
||||
char *buffer = NULL;
|
||||
@@ -158,7 +158,7 @@ int LUKS_hdr_backup(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -172,14 +172,14 @@ int LUKS_hdr_backup(
|
||||
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes).",
|
||||
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS);
|
||||
|
||||
devfd = open(device, O_RDONLY | O_DIRECT | O_SYNC);
|
||||
devfd = open(device_path(device), O_RDONLY | O_DIRECT | O_SYNC);
|
||||
if(devfd == -1) {
|
||||
log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device);
|
||||
log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(read_blockwise(devfd, buffer, buffer_size) < buffer_size) {
|
||||
if(read_blockwise(devfd, device_block_size(device), buffer, buffer_size) < buffer_size) {
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -210,10 +210,10 @@ out:
|
||||
|
||||
int LUKS_hdr_restore(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
int r = 0, devfd = -1, diff_uuid = 0;
|
||||
ssize_t buffer_size = 0;
|
||||
char *buffer = NULL, msg[200];
|
||||
@@ -225,7 +225,7 @@ int LUKS_hdr_restore(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = LUKS_read_phdr_backup(backup_file, device, &hdr_file, 0, ctx);
|
||||
r = LUKS_read_phdr_backup(backup_file, &hdr_file, 0, ctx);
|
||||
if (!r)
|
||||
buffer_size = LUKS_device_sectors(hdr_file.keyBytes) << SECTOR_SHIFT;
|
||||
|
||||
@@ -255,9 +255,9 @@ int LUKS_hdr_restore(
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
r = LUKS_read_phdr(device, hdr, 0, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 0, 0, ctx);
|
||||
if (r == 0) {
|
||||
log_dbg("Device %s already contains LUKS header, checking UUID and offset.", device);
|
||||
log_dbg("Device %s already contains LUKS header, checking UUID and offset.", device_path(device));
|
||||
if(hdr->payloadOffset != hdr_file.payloadOffset ||
|
||||
hdr->keyBytes != hdr_file.keyBytes) {
|
||||
log_err(ctx, _("Data offset or key size differs on device and backup, restore failed.\n"));
|
||||
@@ -268,7 +268,7 @@ int LUKS_hdr_restore(
|
||||
diff_uuid = 1;
|
||||
}
|
||||
|
||||
if (snprintf(msg, sizeof(msg), _("Device %s %s%s"), device,
|
||||
if (snprintf(msg, sizeof(msg), _("Device %s %s%s"), device_path(device),
|
||||
r ? _("does not contain LUKS header. Replacing header can destroy data on that device.") :
|
||||
_("already contains LUKS header. Replacing header will destroy existing keyslots."),
|
||||
diff_uuid ? _("\nWARNING: real device header has different UUID than backup!") : "") < 0) {
|
||||
@@ -282,23 +282,23 @@ int LUKS_hdr_restore(
|
||||
}
|
||||
|
||||
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes) to device %s.",
|
||||
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS, device);
|
||||
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS, device_path(device));
|
||||
|
||||
devfd = open(device, O_WRONLY | O_DIRECT | O_SYNC);
|
||||
devfd = open(device_path(device), O_WRONLY | O_DIRECT | O_SYNC);
|
||||
if(devfd == -1) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device);
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(write_blockwise(devfd, buffer, buffer_size) < buffer_size) {
|
||||
if (write_blockwise(devfd, device_block_size(device), buffer, buffer_size) < buffer_size) {
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
/* Be sure to reload new data */
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
out:
|
||||
if (devfd != -1)
|
||||
close(devfd);
|
||||
@@ -307,7 +307,7 @@ out:
|
||||
}
|
||||
|
||||
/* This routine should do some just basic recovery for known problems. */
|
||||
static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
{
|
||||
struct luks_phdr temp_phdr;
|
||||
const unsigned char *sector = (const unsigned char*)phdr;
|
||||
@@ -336,7 +336,7 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
|
||||
phdr->hashSpec,phdr->uuid, LUKS_STRIPES,
|
||||
phdr->payloadOffset, 0,
|
||||
1, &PBKDF2_per_sec,
|
||||
"/dev/null", ctx);
|
||||
1, ctx);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Repair failed."));
|
||||
goto out;
|
||||
@@ -384,7 +384,7 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
|
||||
|
||||
if (need_write) {
|
||||
log_verbose(ctx, _("Writing LUKS header to disk.\n"));
|
||||
r = LUKS_write_phdr(device, phdr, ctx);
|
||||
r = LUKS_write_phdr(phdr, ctx);
|
||||
}
|
||||
out:
|
||||
crypt_free_volume_key(vk);
|
||||
@@ -441,7 +441,7 @@ static int _check_and_convert_hdr(const char *device,
|
||||
|
||||
if (repair) {
|
||||
if (r == -EINVAL)
|
||||
r = _keyslot_repair(device, hdr, ctx);
|
||||
r = _keyslot_repair(hdr, ctx);
|
||||
else
|
||||
log_verbose(ctx, _("No known problems detected for LUKS header.\n"));
|
||||
}
|
||||
@@ -464,7 +464,6 @@ static void LUKS_fix_header_compatible(struct luks_phdr *header)
|
||||
}
|
||||
|
||||
int LUKS_read_phdr_backup(const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
struct crypt_device *ctx)
|
||||
@@ -477,7 +476,7 @@ int LUKS_read_phdr_backup(const char *backup_file,
|
||||
|
||||
devfd = open(backup_file, O_RDONLY);
|
||||
if(-1 == devfd) {
|
||||
log_err(ctx, _("Cannot open file %s.\n"), device);
|
||||
log_err(ctx, _("Cannot open file %s.\n"), backup_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -493,12 +492,12 @@ int LUKS_read_phdr_backup(const char *backup_file,
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_read_phdr(const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int LUKS_read_phdr(struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
int repair,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
ssize_t hdr_size = sizeof(struct luks_phdr);
|
||||
int devfd = 0, r = 0;
|
||||
|
||||
@@ -506,31 +505,31 @@ int LUKS_read_phdr(const char *device,
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg("Reading LUKS header of size %d from device %s",
|
||||
hdr_size, device);
|
||||
hdr_size, device_path(device));
|
||||
|
||||
devfd = open(device,O_RDONLY | O_DIRECT | O_SYNC);
|
||||
if(-1 == devfd) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device);
|
||||
devfd = open(device_path(device), O_RDONLY | O_DIRECT | O_SYNC);
|
||||
if (devfd == -1) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (read_blockwise(devfd, hdr, hdr_size) < hdr_size)
|
||||
if (read_blockwise(devfd, device_block_size(device), hdr, hdr_size) < hdr_size)
|
||||
r = -EIO;
|
||||
else
|
||||
r = _check_and_convert_hdr(device, hdr, require_luks_device,
|
||||
r = _check_and_convert_hdr(device_path(device), hdr, require_luks_device,
|
||||
repair, ctx);
|
||||
|
||||
if (!r)
|
||||
r = LUKS_check_device_size(ctx, device, hdr->keyBytes);
|
||||
r = LUKS_check_device_size(ctx, hdr->keyBytes);
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_write_phdr(const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int LUKS_write_phdr(struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
ssize_t hdr_size = sizeof(struct luks_phdr);
|
||||
int devfd = 0;
|
||||
unsigned int i;
|
||||
@@ -538,15 +537,15 @@ int LUKS_write_phdr(const char *device,
|
||||
int r;
|
||||
|
||||
log_dbg("Updating LUKS header of size %d on device %s",
|
||||
sizeof(struct luks_phdr), device);
|
||||
sizeof(struct luks_phdr), device_path(device));
|
||||
|
||||
r = LUKS_check_device_size(ctx, device, hdr->keyBytes);
|
||||
r = LUKS_check_device_size(ctx, hdr->keyBytes);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
devfd = open(device,O_RDWR | O_DIRECT | O_SYNC);
|
||||
devfd = open(device_path(device), O_RDWR | O_DIRECT | O_SYNC);
|
||||
if(-1 == devfd) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device);
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -565,16 +564,17 @@ int LUKS_write_phdr(const char *device,
|
||||
convHdr.keyblock[i].stripes = htonl(hdr->keyblock[i].stripes);
|
||||
}
|
||||
|
||||
r = write_blockwise(devfd, &convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
||||
r = write_blockwise(devfd, device_block_size(device), &convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
||||
if (r)
|
||||
log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device);
|
||||
log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device_path(device));
|
||||
close(devfd);
|
||||
|
||||
/* Re-read header from disk to be sure that in-memory and on-disk data are the same. */
|
||||
if (!r) {
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
if (r)
|
||||
log_err(ctx, _("Error re-reading LUKS header after update on device %s.\n"), device);
|
||||
log_err(ctx, _("Error re-reading LUKS header after update on device %s.\n"),
|
||||
device_path(device));
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -603,7 +603,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
unsigned int alignOffset,
|
||||
uint32_t iteration_time_ms,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
const char *metadata_device,
|
||||
int detached_metadata_device,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
unsigned int i=0;
|
||||
@@ -614,7 +614,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
char luksMagic[] = LUKS_MAGIC;
|
||||
|
||||
/* For separate metadata device allow zero alignment */
|
||||
if (alignPayload == 0 && !metadata_device)
|
||||
if (alignPayload == 0 && !detached_metadata_device)
|
||||
alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE;
|
||||
|
||||
if (PBKDF2_HMAC_ready(hashSpec) < 0) {
|
||||
@@ -679,7 +679,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
}
|
||||
|
||||
if (metadata_device) {
|
||||
if (detached_metadata_device) {
|
||||
/* for separate metadata device use alignPayload directly */
|
||||
header->payloadOffset = alignPayload;
|
||||
} else {
|
||||
@@ -697,7 +697,6 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
}
|
||||
|
||||
int LUKS_hdr_uuid_set(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
const char *uuid,
|
||||
struct crypt_device *ctx)
|
||||
@@ -713,10 +712,10 @@ int LUKS_hdr_uuid_set(
|
||||
|
||||
uuid_unparse(partitionUuid, hdr->uuid);
|
||||
|
||||
return LUKS_write_phdr(device, hdr, ctx);
|
||||
return LUKS_write_phdr(hdr, ctx);
|
||||
}
|
||||
|
||||
int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
int LUKS_set_key(unsigned int keyIndex,
|
||||
const char *password, size_t passwordLen,
|
||||
struct luks_phdr *hdr, struct volume_key *vk,
|
||||
uint32_t iteration_time_ms,
|
||||
@@ -791,14 +790,13 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
log_dbg("Updating key slot %d [0x%04x] area on device %s.", keyIndex,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset << 9, device);
|
||||
log_dbg("Updating key slot %d [0x%04x] area.", keyIndex,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset << 9);
|
||||
/* Encryption via dm */
|
||||
r = LUKS_encrypt_to_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr,
|
||||
derived_key,
|
||||
device,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
ctx);
|
||||
if (r < 0) {
|
||||
@@ -811,7 +809,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_write_phdr(device, hdr, ctx);
|
||||
r = LUKS_write_phdr(hdr, ctx);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -841,8 +839,7 @@ int LUKS_verify_volume_key(const struct luks_phdr *hdr,
|
||||
}
|
||||
|
||||
/* Try to open a particular key slot */
|
||||
static int LUKS_open_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
static int LUKS_open_key(unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
@@ -883,7 +880,6 @@ static int LUKS_open_key(const char *device,
|
||||
AFEKSize,
|
||||
hdr,
|
||||
derived_key,
|
||||
device,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
ctx);
|
||||
if (r < 0) {
|
||||
@@ -904,8 +900,7 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_open_key_with_hdr(const char *device,
|
||||
int keyIndex,
|
||||
int LUKS_open_key_with_hdr(int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
@@ -918,12 +913,12 @@ int LUKS_open_key_with_hdr(const char *device,
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
|
||||
if (keyIndex >= 0) {
|
||||
r = LUKS_open_key(device, keyIndex, password, passwordLen, hdr, *vk, ctx);
|
||||
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, *vk, ctx);
|
||||
return (r < 0) ? r : keyIndex;
|
||||
}
|
||||
|
||||
for(i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
r = LUKS_open_key(device, i, password, passwordLen, hdr, *vk, ctx);
|
||||
r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx);
|
||||
if(r == 0)
|
||||
return i;
|
||||
|
||||
@@ -937,15 +932,15 @@ int LUKS_open_key_with_hdr(const char *device,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int LUKS_del_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
int LUKS_del_key(unsigned int keyIndex,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
unsigned int startOffset, endOffset, stripesLen;
|
||||
int r;
|
||||
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -965,7 +960,7 @@ int LUKS_del_key(const char *device,
|
||||
(endOffset - startOffset) * SECTOR_SIZE,
|
||||
CRYPT_WIPE_DISK, 0);
|
||||
if (r) {
|
||||
log_err(ctx, _("Cannot wipe device %s.\n"), device);
|
||||
log_err(ctx, _("Cannot wipe device %s.\n"), device_path(device));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -973,7 +968,7 @@ int LUKS_del_key(const char *device,
|
||||
memset(&hdr->keyblock[keyIndex].passwordSalt, 0, LUKS_SALTSIZE);
|
||||
hdr->keyblock[keyIndex].passwordIterations = 0;
|
||||
|
||||
r = LUKS_write_phdr(device, hdr, ctx);
|
||||
r = LUKS_write_phdr(hdr, ctx);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1048,7 +1043,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.flags = flags,
|
||||
.size = 0,
|
||||
.data_device = crypt_get_device_name(cd),
|
||||
.data_device = crypt_data_device(cd),
|
||||
.u.crypt = {
|
||||
.cipher = NULL,
|
||||
.vk = vk,
|
||||
@@ -1062,9 +1057,8 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
else
|
||||
device_check = DEV_EXCL;
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, device_check,
|
||||
&dmd.size, &dmd.u.crypt.offset,
|
||||
&dmd.flags);
|
||||
r = device_block_adjust(cd, dmd.data_device, device_check,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
converted */
|
||||
|
||||
struct volume_key;
|
||||
struct device_backend;
|
||||
|
||||
struct luks_phdr {
|
||||
char magic[LUKS_MAGIC_L];
|
||||
@@ -108,11 +109,10 @@ int LUKS_generate_phdr(
|
||||
unsigned int alignOffset,
|
||||
uint32_t iteration_time_ms,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
const char *metadata_device,
|
||||
int detached_metadata_device,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_read_phdr(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
int repair,
|
||||
@@ -120,36 +120,30 @@ int LUKS_read_phdr(
|
||||
|
||||
int LUKS_read_phdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_uuid_set(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
const char *uuid,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_restore(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_write_phdr(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_set_key(
|
||||
const char *device,
|
||||
unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
@@ -160,7 +154,6 @@ int LUKS_set_key(
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_open_key_with_hdr(
|
||||
const char *device,
|
||||
int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
@@ -169,7 +162,6 @@ int LUKS_open_key_with_hdr(
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_del_key(
|
||||
const char *device,
|
||||
unsigned int keyIndex,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
@@ -183,7 +175,6 @@ int LUKS_encrypt_to_storage(
|
||||
char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
@@ -191,7 +182,6 @@ int LUKS_decrypt_from_storage(
|
||||
char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
|
||||
234
lib/setup.c
234
lib/setup.c
@@ -35,12 +35,8 @@
|
||||
struct crypt_device {
|
||||
char *type;
|
||||
|
||||
char *device;
|
||||
char *metadata_device;
|
||||
|
||||
/* loopback automatic detach helpers */
|
||||
int loop_device_fd;
|
||||
int loop_metadata_device_fd;
|
||||
struct device *device;
|
||||
struct device *metadata_device;
|
||||
|
||||
struct volume_key *volume_key;
|
||||
uint64_t timeout;
|
||||
@@ -156,11 +152,22 @@ void logger(struct crypt_device *cd, int level, const char *file,
|
||||
free(target);
|
||||
}
|
||||
|
||||
static const char *mdata_device(struct crypt_device *cd)
|
||||
static const char *mdata_device_path(struct crypt_device *cd)
|
||||
{
|
||||
return device_path(cd->metadata_device ?: cd->device);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
struct device *crypt_metadata_device(struct crypt_device *cd)
|
||||
{
|
||||
return cd->metadata_device ?: cd->device;
|
||||
}
|
||||
|
||||
struct device *crypt_data_device(struct crypt_device *cd)
|
||||
{
|
||||
return cd->device;
|
||||
}
|
||||
|
||||
static int init_crypto(struct crypt_device *ctx)
|
||||
{
|
||||
int r;
|
||||
@@ -307,7 +314,7 @@ int PLAIN_activate(struct crypt_device *cd,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.size = size,
|
||||
.flags = flags,
|
||||
.data_device = crypt_get_device_name(cd),
|
||||
.data_device = crypt_data_device(cd),
|
||||
.u.crypt = {
|
||||
.cipher = NULL,
|
||||
.vk = vk,
|
||||
@@ -321,8 +328,8 @@ int PLAIN_activate(struct crypt_device *cd,
|
||||
else
|
||||
device_check = DEV_EXCL;
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, device_check,
|
||||
&dmd.size, &dmd.u.crypt.offset, &dmd.flags);
|
||||
r = device_block_adjust(cd, dmd.data_device, device_check,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -417,7 +424,7 @@ static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslo
|
||||
if(r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase_read,
|
||||
passphrase_size_read, &cd->hdr, vk, cd);
|
||||
if (r == -EPERM)
|
||||
eperm = 1;
|
||||
@@ -504,44 +511,6 @@ const char *crypt_get_dir(void)
|
||||
return dm_get_dir();
|
||||
}
|
||||
|
||||
static int set_device_or_loop(const char *device_org, char **device, int *loop_fd)
|
||||
{
|
||||
int r, readonly = 0;
|
||||
|
||||
if (!device_org)
|
||||
return 0;
|
||||
|
||||
r = device_ready(NULL, device_org, O_RDONLY);
|
||||
if (r == -ENOTBLK) {
|
||||
*device = crypt_loop_get_device();
|
||||
log_dbg("Not a block device, %s%s.", *device ?
|
||||
"using free loop device " : "no free loop device found",
|
||||
*device ?: "");
|
||||
if (!*device) {
|
||||
log_err(NULL, _("Cannot find a free loopback device.\n"));
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Keep the loop open, dettached on last close. */
|
||||
*loop_fd = crypt_loop_attach(*device, device_org, 0, 1, &readonly);
|
||||
if (*loop_fd == -1) {
|
||||
log_err(NULL, _("Attaching loopback device failed "
|
||||
"(loop device with autoclear flag is required).\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = device_ready(NULL, *device, O_RDONLY);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
return -ENOTBLK;
|
||||
|
||||
if (!*device && device_org && !(*device = strdup(device_org)))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_init(struct crypt_device **cd, const char *device)
|
||||
{
|
||||
struct crypt_device *h = NULL;
|
||||
@@ -556,10 +525,8 @@ int crypt_init(struct crypt_device **cd, const char *device)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(h, 0, sizeof(*h));
|
||||
h->loop_device_fd = -1;
|
||||
h->loop_metadata_device_fd = -1;
|
||||
|
||||
r = set_device_or_loop(device, &h->device, &h->loop_device_fd);
|
||||
r = device_alloc(&h->device, device);
|
||||
if (r < 0)
|
||||
goto bad;
|
||||
|
||||
@@ -575,12 +542,7 @@ int crypt_init(struct crypt_device **cd, const char *device)
|
||||
*cd = h;
|
||||
return 0;
|
||||
bad:
|
||||
|
||||
if (h) {
|
||||
if (h->loop_device_fd != -1)
|
||||
close(h->loop_device_fd);
|
||||
free(h->device);
|
||||
}
|
||||
device_free(h->device);
|
||||
free(h);
|
||||
return r;
|
||||
}
|
||||
@@ -593,13 +555,13 @@ static int crypt_check_data_device_size(struct crypt_device *cd)
|
||||
/* Check data device size, require at least one sector */
|
||||
size_min = crypt_get_data_offset(cd) << SECTOR_SHIFT ?: SECTOR_SIZE;
|
||||
|
||||
r = device_size(crypt_get_device_name(cd), &size);
|
||||
r = device_size(cd->device, &size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (size < size_min) {
|
||||
log_err(cd, _("Header detected but device %s is too small.\n"),
|
||||
crypt_get_device_name(cd));
|
||||
device_path(cd->device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -608,8 +570,8 @@ static int crypt_check_data_device_size(struct crypt_device *cd)
|
||||
|
||||
int crypt_set_data_device(struct crypt_device *cd, const char *device)
|
||||
{
|
||||
char *data_device = NULL;
|
||||
int r, loop_fd = -1;
|
||||
struct device *dev = NULL;
|
||||
int r;
|
||||
|
||||
log_dbg("Setting ciphertext data device to %s.", device ?: "(none)");
|
||||
|
||||
@@ -622,21 +584,16 @@ int crypt_set_data_device(struct crypt_device *cd, const char *device)
|
||||
if (!cd->device || !device)
|
||||
return -EINVAL;
|
||||
|
||||
r = set_device_or_loop(device, &data_device, &loop_fd);
|
||||
r = device_alloc(&dev, device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!cd->metadata_device) {
|
||||
cd->metadata_device = cd->device;
|
||||
cd->loop_metadata_device_fd = cd->loop_device_fd;
|
||||
} else {
|
||||
free(cd->device);
|
||||
if (cd->loop_device_fd != -1)
|
||||
close(cd->loop_device_fd);
|
||||
}
|
||||
} else
|
||||
device_free(cd->device);
|
||||
|
||||
cd->device = data_device;
|
||||
cd->loop_device_fd = loop_fd;
|
||||
cd->device = dev;
|
||||
|
||||
return crypt_check_data_device_size(cd);
|
||||
}
|
||||
@@ -650,7 +607,7 @@ static int _crypt_load_luks1(struct crypt_device *cd, int require_header, int re
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = LUKS_read_phdr(mdata_device(cd), &hdr, require_header, repair, cd);
|
||||
r = LUKS_read_phdr(&hdr, require_header, repair, cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -677,8 +634,7 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
|
||||
if (params)
|
||||
sb_offset = params->hash_area_offset;
|
||||
|
||||
r = VERITY_read_sb(cd, mdata_device(cd), sb_offset,
|
||||
&cd->verity_uuid, &cd->verity_hdr);
|
||||
r = VERITY_read_sb(cd, sb_offset, &cd->verity_uuid, &cd->verity_hdr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -740,7 +696,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
|
||||
cd->loopaes_key_size = dmd.u.crypt.vk->keylength / key_nums;
|
||||
}
|
||||
} else if (isLUKS(cd->type)) {
|
||||
if (mdata_device(cd)) {
|
||||
if (crypt_metadata_device(cd)) {
|
||||
r = _crypt_load_luks1(cd, 0, 0);
|
||||
if (r < 0) {
|
||||
log_dbg("LUKS device header does not match active device.");
|
||||
@@ -763,8 +719,8 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
|
||||
}
|
||||
out:
|
||||
crypt_free_volume_key(dmd.u.crypt.vk);
|
||||
device_free(dmd.data_device);
|
||||
free(CONST_CAST(void*)dmd.u.crypt.cipher);
|
||||
free(CONST_CAST(void*)dmd.data_device);
|
||||
free(CONST_CAST(void*)dmd.uuid);
|
||||
return r;
|
||||
}
|
||||
@@ -801,12 +757,10 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
||||
cd->verity_hdr.flags = params.flags;
|
||||
cd->verity_hdr.salt_size = params.salt_size;
|
||||
cd->verity_hdr.salt = params.salt;
|
||||
if (!(cd->metadata_device = strdup(dmd.u.verity.hash_device)))
|
||||
r = -ENOMEM;
|
||||
cd->metadata_device = dmd.u.verity.hash_device;
|
||||
}
|
||||
out:
|
||||
free(CONST_CAST(void*)dmd.u.verity.hash_device);
|
||||
free(CONST_CAST(void*)dmd.data_device);
|
||||
device_free(dmd.data_device);
|
||||
free(CONST_CAST(void*)dmd.uuid);
|
||||
return r;
|
||||
}
|
||||
@@ -839,7 +793,7 @@ 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.data_device);
|
||||
r = crypt_init(cd, device_path(dmd.data_device));
|
||||
|
||||
/* Underlying device disappeared but mapping still active */
|
||||
if (!dmd.data_device || r == -ENOTBLK)
|
||||
@@ -848,7 +802,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
|
||||
/* Underlying device is not readable but crypt mapping exists */
|
||||
if (r == -ENOTBLK) {
|
||||
free(CONST_CAST(void*)dmd.data_device);
|
||||
device_free(dmd.data_device);
|
||||
dmd.data_device = NULL;
|
||||
r = crypt_init(cd, NULL);
|
||||
}
|
||||
@@ -872,7 +826,7 @@ 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.data_device);
|
||||
r = crypt_set_data_device(*cd, device_path(dmd.data_device));
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
@@ -888,7 +842,7 @@ out:
|
||||
crypt_free(*cd);
|
||||
*cd = NULL;
|
||||
}
|
||||
free(CONST_CAST(void*)dmd.data_device);
|
||||
device_free(dmd.data_device);
|
||||
free(CONST_CAST(void*)dmd.uuid);
|
||||
return r;
|
||||
}
|
||||
@@ -954,7 +908,7 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
||||
unsigned long required_alignment = DEFAULT_DISK_ALIGNMENT;
|
||||
unsigned long alignment_offset = 0;
|
||||
|
||||
if (!mdata_device(cd)) {
|
||||
if (!crypt_metadata_device(cd)) {
|
||||
log_err(cd, _("Can't format LUKS without device.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -973,13 +927,15 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
||||
|
||||
if (params && params->data_device) {
|
||||
cd->metadata_device = cd->device;
|
||||
if (!(cd->device = strdup(params->data_device)))
|
||||
cd->device = NULL;
|
||||
if (device_alloc(&cd->device, params->data_device) < 0)
|
||||
return -ENOMEM;
|
||||
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||
} else if (params && params->data_alignment) {
|
||||
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||
} else
|
||||
get_topology_alignment(cd->device, &required_alignment,
|
||||
device_topology_alignment(cd->device,
|
||||
&required_alignment,
|
||||
&alignment_offset, DEFAULT_DISK_ALIGNMENT);
|
||||
|
||||
r = LUKS_generate_phdr(&cd->hdr, cd->volume_key, cipher, cipher_mode,
|
||||
@@ -988,24 +944,24 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
||||
required_alignment / SECTOR_SIZE,
|
||||
alignment_offset / SECTOR_SIZE,
|
||||
cd->iteration_time, &cd->PBKDF2_per_sec,
|
||||
cd->metadata_device, cd);
|
||||
cd->metadata_device ? 1 : 0, cd);
|
||||
if(r < 0)
|
||||
return r;
|
||||
|
||||
/* Wipe first 8 sectors - fs magic numbers etc. */
|
||||
r = crypt_wipe(mdata_device(cd), 0, 8 * SECTOR_SIZE, CRYPT_WIPE_ZERO, 1);
|
||||
r = crypt_wipe(crypt_metadata_device(cd), 0, 8 * SECTOR_SIZE, CRYPT_WIPE_ZERO, 1);
|
||||
if(r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Cannot format device %s which is still in use.\n"),
|
||||
mdata_device(cd));
|
||||
mdata_device_path(cd));
|
||||
else
|
||||
log_err(cd, _("Cannot wipe header on device %s.\n"),
|
||||
mdata_device(cd));
|
||||
mdata_device_path(cd));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
r = LUKS_write_phdr(mdata_device(cd), &cd->hdr, cd);
|
||||
r = LUKS_write_phdr(&cd->hdr, cd);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1016,7 +972,7 @@ static int _crypt_format_loopaes(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
struct crypt_params_loopaes *params)
|
||||
{
|
||||
if (!mdata_device(cd)) {
|
||||
if (!crypt_metadata_device(cd)) {
|
||||
log_err(cd, _("Can't format LOOPAES without device.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1052,7 +1008,7 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
||||
int r = 0, hash_size;
|
||||
uint64_t data_device_size;
|
||||
|
||||
if (!mdata_device(cd)) {
|
||||
if (!crypt_metadata_device(cd)) {
|
||||
log_err(cd, _("Can't format VERITY without device.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1123,7 +1079,7 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
||||
return r;
|
||||
|
||||
if (params->flags & CRYPT_VERITY_CREATE_HASH) {
|
||||
r = VERITY_create(cd, &cd->verity_hdr, cd->device, mdata_device(cd),
|
||||
r = VERITY_create(cd, &cd->verity_hdr,
|
||||
cd->verity_root_hash, cd->verity_root_hash_size);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -1138,8 +1094,7 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = VERITY_write_sb(cd, mdata_device(cd),
|
||||
cd->verity_hdr.hash_area_offset,
|
||||
r = VERITY_write_sb(cd, cd->verity_hdr.hash_area_offset,
|
||||
cd->verity_uuid,
|
||||
&cd->verity_hdr);
|
||||
}
|
||||
@@ -1165,7 +1120,7 @@ int crypt_format(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg("Formatting device %s as type %s.", mdata_device(cd) ?: "(none)", type);
|
||||
log_dbg("Formatting device %s as type %s.", mdata_device_path(cd) ?: "(none)", type);
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
@@ -1203,9 +1158,9 @@ int crypt_load(struct crypt_device *cd,
|
||||
int r;
|
||||
|
||||
log_dbg("Trying to load %s crypt type from device %s.",
|
||||
requested_type ?: "any", mdata_device(cd) ?: "(none)");
|
||||
requested_type ?: "any", mdata_device_path(cd) ?: "(none)");
|
||||
|
||||
if (!mdata_device(cd))
|
||||
if (!crypt_metadata_device(cd))
|
||||
return -EINVAL;
|
||||
|
||||
if (!requested_type || isLUKS(requested_type)) {
|
||||
@@ -1234,9 +1189,9 @@ int crypt_repair(struct crypt_device *cd,
|
||||
int r;
|
||||
|
||||
log_dbg("Trying to repair %s crypt type from device %s.",
|
||||
requested_type ?: "any", mdata_device(cd) ?: "(none)");
|
||||
requested_type ?: "any", mdata_device_path(cd) ?: "(none)");
|
||||
|
||||
if (!mdata_device(cd))
|
||||
if (!crypt_metadata_device(cd))
|
||||
return -EINVAL;
|
||||
|
||||
if (requested_type && !isLUKS(requested_type))
|
||||
@@ -1282,8 +1237,8 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_OK, &new_size,
|
||||
&dmd.u.crypt.offset, &dmd.flags);
|
||||
r = device_block_adjust(cd, dmd.data_device, DEV_OK,
|
||||
dmd.u.crypt.offset, &new_size, &dmd.flags);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
@@ -1315,19 +1270,19 @@ int crypt_set_uuid(struct crypt_device *cd, const char *uuid)
|
||||
|
||||
if (uuid && !strncmp(uuid, cd->hdr.uuid, sizeof(cd->hdr.uuid))) {
|
||||
log_dbg("UUID is the same as requested (%s) for device %s.",
|
||||
uuid, mdata_device(cd));
|
||||
uuid, mdata_device_path(cd));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uuid)
|
||||
log_dbg("Requested new UUID change to %s for %s.", uuid, mdata_device(cd));
|
||||
log_dbg("Requested new UUID change to %s for %s.", uuid, mdata_device_path(cd));
|
||||
else
|
||||
log_dbg("Requested new UUID refresh for %s.", mdata_device(cd));
|
||||
log_dbg("Requested new UUID refresh for %s.", mdata_device_path(cd));
|
||||
|
||||
if (!crypt_confirm(cd, _("Do you really want to change UUID of device?")))
|
||||
return -EPERM;
|
||||
|
||||
return LUKS_hdr_uuid_set(mdata_device(cd), &cd->hdr, uuid, cd);
|
||||
return LUKS_hdr_uuid_set(&cd->hdr, uuid, cd);
|
||||
}
|
||||
|
||||
int crypt_header_backup(struct crypt_device *cd,
|
||||
@@ -1344,9 +1299,9 @@ int crypt_header_backup(struct crypt_device *cd,
|
||||
return r;
|
||||
|
||||
log_dbg("Requested header backup of device %s (%s) to "
|
||||
"file %s.", mdata_device(cd), requested_type, backup_file);
|
||||
"file %s.", mdata_device_path(cd), requested_type, backup_file);
|
||||
|
||||
return LUKS_hdr_backup(backup_file, mdata_device(cd), &cd->hdr, cd);
|
||||
return LUKS_hdr_backup(backup_file, &cd->hdr, cd);
|
||||
}
|
||||
|
||||
int crypt_header_restore(struct crypt_device *cd,
|
||||
@@ -1363,26 +1318,21 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
return r;
|
||||
|
||||
log_dbg("Requested header restore to device %s (%s) from "
|
||||
"file %s.", mdata_device(cd), requested_type, backup_file);
|
||||
"file %s.", mdata_device_path(cd), requested_type, backup_file);
|
||||
|
||||
return LUKS_hdr_restore(backup_file, mdata_device(cd), &cd->hdr, cd);
|
||||
return LUKS_hdr_restore(backup_file, &cd->hdr, cd);
|
||||
}
|
||||
|
||||
void crypt_free(struct crypt_device *cd)
|
||||
{
|
||||
if (cd) {
|
||||
log_dbg("Releasing crypt device %s context.", mdata_device(cd));
|
||||
|
||||
if (cd->loop_device_fd != -1)
|
||||
close(cd->loop_device_fd);
|
||||
if (cd->loop_metadata_device_fd != -1)
|
||||
close(cd->loop_metadata_device_fd);
|
||||
log_dbg("Releasing crypt device %s context.", mdata_device_path(cd));
|
||||
|
||||
dm_exit();
|
||||
crypt_free_volume_key(cd->volume_key);
|
||||
|
||||
free(cd->device);
|
||||
free(cd->metadata_device);
|
||||
device_free(cd->device);
|
||||
device_free(cd->metadata_device);
|
||||
free(cd->type);
|
||||
|
||||
/* used in plain device only */
|
||||
@@ -1477,8 +1427,8 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (passphrase) {
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase,
|
||||
passphrase_size, &cd->hdr, &vk, cd);
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase, passphrase_size,
|
||||
&cd->hdr, &vk, cd);
|
||||
} else
|
||||
r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
|
||||
|
||||
@@ -1534,7 +1484,7 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase_read,
|
||||
passphrase_size_read, &cd->hdr, &vk, cd);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
@@ -1596,7 +1546,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
||||
}
|
||||
} else if (passphrase) {
|
||||
/* Passphrase provided, use it to unlock existing keyslot */
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), CRYPT_ANY_SLOT, passphrase,
|
||||
r = LUKS_open_key_with_hdr(CRYPT_ANY_SLOT, passphrase,
|
||||
passphrase_size, &cd->hdr, &vk, cd);
|
||||
} else {
|
||||
/* Passphrase not provided, ask first and use it to unlock existing keyslot */
|
||||
@@ -1605,7 +1555,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), CRYPT_ANY_SLOT, password,
|
||||
r = LUKS_open_key_with_hdr(CRYPT_ANY_SLOT, password,
|
||||
passwordLen, &cd->hdr, &vk, cd);
|
||||
crypt_safe_free(password);
|
||||
}
|
||||
@@ -1623,7 +1573,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = LUKS_set_key(mdata_device(cd), keyslot, new_password, new_passwordLen,
|
||||
r = LUKS_set_key(keyslot, new_password, new_passwordLen,
|
||||
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
||||
if(r < 0) goto out;
|
||||
|
||||
@@ -1682,7 +1632,7 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), CRYPT_ANY_SLOT, password, passwordLen,
|
||||
r = LUKS_open_key_with_hdr(CRYPT_ANY_SLOT, password, passwordLen,
|
||||
&cd->hdr, &vk, cd);
|
||||
}
|
||||
|
||||
@@ -1699,7 +1649,7 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_set_key(mdata_device(cd), keyslot, new_password, new_passwordLen,
|
||||
r = LUKS_set_key(keyslot, new_password, new_passwordLen,
|
||||
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
||||
out:
|
||||
crypt_safe_free(password);
|
||||
@@ -1765,7 +1715,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
|
||||
passphrase_size = new_passwordLen;
|
||||
}
|
||||
|
||||
r = LUKS_set_key(mdata_device(cd), keyslot, passphrase, passphrase_size,
|
||||
r = LUKS_set_key(keyslot, passphrase, passphrase_size,
|
||||
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
|
||||
out:
|
||||
crypt_safe_free(new_password);
|
||||
@@ -1795,7 +1745,7 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return LUKS_del_key(mdata_device(cd), keyslot, &cd->hdr, cd);
|
||||
return LUKS_del_key(keyslot, &cd->hdr, cd);
|
||||
}
|
||||
|
||||
// activation/deactivation of device mapping
|
||||
@@ -1851,7 +1801,7 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
|
||||
} else if (isLUKS(cd->type)) {
|
||||
/* provided passphrase, do not retry */
|
||||
if (passphrase) {
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase,
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase,
|
||||
passphrase_size, &cd->hdr, &vk, cd);
|
||||
} else
|
||||
r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
|
||||
@@ -1923,7 +1873,7 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
|
||||
&passphrase_size_read, keyfile, keyfile_offset, keyfile_size);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase_read,
|
||||
passphrase_size_read, &cd->hdr, &vk, cd);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
@@ -2033,8 +1983,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = VERITY_activate(cd, name, mdata_device(cd),
|
||||
volume_key, volume_key_size,
|
||||
r = VERITY_activate(cd, name, volume_key, volume_key_size,
|
||||
&cd->verity_hdr, CRYPT_ACTIVATE_READONLY);
|
||||
|
||||
if (r == -EPERM) {
|
||||
@@ -2115,7 +2064,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
log_err(cd, _("Cannot retrieve volume key for plain device.\n"));
|
||||
} else if (isLUKS(cd->type)) {
|
||||
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase,
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase,
|
||||
passphrase_size, &cd->hdr, &vk, cd);
|
||||
|
||||
} else
|
||||
@@ -2243,7 +2192,7 @@ static int _luks_dump(struct crypt_device *cd)
|
||||
{
|
||||
int i;
|
||||
|
||||
log_std(cd, "LUKS header information for %s\n\n", mdata_device(cd));
|
||||
log_std(cd, "LUKS header information for %s\n\n", mdata_device_path(cd));
|
||||
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 mode: \t%s\n", cd->hdr.cipherMode);
|
||||
@@ -2286,7 +2235,7 @@ static int _luks_dump(struct crypt_device *cd)
|
||||
|
||||
static int _verity_dump(struct crypt_device *cd)
|
||||
{
|
||||
log_std(cd, "VERITY header information for %s\n", mdata_device(cd));
|
||||
log_std(cd, "VERITY header information for %s\n", mdata_device_path(cd));
|
||||
log_std(cd, "UUID: \t%s\n", cd->verity_uuid ?: "");
|
||||
log_std(cd, "Hash type: \t%u\n", cd->verity_hdr.hash_type);
|
||||
log_std(cd, "Data blocks: \t%" PRIu64 "\n", cd->verity_hdr.data_size);
|
||||
@@ -2365,7 +2314,12 @@ const char *crypt_get_uuid(struct crypt_device *cd)
|
||||
|
||||
const char *crypt_get_device_name(struct crypt_device *cd)
|
||||
{
|
||||
return cd->device;
|
||||
const char *path = device_block_path(cd->device);
|
||||
|
||||
if (!path)
|
||||
path = device_path(cd->device);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
int crypt_get_volume_key_size(struct crypt_device *cd)
|
||||
@@ -2442,8 +2396,8 @@ int crypt_get_verity_info(struct crypt_device *cd,
|
||||
if (!isVERITY(cd->type) || !vp)
|
||||
return -EINVAL;
|
||||
|
||||
vp->data_device = cd->device;
|
||||
vp->hash_device = mdata_device(cd);
|
||||
vp->data_device = device_path(cd->device);
|
||||
vp->hash_device = mdata_device_path(cd);
|
||||
vp->hash_name = cd->verity_hdr.hash_name;
|
||||
vp->salt = cd->verity_hdr.salt;
|
||||
vp->salt_size = cd->verity_hdr.salt_size;
|
||||
|
||||
295
lib/utils.c
295
lib/utils.c
@@ -22,20 +22,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
unsigned crypt_getpagesize(void)
|
||||
@@ -74,52 +64,15 @@ static void *aligned_malloc(void **base, int size, int alignment)
|
||||
#endif
|
||||
}
|
||||
|
||||
int device_read_ahead(const char *dev, uint32_t *read_ahead)
|
||||
{
|
||||
int fd, r = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
if ((fd = open(dev, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
|
||||
close(fd);
|
||||
|
||||
if (r)
|
||||
*read_ahead = (uint32_t) read_ahead_long;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sector_size(int fd)
|
||||
{
|
||||
int bsize;
|
||||
if (ioctl(fd,BLKSSZGET, &bsize) < 0)
|
||||
return -EINVAL;
|
||||
else
|
||||
return bsize;
|
||||
}
|
||||
|
||||
int sector_size_for_device(const char *device)
|
||||
{
|
||||
int fd = open(device, O_RDONLY);
|
||||
int r;
|
||||
if(fd < 0)
|
||||
return -EINVAL;
|
||||
r = sector_size(fd);
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t write_blockwise(int fd, void *orig_buf, size_t count)
|
||||
ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count)
|
||||
{
|
||||
void *hangover_buf, *hangover_buf_base = NULL;
|
||||
void *buf, *buf_base = NULL;
|
||||
int r, hangover, solid, bsize, alignment;
|
||||
int r, hangover, solid, alignment;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
if (fd == -1 || !orig_buf || bsize <= 0)
|
||||
return -1;
|
||||
|
||||
hangover = count % bsize;
|
||||
solid = count - hangover;
|
||||
@@ -163,14 +116,14 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
|
||||
ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) {
|
||||
void *hangover_buf, *hangover_buf_base = NULL;
|
||||
void *buf, *buf_base = NULL;
|
||||
int r, hangover, solid, bsize, alignment;
|
||||
int r, hangover, solid, alignment;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
if (fd == -1 || !orig_buf || bsize <= 0)
|
||||
return -1;
|
||||
|
||||
hangover = count % bsize;
|
||||
solid = count - hangover;
|
||||
@@ -213,15 +166,15 @@ out:
|
||||
* is implicitly included in the read/write offset, which can not be set to non-aligned
|
||||
* boundaries. Hence, we combine llseek with write.
|
||||
*/
|
||||
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset) {
|
||||
ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset) {
|
||||
char *frontPadBuf;
|
||||
void *frontPadBuf_base = NULL;
|
||||
int r, bsize, frontHang;
|
||||
int r, frontHang;
|
||||
size_t innerCount = 0;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
if (fd == -1 || !buf || bsize <= 0)
|
||||
return -1;
|
||||
|
||||
frontHang = offset % bsize;
|
||||
|
||||
@@ -255,7 +208,7 @@ ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset) {
|
||||
count -= innerCount;
|
||||
}
|
||||
|
||||
ret = count ? write_blockwise(fd, buf, count) : 0;
|
||||
ret = count ? write_blockwise(fd, bsize, buf, count) : 0;
|
||||
if (ret >= 0)
|
||||
ret += innerCount;
|
||||
out:
|
||||
@@ -264,171 +217,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int device_ready(struct crypt_device *cd, const char *device, int mode)
|
||||
{
|
||||
int devfd, r = 0;
|
||||
ssize_t s;
|
||||
struct stat st;
|
||||
char buf[512];
|
||||
|
||||
if(stat(device, &st) < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
|
||||
log_dbg("Trying to open and read device %s.", device);
|
||||
devfd = open(device, mode | O_DIRECT | O_SYNC);
|
||||
if(devfd < 0) {
|
||||
log_err(cd, _("Cannot open device %s for %s%s access.\n"), device,
|
||||
(mode & O_EXCL) ? _("exclusive ") : "",
|
||||
(mode & O_RDWR) ? _("writable") : _("read-only"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Try to read first sector */
|
||||
s = read_blockwise(devfd, buf, sizeof(buf));
|
||||
if (s < 0 || s != sizeof(buf)) {
|
||||
log_verbose(cd, _("Cannot read device %s.\n"), device);
|
||||
r = -EIO;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
close(devfd);
|
||||
|
||||
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,
|
||||
int *readonly, uint64_t *size)
|
||||
{
|
||||
struct stat st;
|
||||
unsigned long size_small;
|
||||
int fd, r = -1;
|
||||
int flags = 0;
|
||||
|
||||
*readonly = 0;
|
||||
*size = 0;
|
||||
|
||||
if (stat(device, &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* never wipe header on mounted device */
|
||||
if (device_check == DEV_EXCL && S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
/* Try to open read-write to check whether it is a read-only device */
|
||||
fd = open(device, O_RDWR | flags);
|
||||
if (fd == -1 && errno == EROFS) {
|
||||
*readonly = 1;
|
||||
fd = open(device, O_RDONLY | flags);
|
||||
}
|
||||
|
||||
if (fd == -1 && device_check == DEV_EXCL && errno == EBUSY)
|
||||
return -EBUSY;
|
||||
|
||||
if (fd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
||||
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
||||
* devices may be openend read-write but are read-only according to BLKROGET
|
||||
*/
|
||||
if (*readonly == 0 && (r = ioctl(fd, BLKROGET, readonly)) < 0)
|
||||
goto out;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) >= 0) {
|
||||
*size >>= SECTOR_SHIFT;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
|
||||
*size = (uint64_t)size_small;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = -EINVAL;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_check_and_adjust(struct crypt_device *cd,
|
||||
const char *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t *size,
|
||||
uint64_t *offset,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int r, real_readonly;
|
||||
uint64_t real_size;
|
||||
|
||||
if (!device)
|
||||
return -ENOTBLK;
|
||||
|
||||
r = get_device_infos(device, device_check, &real_readonly, &real_size);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Cannot use device %s which is in use "
|
||||
"(already mapped or mounted).\n"),
|
||||
device);
|
||||
else
|
||||
log_err(cd, _("Cannot get info about device %s.\n"),
|
||||
device);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (*offset >= real_size) {
|
||||
log_err(cd, _("Requested offset is beyond real size of device %s.\n"),
|
||||
device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!*size) {
|
||||
*size = real_size;
|
||||
if (!*size) {
|
||||
log_err(cd, _("Device %s has zero size.\n"), device);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
*size -= *offset;
|
||||
}
|
||||
|
||||
/* in case of size is set by parameter */
|
||||
if ((real_size - *offset) < *size) {
|
||||
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
|
||||
", backing device size = %" PRIu64,
|
||||
device, *offset, *size, real_size);
|
||||
log_err(cd, _("Device %s is too small.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (real_readonly)
|
||||
*flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".",
|
||||
*size, real_readonly ? "RO" : "RW", *offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MEMLOCK */
|
||||
#define DEFAULT_PROCESS_PRIORITY -18
|
||||
|
||||
@@ -467,60 +255,3 @@ int crypt_memlock_dec(struct crypt_device *ctx)
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
}
|
||||
|
||||
/* DEVICE TOPOLOGY */
|
||||
|
||||
/* block device topology ioctls, introduced in 2.6.32 */
|
||||
#ifndef BLKIOMIN
|
||||
#define BLKIOMIN _IO(0x12,120)
|
||||
#define BLKIOOPT _IO(0x12,121)
|
||||
#define BLKALIGNOFF _IO(0x12,122)
|
||||
#endif
|
||||
|
||||
void get_topology_alignment(const char *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment)
|
||||
{
|
||||
int dev_alignment_offset = 0;
|
||||
unsigned int min_io_size = 0, opt_io_size = 0;
|
||||
unsigned long temp_alignment = 0;
|
||||
int fd;
|
||||
|
||||
*required_alignment = default_alignment;
|
||||
*alignment_offset = 0;
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
/* minimum io size */
|
||||
if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
|
||||
log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
|
||||
device, default_alignment);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* optimal io size */
|
||||
if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
|
||||
opt_io_size = min_io_size;
|
||||
|
||||
/* alignment offset, bogus -1 means misaligned/unknown */
|
||||
if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
|
||||
dev_alignment_offset = 0;
|
||||
*alignment_offset = (unsigned long)dev_alignment_offset;
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
if (temp_alignment < (unsigned long)opt_io_size)
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
*required_alignment = temp_alignment;
|
||||
|
||||
log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
|
||||
min_io_size, opt_io_size, *alignment_offset, *required_alignment);
|
||||
out:
|
||||
(void)close(fd);
|
||||
}
|
||||
|
||||
420
lib/utils_device.c
Normal file
420
lib/utils_device.c
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* device backend utilities
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <unistd.h>
|
||||
#include "internal.h"
|
||||
|
||||
struct device {
|
||||
char *path;
|
||||
|
||||
char *file_path;
|
||||
int loop_fd;
|
||||
|
||||
int init_done:1;
|
||||
};
|
||||
|
||||
static int device_ready(const char *device)
|
||||
{
|
||||
int devfd, r = 0;
|
||||
struct stat st;
|
||||
|
||||
if(stat(device, &st) < 0) {
|
||||
log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
|
||||
|
||||
log_dbg("Trying to open and read device %s.", device);
|
||||
devfd = open(device, O_RDONLY | O_DIRECT | O_SYNC);
|
||||
if(devfd < 0) {
|
||||
log_err(NULL, _("Cannot open device %s.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_alloc(struct device **device, const char *path)
|
||||
{
|
||||
struct device *dev;
|
||||
int r;
|
||||
|
||||
if (!path) {
|
||||
*device = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev = malloc(sizeof(struct device));
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dev, 0, sizeof(struct device));
|
||||
dev->loop_fd = -1;
|
||||
|
||||
r = device_ready(path);
|
||||
if (!r) {
|
||||
dev->init_done = 1;
|
||||
} else if (r == -ENOTBLK) {
|
||||
/* alloc loop later */
|
||||
} else if (r < 0) {
|
||||
free(dev);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
|
||||
dev->path = strdup(path);
|
||||
if (!dev->path) {
|
||||
free(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*device = dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void device_free(struct device *device)
|
||||
{
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
if (device->loop_fd != -1) {
|
||||
log_dbg("Closed loop %s (%s).", device->path, device->file_path);
|
||||
close(device->loop_fd);
|
||||
}
|
||||
|
||||
free(device->file_path);
|
||||
free(device->path);
|
||||
free(device);
|
||||
}
|
||||
|
||||
/* Get block device path */
|
||||
const char *device_block_path(const struct device *device)
|
||||
{
|
||||
if (!device || !device->init_done)
|
||||
return NULL;
|
||||
|
||||
return device->path;
|
||||
}
|
||||
|
||||
/* Get path to device / file */
|
||||
const char *device_path(const struct device *device)
|
||||
{
|
||||
if (!device)
|
||||
return NULL;
|
||||
|
||||
if (device->file_path)
|
||||
return device->file_path;
|
||||
|
||||
return device->path;
|
||||
}
|
||||
|
||||
/* block device topology ioctls, introduced in 2.6.32 */
|
||||
#ifndef BLKIOMIN
|
||||
#define BLKIOMIN _IO(0x12,120)
|
||||
#define BLKIOOPT _IO(0x12,121)
|
||||
#define BLKALIGNOFF _IO(0x12,122)
|
||||
#endif
|
||||
|
||||
void device_topology_alignment(struct device *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment)
|
||||
{
|
||||
int dev_alignment_offset = 0;
|
||||
unsigned int min_io_size = 0, opt_io_size = 0;
|
||||
unsigned long temp_alignment = 0;
|
||||
int fd;
|
||||
|
||||
*required_alignment = default_alignment;
|
||||
*alignment_offset = 0;
|
||||
|
||||
if (!device || !device->path) //FIXME
|
||||
return;
|
||||
|
||||
fd = open(device->path, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
/* minimum io size */
|
||||
if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
|
||||
log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
|
||||
device->path, default_alignment);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* optimal io size */
|
||||
if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
|
||||
opt_io_size = min_io_size;
|
||||
|
||||
/* alignment offset, bogus -1 means misaligned/unknown */
|
||||
if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
|
||||
dev_alignment_offset = 0;
|
||||
*alignment_offset = (unsigned long)dev_alignment_offset;
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
if (temp_alignment < (unsigned long)opt_io_size)
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
*required_alignment = temp_alignment;
|
||||
|
||||
log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
|
||||
min_io_size, opt_io_size, *alignment_offset, *required_alignment);
|
||||
out:
|
||||
(void)close(fd);
|
||||
}
|
||||
|
||||
int device_block_size(struct device *device)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, bsize = 0, r = -EINVAL;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
fd = open(device->path, O_RDONLY);
|
||||
if(fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
goto out;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
r = (int)crypt_getpagesize();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
|
||||
r = bsize;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_read_ahead(struct device *device, uint32_t *read_ahead)
|
||||
{
|
||||
int fd, r = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(device->path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
|
||||
close(fd);
|
||||
|
||||
if (r)
|
||||
*read_ahead = (uint32_t) read_ahead_long;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Get data size in bytes */
|
||||
int device_size(struct device *device, uint64_t *size)
|
||||
{
|
||||
struct stat st;
|
||||
int devfd, r = -EINVAL;
|
||||
|
||||
devfd = open(device->path, O_RDONLY);
|
||||
if(devfd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (fstat(devfd, &st) < 0)
|
||||
goto out;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
*size = (uint64_t)st.st_size;
|
||||
r = 0;
|
||||
} else if (ioctl(devfd, BLKGETSIZE64, size) >= 0)
|
||||
r = 0;
|
||||
out:
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int device_info(struct device *device,
|
||||
enum devcheck device_check,
|
||||
int *readonly, uint64_t *size)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, r = -EINVAL, flags = 0;
|
||||
|
||||
*readonly = 0;
|
||||
*size = 0;
|
||||
|
||||
if (stat(device->path, &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* never wipe header on mounted device */
|
||||
if (device_check == DEV_EXCL && S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
/* Try to open read-write to check whether it is a read-only device */
|
||||
fd = open(device->path, O_RDWR | flags);
|
||||
if (fd == -1 && errno == EROFS) {
|
||||
*readonly = 1;
|
||||
fd = open(device->path, O_RDONLY | flags);
|
||||
}
|
||||
|
||||
if (fd == -1 && device_check == DEV_EXCL && errno == EBUSY)
|
||||
return -EBUSY;
|
||||
|
||||
if (fd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
//FIXME: add readonly check
|
||||
|
||||
*size = (uint64_t)st.st_size;
|
||||
*size >>= SECTOR_SHIFT;
|
||||
} else {
|
||||
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
||||
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
||||
* devices may be openend read-write but are read-only according to BLKROGET
|
||||
*/
|
||||
if (*readonly == 0 && (r = ioctl(fd, BLKROGET, readonly)) < 0)
|
||||
goto out;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) >= 0) {
|
||||
*size >>= SECTOR_SHIFT;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
r = -EINVAL;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int device_internal_prepare(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
char *loop_device;
|
||||
int r, loop_fd, readonly = 0;
|
||||
|
||||
if (device->init_done)
|
||||
return 0;
|
||||
|
||||
log_dbg("Allocating free loop device.");
|
||||
loop_device = crypt_loop_get_device();
|
||||
if (!loop_device) {
|
||||
log_err(cd, _("Cannot find a free loopback device.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Keep the loop open, dettached on last close. */
|
||||
loop_fd = crypt_loop_attach(loop_device, device->path, 0, 1, &readonly);
|
||||
if (loop_fd == -1) {
|
||||
log_err(cd, _("Attaching loopback device failed "
|
||||
"(loop device with autoclear flag is required).\n"));
|
||||
free(loop_device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = device_ready(loop_device);
|
||||
if (r < 0) {
|
||||
free(loop_device);
|
||||
return r;
|
||||
}
|
||||
|
||||
device->loop_fd = loop_fd;
|
||||
device->file_path = device->path;
|
||||
device->path = loop_device;
|
||||
device->init_done = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_block_adjust(struct crypt_device *cd,
|
||||
struct device *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t device_offset,
|
||||
uint64_t *size,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int r, real_readonly;
|
||||
uint64_t real_size;
|
||||
|
||||
if (!device)
|
||||
return -ENOTBLK;
|
||||
|
||||
r = device_internal_prepare(cd, device);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = device_info(device, device_check, &real_readonly, &real_size);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Cannot use device %s which is in use "
|
||||
"(already mapped or mounted).\n"),
|
||||
device->path);
|
||||
else
|
||||
log_err(cd, _("Cannot get info about device %s.\n"),
|
||||
device->path);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (device_offset >= real_size) {
|
||||
log_err(cd, _("Requested offset is beyond real size of device %s.\n"),
|
||||
device->path);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size && !*size) {
|
||||
*size = real_size;
|
||||
if (!*size) {
|
||||
log_err(cd, _("Device %s has zero size.\n"), device->path);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
*size -= device_offset;
|
||||
}
|
||||
|
||||
/* in case of size is set by parameter */
|
||||
if (size && ((real_size - device_offset) < *size)) {
|
||||
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
|
||||
", backing device size = %" PRIu64,
|
||||
device->path, device_offset, *size, real_size);
|
||||
log_err(cd, _("Device %s is too small.\n"), device->path);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flags && real_readonly)
|
||||
*flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (size)
|
||||
log_dbg("Calculated device size is %" PRIu64" sectors (%s), offset %" PRIu64 ".",
|
||||
*size, real_readonly ? "RO" : "RW", device_offset);
|
||||
return 0;
|
||||
}
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "utils_dm.h"
|
||||
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
|
||||
|
||||
static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
|
||||
@@ -168,82 +167,6 @@ char *crypt_lookup_dev(const char *dev_id)
|
||||
return devpath;
|
||||
}
|
||||
|
||||
static int crypt_sysfs_get_major_minor(const char *kname, int *major, int *minor)
|
||||
{
|
||||
char path[PATH_MAX], tmp[64] = {0};
|
||||
int fd, r = 0;
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/block/%s/dev", kname) < 0)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
r = read(fd, tmp, sizeof(tmp));
|
||||
close(fd);
|
||||
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
tmp[63] = '\0';
|
||||
if (sscanf(tmp, "%d:%d", major, minor) != 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int crypt_sysfs_get_holders_dir(const char *device, char *path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
|
||||
return 0;
|
||||
|
||||
if (snprintf(path, size, "/sys/dev/block/%d:%d/holders",
|
||||
major(st.st_rdev), minor(st.st_rdev)) < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *d;
|
||||
char path[PATH_MAX], *dmname;
|
||||
int major, minor, r = 0;
|
||||
|
||||
if (!crypt_sysfs_get_holders_dir(device, path, sizeof(path)))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(dir = opendir(path)))
|
||||
return -EINVAL;
|
||||
|
||||
while (!r && (d = readdir(dir))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (!dm_is_dm_kernel_name(d->d_name)) {
|
||||
r = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!crypt_sysfs_get_major_minor(d->d_name, &major, &minor)) {
|
||||
r = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(dmname = dm_device_path(NULL, major, minor))) {
|
||||
r = -EINVAL;
|
||||
break;
|
||||
}
|
||||
r = dm_check_segment(dmname, offset, size);
|
||||
free(dmname);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational)
|
||||
{
|
||||
char path[PATH_MAX], tmp[64] = {0};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
struct crypt_params_verity;
|
||||
struct device;
|
||||
|
||||
/* Device mapper backend - kernel support flags */
|
||||
#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */
|
||||
@@ -54,7 +55,7 @@ struct crypt_dm_active_device {
|
||||
uint64_t size; /* active device size */
|
||||
uint32_t flags; /* activation flags */
|
||||
const char *uuid;
|
||||
const char *data_device;
|
||||
struct device *data_device;
|
||||
union {
|
||||
struct {
|
||||
const char *cipher;
|
||||
@@ -67,7 +68,7 @@ struct crypt_dm_active_device {
|
||||
uint64_t iv_offset; /* IV initilisation sector */
|
||||
} crypt;
|
||||
struct {
|
||||
const char *hash_device;
|
||||
struct device *hash_device;
|
||||
|
||||
const char *root_hash;
|
||||
uint32_t root_hash_size;
|
||||
@@ -98,6 +99,5 @@ int dm_resume_and_reinstate_key(const char *name,
|
||||
char *dm_device_path(const char *prefix, int major, int minor);
|
||||
int dm_is_dm_device(int major, int minor);
|
||||
int dm_is_dm_kernel_name(const char *name);
|
||||
int dm_check_segment(const char *name, uint64_t offset, uint64_t size);
|
||||
|
||||
#endif /* _UTILS_DM_H */
|
||||
|
||||
@@ -34,18 +34,20 @@
|
||||
|
||||
#define MAXIMUM_WIPE_BYTES 1024 * 1024 * 32 /* 32 MiB */
|
||||
|
||||
static ssize_t _crypt_wipe_zero(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_zero(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
memset(buffer, 0, size);
|
||||
return write_lseek_blockwise(fd, buffer, size, offset);
|
||||
return write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_random(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_random(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
if (crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return write_lseek_blockwise(fd, buffer, size, offset);
|
||||
return write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -74,7 +76,8 @@ static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_disk(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
int r;
|
||||
unsigned int i;
|
||||
@@ -95,22 +98,23 @@ static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
written = write_lseek_blockwise(fd, buffer, size, offset);
|
||||
written = write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
||||
if (written < 0 || written != (ssize_t)size)
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Rewrite it finally with random */
|
||||
return _crypt_wipe_random(fd, buffer, offset, size);
|
||||
return _crypt_wipe_random(fd, bsize, buffer, offset, size);
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_ssd(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_ssd(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
// FIXME: for now just rewrite it by random
|
||||
return _crypt_wipe_random(fd, buffer, offset, size);
|
||||
return _crypt_wipe_random(fd, bsize, buffer, offset, size);
|
||||
}
|
||||
|
||||
int crypt_wipe(const char *device,
|
||||
int crypt_wipe(struct device *device,
|
||||
uint64_t offset,
|
||||
uint64_t size,
|
||||
crypt_wipe_type type,
|
||||
@@ -118,17 +122,17 @@ int crypt_wipe(const char *device,
|
||||
{
|
||||
struct stat st;
|
||||
char *buffer;
|
||||
int devfd, flags, rotational;
|
||||
int devfd, flags, rotational, bsize;
|
||||
ssize_t written;
|
||||
|
||||
if (!size || size % SECTOR_SIZE || (size > MAXIMUM_WIPE_BYTES)) {
|
||||
log_dbg("Unsuported wipe size for device %s: %ld.",
|
||||
device, (unsigned long)size);
|
||||
device_path(device), (unsigned long)size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stat(device, &st) < 0) {
|
||||
log_dbg("Device %s not found.", device);
|
||||
if (stat(device_path(device), &st) < 0) {
|
||||
log_dbg("Device %s not found.", device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -142,6 +146,10 @@ int crypt_wipe(const char *device,
|
||||
type = CRYPT_WIPE_SSD;
|
||||
}
|
||||
|
||||
bsize = device_block_size(device);
|
||||
if (bsize <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
buffer = malloc(size);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
@@ -152,7 +160,7 @@ int crypt_wipe(const char *device,
|
||||
if (exclusive && S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
devfd = open(device, flags);
|
||||
devfd = open(device_path(device), flags);
|
||||
if (devfd == -1) {
|
||||
free(buffer);
|
||||
return errno == EBUSY ? -EBUSY : -EINVAL;
|
||||
@@ -161,16 +169,16 @@ int crypt_wipe(const char *device,
|
||||
// FIXME: use fixed block size and loop here
|
||||
switch (type) {
|
||||
case CRYPT_WIPE_ZERO:
|
||||
written = _crypt_wipe_zero(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_zero(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_DISK:
|
||||
written = _crypt_wipe_disk(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_disk(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_SSD:
|
||||
written = _crypt_wipe_ssd(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_ssd(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_RANDOM:
|
||||
written = _crypt_wipe_random(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_random(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
default:
|
||||
log_dbg("Unsuported wipe type requested: (%d)", type);
|
||||
|
||||
@@ -52,11 +52,12 @@ struct verity_sb {
|
||||
|
||||
/* Read verity superblock from disk */
|
||||
int VERITY_read_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
char **uuid_string,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
const char *device = device_path(crypt_metadata_device(cd));
|
||||
int bsize = device_block_size(crypt_metadata_device(cd));
|
||||
struct verity_sb sb = {};
|
||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||
int devfd = 0, sb_version;
|
||||
@@ -81,7 +82,7 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if(lseek(devfd, sb_offset, SEEK_SET) < 0 ||
|
||||
read_blockwise(devfd, &sb, hdr_size) < hdr_size) {
|
||||
read_blockwise(devfd, bsize, &sb, hdr_size) < hdr_size) {
|
||||
close(devfd);
|
||||
return -EIO;
|
||||
}
|
||||
@@ -144,11 +145,12 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
|
||||
/* Write verity superblock to disk */
|
||||
int VERITY_write_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
const char *uuid_string,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
const char *device = device_path(crypt_metadata_device(cd));
|
||||
int bsize = device_block_size(crypt_metadata_device(cd));
|
||||
struct verity_sb sb = {};
|
||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||
uuid_t uuid;
|
||||
@@ -184,7 +186,7 @@ int VERITY_write_sb(struct crypt_device *cd,
|
||||
memcpy(sb.salt, params->salt, params->salt_size);
|
||||
memcpy(sb.uuid, uuid, sizeof(sb.uuid));
|
||||
|
||||
r = write_lseek_blockwise(devfd, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
||||
r = write_lseek_blockwise(devfd, bsize, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
||||
if (r)
|
||||
log_err(cd, _("Error during update of verity header on device %s.\n"), device);
|
||||
close(devfd);
|
||||
@@ -220,14 +222,12 @@ int VERITY_UUID_generate(struct crypt_device *cd, char **uuid_string)
|
||||
/* Activate verity device in kernel device-mapper */
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd;
|
||||
uint64_t offset = 0;
|
||||
int r;
|
||||
|
||||
log_dbg("Trying to activate VERITY device %s using hash %s.",
|
||||
@@ -236,7 +236,6 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
|
||||
log_dbg("Verification of data in userspace required.");
|
||||
r = VERITY_verify(cd, verity_hdr,
|
||||
crypt_get_device_name(cd), hash_device,
|
||||
root_hash, root_hash_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -246,8 +245,8 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
return 0;
|
||||
|
||||
dmd.target = DM_VERITY;
|
||||
dmd.data_device = crypt_get_device_name(cd);
|
||||
dmd.u.verity.hash_device = hash_device;
|
||||
dmd.data_device = crypt_data_device(cd);
|
||||
dmd.u.verity.hash_device = crypt_metadata_device(cd);
|
||||
dmd.u.verity.root_hash = root_hash;
|
||||
dmd.u.verity.root_hash_size = root_hash_size;
|
||||
dmd.u.verity.hash_offset = VERITY_hash_offset_block(verity_hdr),
|
||||
@@ -256,8 +255,13 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
dmd.uuid = crypt_get_uuid(cd);
|
||||
dmd.u.verity.vp = verity_hdr;
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
&dmd.size, &offset, &dmd.flags);
|
||||
r = device_block_adjust(cd, dmd.u.verity.hash_device, DEV_OK,
|
||||
0, NULL, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = device_block_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
0, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -31,20 +31,17 @@ struct crypt_device;
|
||||
struct crypt_params_verity;
|
||||
|
||||
int VERITY_read_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
char **uuid,
|
||||
struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_write_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
const char *uuid_string,
|
||||
struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
@@ -52,15 +49,11 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
int VERITY_verify(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
|
||||
@@ -202,8 +202,8 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
int verify,
|
||||
int version,
|
||||
const char *hash_name,
|
||||
const char *hash_device,
|
||||
const char *data_device,
|
||||
struct device *hash_device,
|
||||
struct device *data_device,
|
||||
size_t hash_block_size,
|
||||
size_t data_block_size,
|
||||
off_t data_blocks,
|
||||
@@ -227,7 +227,8 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
log_dbg("Hash %s %s, data device %s, data blocks %" PRIu64
|
||||
", hash_device %s, offset %" PRIu64 ".",
|
||||
verify ? "verification" : "creation", hash_name,
|
||||
data_device, data_blocks, hash_device, hash_position);
|
||||
device_path(data_device), data_blocks,
|
||||
device_path(hash_device), hash_position);
|
||||
|
||||
if (data_blocks < 0 || hash_position < 0) {
|
||||
log_err(cd, _("Invalid size parameters for verity device.\n"));
|
||||
@@ -288,18 +289,21 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
|
||||
log_dbg("Data device size required: %" PRIu64 " bytes.",
|
||||
data_device_size);
|
||||
data_file = fopen(data_device, "r");
|
||||
data_file = fopen(device_path(data_device), "r");
|
||||
if (!data_file) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), data_device);
|
||||
log_err(cd, _("Cannot open device %s.\n"),
|
||||
device_path(data_device)
|
||||
);
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg("Hash device size required: %" PRIu64 " bytes.",
|
||||
hash_device_size);
|
||||
hash_file = fopen(hash_device, verify ? "r" : "r+");
|
||||
hash_file = fopen(device_path(hash_device), verify ? "r" : "r+");
|
||||
if (!hash_file) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), hash_device);
|
||||
log_err(cd, _("Cannot open device %s.\n"),
|
||||
device_path(hash_device));
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -316,9 +320,10 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
if (r)
|
||||
goto out;
|
||||
} else {
|
||||
hash_file_2 = fopen(hash_device, "r");
|
||||
hash_file_2 = fopen(device_path(hash_device), "r");
|
||||
if (!hash_file_2) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), hash_device);
|
||||
log_err(cd, _("Cannot open device %s.\n"),
|
||||
device_path(hash_device));
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -378,16 +383,14 @@ out:
|
||||
/* Verify verity device using userspace crypto backend */
|
||||
int VERITY_verify(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
return VERITY_create_or_verify_hash(cd, 1,
|
||||
verity_hdr->hash_type,
|
||||
verity_hdr->hash_name,
|
||||
hash_device,
|
||||
data_device,
|
||||
crypt_metadata_device(cd),
|
||||
crypt_data_device(cd),
|
||||
verity_hdr->hash_block_size,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
@@ -401,8 +404,6 @@ int VERITY_verify(struct crypt_device *cd,
|
||||
/* Create verity hash */
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
@@ -418,8 +419,8 @@ int VERITY_create(struct crypt_device *cd,
|
||||
return VERITY_create_or_verify_hash(cd, 0,
|
||||
verity_hdr->hash_type,
|
||||
verity_hdr->hash_name,
|
||||
hash_device,
|
||||
data_device,
|
||||
crypt_metadata_device(cd),
|
||||
crypt_data_device(cd),
|
||||
verity_hdr->hash_block_size,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
|
||||
Reference in New Issue
Block a user