On Aug 8, 2012, at 1:56 PM, Milan Broz wrote: > On 08/08/2012 10:46 PM, Wesley Miaw wrote: > >> I did modify veritysetup on my own so the format and verify commands will work with regular files on disk instead of having to mount through loop devices. > > Which veritysetup? In upstream (cryptsetup repository) it allocates loop automatically. > (And for userspace verification it doesn't need loop at all.) > > Anyway, please send a patch for userspace as well then ;-) This isn't as polished because I pretty much just added support to do what I needed. I'm not sure if the LKML is the right place to post, so let me know if I should send this somewhere else. Your previous email implied that veritysetup would need a way to determine if the data offset option is supported; I did not modify veritysetup to support this idea as I didn't need it. Thanks. From: Wesley Miaw <wmiaw@xxxxxxxxxxx> Allow veritysetup format and verify commands to directly operate on regular files instead of requiring mounts through loop devices. Signed-off-by: Wesley Miaw <wmiaw@xxxxxxxxxxx> --- cryptsetup/lib/internal.h | 1 cryptsetup/lib/libcryptsetup.h | 22 ++++ cryptsetup/lib/libcryptsetup.sym | 2 cryptsetup/lib/setup.c | 133 ++++++++++++++++++++++++++++- cryptsetup/lib/utils.c | 12 ++ cryptsetup/src/veritysetup.c | 23 +++-- 6 files changed, 183 insertions(+), 10 deletions(-) --- a/cryptsetup/lib/internal.h 2012-08-08 17:11:20.366392301 -0700 +++ b/cryptsetup/lib/internal.h 2012-08-06 16:17:35.154719491 -0700 @@ -76,6 +76,7 @@ ssize_t read_blockwise(int fd, void *_bu 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); +int file_size(const char *filename, uint64_t *size); unsigned crypt_getpagesize(void); --- a/cryptsetup/lib/libcryptsetup.h 2012-08-08 17:11:20.375392929 -0700 +++ b/cryptsetup/lib/libcryptsetup.h 2012-08-06 16:17:35.159720699 -0700 @@ -56,6 +57,19 @@ struct crypt_device; /* crypt device han int crypt_init(struct crypt_device **cd, const char *device); /** + * Initial crypt device handle from a file and check if provided file exists. + * + * @param cd Returns pointer to crypt device handle. + * @param filename Path to the backing file. + * + * @return @e 0 on success or negative errno value otherwise. + * + * @note Note that logging is not initialized here, possible messages uses + * default log function. + */ +int crypt_initfile(struct crypt_device **cd, const char *filename); + +/** * Initialize crypt device handle from provided active device name, * and, optionally, from separate metadata (header) device * and check if provided device exists. @@ -237,6 +251,15 @@ void crypt_set_password_verify(struct cr int crypt_set_data_device(struct crypt_device *cd, const char *device); /** + * Set data file + * For VERITY it is data file when hash device is separated. + * + * @param cd crypt device handle + * @param filename path to data file + */ +int crypt_set_data_file(struct crypt_device *cd, const char *device); + +/** * @defgroup rng "Cryptsetup RNG" * * @addtogroup rng --- a/cryptsetup/lib/libcryptsetup.sym 2012-08-08 17:11:20.375392930 -0700 +++ b/cryptsetup/lib/libcryptsetup.sym 2012-08-06 16:17:35.160720941 -0700 @@ -1,6 +1,7 @@ CRYPTSETUP_1.0 { global: crypt_init; + crypt_initfile; crypt_init_by_name; crypt_init_by_name_and_header; crypt_set_log_callback; @@ -13,6 +14,7 @@ CRYPTSETUP_1.0 { crypt_set_password_verify; crypt_set_uuid; crypt_set_data_device; + crypt_set_data_file; crypt_memory_lock; crypt_format; --- a/cryptsetup/lib/setup.c 2012-08-08 17:11:20.428396640 -0700 +++ b/cryptsetup/lib/setup.c 2012-08-06 16:17:35.192728669 -0700 @@ -25,6 +25,8 @@ #include <stdarg.h> #include <fcntl.h> #include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> #include "libcryptsetup.h" #include "luks.h" @@ -585,6 +587,56 @@ bad: return r; } +int crypt_initfile(struct crypt_device **cd, const char *filename) +{ + struct crypt_device *h = NULL; + int fd; + struct stat st; + int r; + + if (!cd) + return -EINVAL; + + if (stat(filename, &st) < 0) { + log_err(NULL, _("File %s doesn't exist or access denied.\n"), filename); + return -EINVAL; + } + + log_dbg("Trying to open and write file %s.", filename); + fd = open(filename, O_RDWR); + if (fd < 0) { + log_err(NULL, _("Cannot open file %s for writeable access.\n"), filename); + return -EINVAL; + } + close(fd); + + log_dbg("Allocating crypt device %s context.", filename); + + if (!(h = malloc(sizeof(struct crypt_device)))) + return -ENOMEM; + + memset(h, 0, sizeof(*h)); + h->loop_device_fd = -1; + h->loop_metadata_device_fd = -1; + h->device = strdup(filename); + if (!h->device) { + r = -ENOMEM; + goto bad; + } + h->iteration_time = 1000; + h->password_verify = 0; + h->tries = 3; + h->rng_type = crypt_random_default_key_rng(); + *cd = h; + return 0; +bad: + if (h) { + free(h->device); + } + free(h); + return r; +} + static int crypt_check_data_device_size(struct crypt_device *cd) { int r; @@ -606,6 +658,27 @@ static int crypt_check_data_device_size( return r; } +static int crypt_check_data_file_size(struct crypt_device *cd) +{ + int r; + uint64_t size, size_min; + + /* Check data device size, require at least one sector */ + size_min = crypt_get_data_offset(cd) << SECTOR_SHIFT ?: SECTOR_SIZE; + + r = file_size(crypt_get_device_name(cd), &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)); + return -EINVAL; + } + + return r; +} + int crypt_set_data_device(struct crypt_device *cd, const char *device) { char *data_device = NULL; @@ -641,6 +714,52 @@ int crypt_set_data_device(struct crypt_d return crypt_check_data_device_size(cd); } +int crypt_set_data_file(struct crypt_device *cd, const char *filename) +{ + int fd; + struct stat st; + + log_dbg("Setting ciphertext data file to %s.", filename ?: "(none"); + + if (!isVERITY(cd->type)) { + log_err(cd, _("This operation is not supported for this device type.\n")); + return -EINVAL; + } + + /* metadata device must be set */ + if (!cd->device || !filename) + return -EINVAL; + + if (stat(filename, &st) < 0) { + log_err(NULL, _("File %s doesn't exist or access denied.\n"), filename); + return -EINVAL; + } + + log_dbg("Trying to open and read file %s.", filename); + fd = open(filename, O_RDONLY); + if (fd < 0) { + log_err(NULL, _("Cannot open file %s for read access.\n"), filename); + return -EINVAL; + } + close(fd); + + 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); + } + + cd->device = strdup(filename); + if (!cd->device) + return -ENOMEM; + cd->loop_device_fd = -1; + + return crypt_check_data_file_size(cd); +} + static int _crypt_load_luks1(struct crypt_device *cd, int require_header, int repair) { struct luks_phdr hdr; @@ -1080,12 +1199,18 @@ static int _crypt_format_verity(struct c return -ENOMEM; r = crypt_set_data_device(cd, params->data_device); - if (r) - return r; + if (r) { + r = crypt_set_data_file(cd, params->data_device); + if (r) + return r; + } if (!params->data_size) { r = device_size(cd->device, &data_device_size); - if (r < 0) - return r; + if (r < 0) { + r = file_size(cd->device, &data_device_size); + if (r < 0) + return r; + } cd->verity_hdr.data_size = data_device_size / params->data_block_size; } else --- a/cryptsetup/lib/utils.c 2012-08-08 17:11:20.433396990 -0700 +++ b/cryptsetup/lib/utils.c 2012-08-06 16:17:35.202731084 -0700 @@ -316,6 +316,18 @@ int device_size(const char *device, uint return r; } +int file_size(const char *filename, uint64_t *size) +{ + struct stat st; + + if (stat(filename, &st) < 0) + return -EINVAL; + + *size = (uint64_t)st.st_size; + + return 0; +} + static int get_device_infos(const char *device, enum devcheck device_check, int *readonly, uint64_t *size) { --- a/cryptsetup/src/veritysetup.c 2012-08-08 17:11:20.942432624 -0700 +++ b/cryptsetup/src/veritysetup.c 2012-08-06 16:17:35.235739053 -0700 @@ -142,8 +142,12 @@ static int action_format(int arg) uint32_t flags = CRYPT_VERITY_CREATE_HASH; int r; - if ((r = crypt_init(&cd, action_argv[1]))) - goto out; + r = crypt_init(&cd, action_argv[1]); + if (r < 0) { + r = crypt_initfile(&cd, action_argv[1]); + if (r < 0) + goto out; + } if (!use_superblock) flags |= CRYPT_VERITY_NO_HEADER; @@ -174,8 +178,12 @@ static int _activate(const char *dm_devi ssize_t hash_size; int r; - if ((r = crypt_init(&cd, hash_device))) - goto out; + r = crypt_init(&cd, hash_device); + if (r < 0) { + r = crypt_initfile(&cd, hash_device); + if (r < 0) + goto out; + } if (use_superblock) { params.flags = flags; @@ -190,8 +198,11 @@ static int _activate(const char *dm_devi if (r < 0) goto out; r = crypt_set_data_device(cd, data_device); - if (r < 0) - goto out; + if (r < 0) { + r = crypt_set_data_file(cd, data_device); + if (r < 0) + goto out; + } hash_size = crypt_get_volume_key_size(cd); if (crypt_hex_to_bytes(root_hash, &root_hash_bytes, 0) != hash_size) {
Attachment:
signature.asc
Description: Message signed with OpenPGP using GPGMail
-- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel