From 2639af74bfc77808ff8813feada914fc4bc91fff Mon Sep 17 00:00:00 2001 From: = Date: Sun, 20 Aug 2023 16:09:37 +0200 Subject: [PATCH 01/75] feat:Write module.c --- dm-vvz/Kbuild | 36 +++++++++++++++++++++ dm-vvz/Makefile | 44 ++++++++++++++++++++++++++ dm-vvz/module.c | 71 ++++++++++++++++++++++++++++++++++++++++++ dm-vvz/utils/log.h | 31 ++++++++++++++++++ dm-vvz/vvz_constants.h | 35 +++++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 dm-vvz/Kbuild create mode 100644 dm-vvz/Makefile create mode 100644 dm-vvz/module.c create mode 100644 dm-vvz/utils/log.h create mode 100644 dm-vvz/vvz_constants.h diff --git a/dm-vvz/Kbuild b/dm-vvz/Kbuild new file mode 100644 index 0000000..352db93 --- /dev/null +++ b/dm-vvz/Kbuild @@ -0,0 +1,36 @@ + # + # Copyright The Shufflecake Project Authors (2022) + # Copyright The Shufflecake Project Contributors (2022) + # Copyright Contributors to the The Shufflecake Project. + # + # See the AUTHORS file at the top-level directory of this distribution and at + # + # + # This file is part of the program shufflecake-c, which is part of the + # Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + # layer for Linux. See . + # + # This program is free software: you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by the Free + # Software Foundation, either version 2 of the License, or (at your option) + # any later version. 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, see . + # + +MODULE_NAME := vvz +obj-m := $(MODULE_NAME).o + + +OBJ_LIST := module.o + +$(MODULE_NAME)-y += $(OBJ_LIST) + + +# Normal CC flags +ccflags-y := -O2 +ccflags-y += -I$(src) +ccflags-y += -Wall -Wno-declaration-after-statement diff --git a/dm-vvz/Makefile b/dm-vvz/Makefile new file mode 100644 index 0000000..45cdc18 --- /dev/null +++ b/dm-vvz/Makefile @@ -0,0 +1,44 @@ + # + # Copyright The Shufflecake Project Authors (2022) + # Copyright The Shufflecake Project Contributors (2022) + # Copyright Contributors to the The Shufflecake Project. + # + # See the AUTHORS file at the top-level directory of this distribution and at + # + # + # This file is part of the program shufflecake-c, which is part of the + # Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + # layer for Linux. See . + # + # This program is free software: you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by the Free + # Software Foundation, either version 2 of the License, or (at your option) + # any later version. 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, see . + # + +KERNEL_DIR = /lib/modules/$(shell uname -r)/build +SRC_DIR = $(shell pwd) +BUILD_DIR = $(shell pwd)/bin +BUILD_DIR_MAKEFILE = $(BUILD_DIR)/Makefile + +default: $(BUILD_DIR_MAKEFILE) + make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) modules + +$(BUILD_DIR_MAKEFILE): $(BUILD_DIR) + echo "# This Makefile is here because of Kbuild" > $@ + +$(BUILD_DIR): + mkdir -p $@ + + +install: + make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) modules_install + +clean: + rm -rf $(BUILD_DIR) + diff --git a/dm-vvz/module.c b/dm-vvz/module.c new file mode 100644 index 0000000..68ca855 --- /dev/null +++ b/dm-vvz/module.c @@ -0,0 +1,71 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include "dm_target.h" +#include "vvz_constants.h" +#include "utils/log.h" + + +static struct target_type vvz_target = { + .name = "vvz", + .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, + .module = THIS_MODULE, + .ctr = vvz_ctr, + .dtr = vvz_dtr, + .map = vvz_map, + .io_hints = vvz_io_hints, + .iterate_devices = vvz_iterate_devices, +}; + + +/* Module entry point: register DM target */ +static int __init vvz_init(void) +{ + int ret; + + ret = dm_register_target(&vvz_target); + if (ret < 0) + return ret; + + DMINFO("vvz loaded"); + return 0; +} + +/* Module exit point: unregister DM target */ +static void __exit vvz_exit(void) +{ + dm_unregister_target(&vvz_target); + + DMINFO("vvz unloaded"); + return; +} + + +module_init(vvz_init); +module_exit(vvz_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("The Shufflecake Project Authors"); +MODULE_DESCRIPTION(DM_NAME " target for Shufflecake"); diff --git a/dm-vvz/utils/log.h b/dm-vvz/utils/log.h new file mode 100644 index 0000000..160454d --- /dev/null +++ b/dm-vvz/utils/log.h @@ -0,0 +1,31 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _VVZ_UTILS_LOG_H_ +#define _VVZ_UTILS_LOG_H_ + + +#define DM_MSG_PREFIX "vvz" + + +#endif /* _VVZ_UTILS_LOG_H_ */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h new file mode 100644 index 0000000..aed4038 --- /dev/null +++ b/dm-vvz/vvz_constants.h @@ -0,0 +1,35 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* This is just a placeholder for defining constants and parameters that must be the same across shufflecake components (kernel module, userland tool, etc) such as block size, slice size etc */ + + +#define VVZ_VER_MAJOR 0 +#define VVZ_VER_MINOR 4 +#define VVZ_VER_REVISION 0 +#define VVZ_VER_SPECIAL "rc1" + +#define STRINGIFY0(s) # s +#define STRINGIFY(s) STRINGIFY0(s) + +#define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL From f26edc18dc3b6426d4a6b664023dd0f3ae4c5539 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 20 Aug 2023 17:25:00 +0200 Subject: [PATCH 02/75] feat:Write target stub --- dm-vvz/dm_target.c | 118 +++++++++++++++++++++++++++++++++++++++++ dm-vvz/dm_target.h | 38 +++++++++++++ dm-vvz/module.c | 2 +- dm-vvz/vvz_constants.h | 9 ++++ 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 dm-vvz/dm_target.c create mode 100644 dm-vvz/dm_target.h diff --git a/dm-vvz/dm_target.c b/dm-vvz/dm_target.c new file mode 100644 index 0000000..939481e --- /dev/null +++ b/dm-vvz/dm_target.c @@ -0,0 +1,118 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include "dm_target.h" +#include "vvz_constants.h" +#include "utils/log.h" + + +/* Create volume and, if needed, the underlying device */ +int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + char *bdev_path; + int vol_idx; + char *enckey_hex; + u8 enckey[VVZ_CRYPTO_KEYLEN]; + u32 tot_slices; + int err; + + /* + * Parse arguments. + * + * argv[0]: underlying block device path + * argv[1]: volume index within the device + * argv[2]: number of 1-MiB slices in the underlying device + * argv[3]: 32-byte encryption key (hex-encoded) + */ + if (argc != 4) { + ti->error = "Invalid argument count"; + return -EINVAL; + } + bdev_path = argv[0]; + sscanf(argv[1], "%d", &vol_idx); + sscanf(argv[2], "%u", &tot_slices); + enckey_hex = argv[3]; + + /* Decode the encryption key */ + if (strlen(enckey_hex) != 2 * SFLC_SK_KEY_LEN) { + ti->error = "Invalid key length"; + return -EINVAL; + } + err = hex2bin(enckey, enckey_hex, VVZ_CRYPTO_KEYLEN); + if (err) { + ti->error = "Could not decode hexadecimal encryption key"; + return err; + } + + // TODO: create device if needed + + // TODO: create volume + + /* Only accept one block per request for simplicity TODO: improve to one slice*/ + ti->max_io_len = VVZ_LOG_SECTOR_SCALE; + /* Disable REQ_OP_FLUSH bios TODO: enable for lazy posmap syncing */ + ti->num_flush_bios = 1; + /* Disable REQ_OP_DISCARD_BIOS TODO: enable for slice reclamation */ + ti->num_discard_bios = 0; + ti->num_secure_erase_bios = 0; + ti->num_write_zeroes_bios = 0; + /* TODO: set to volume handle */ + ti->private = NULL; + + return 0; +} + + +/* Destroy volume and, if needed, the underlying device */ +void vvz_dtr(struct dm_target *ti) +{ + /* TODO: implement */ + return; +} + + +int vvz_map(struct dm_target *ti, struct bio *bio) +{ + /* TODO: implement */ + return DM_MAPIO_REMAPPED; +} + + +void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) +{ + /* TODO: don't really know what to put here */ + limits->logical_block_size = VVZ_LOG_BLOCK_SIZE; + limits->physical_block_size = VVZ_LOG_BLOCK_SIZE; + limits->io_min = VVZ_LOG_BLOCK_SIZE; + limits->io_opt = VVZ_LOG_BLOCK_SIZE; + + return; +} + + +int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) +{ + /* TODO: implement */ + return 0; +} diff --git a/dm-vvz/dm_target.h b/dm-vvz/dm_target.h new file mode 100644 index 0000000..0e10f45 --- /dev/null +++ b/dm-vvz/dm_target.h @@ -0,0 +1,38 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _VVZ_DM_TARGET_H_ +#define _VVZ_DM_TARGET_H_ + + +#include + + +int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv); +void vvz_dtr(struct dm_target *ti); +int vvz_map(struct dm_target *ti, struct bio *bio); +void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits); +int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data); + + +#endif /* _VVZ_DM_TARGET_H_ */ diff --git a/dm-vvz/module.c b/dm-vvz/module.c index 68ca855..08201ad 100644 --- a/dm-vvz/module.c +++ b/dm-vvz/module.c @@ -67,5 +67,5 @@ module_init(vvz_init); module_exit(vvz_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("The Shufflecake Project Authors"); +MODULE_AUTHOR("Elia Anzuoni"); MODULE_DESCRIPTION(DM_NAME " target for Shufflecake"); diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index aed4038..39c550c 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -33,3 +33,12 @@ #define STRINGIFY(s) STRINGIFY0(s) #define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL + + +#define VVZ_CRYPTO_KEYLEN 32 /* bytes */ + + +#define VVZ_LOG_BLOCK_SIZE 4096 /* bytes */ +#define VVZ_LOG_SECTOR_SCALE 8 /* sectors in logical block */ +#define VVZ_PHYS_BLOCK_SIZE 4608 /* bytes */ +#define VVZ_PHYS_SECTOR_SCALE 9 /* sectors in physical block */ From 111b2914822011da93cc81902d9347ede9fa5808 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 20 Aug 2023 22:16:30 +0200 Subject: [PATCH 03/75] feat:Write device and volume stubs --- .gitignore | 1 + dm-vvz/device/device.h | 72 ++++++++++++++++++++++++++++++++++++++++++ dm-vvz/dm_target.c | 46 +++++++++++++++++++++++---- dm-vvz/dm_target.h | 3 ++ dm-vvz/module.c | 20 +++++++++--- dm-vvz/volume/volume.h | 66 ++++++++++++++++++++++++++++++++++++++ dm-vvz/vvz_constants.h | 5 +++ 7 files changed, 202 insertions(+), 11 deletions(-) create mode 100644 dm-vvz/device/device.h create mode 100644 dm-vvz/volume/volume.h diff --git a/.gitignore b/.gitignore index 26f4f24..52695bf 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ dkms.conf # Eclipse project files .project .cproject +.settings/ # Shufflecake binaries shufflecake diff --git a/dm-vvz/device/device.h b/dm-vvz/device/device.h new file mode 100644 index 0000000..629c67d --- /dev/null +++ b/dm-vvz/device/device.h @@ -0,0 +1,72 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * A device represents the underlying "physical" block device, common to all + * "virtual" volumes that map onto it. + */ + +#ifndef _VVZ_DEVICE_DEVICE_H_ +#define _VVZ_DEVICE_DEVICE_H_ + + +#include +#include "vvz_constants.h" + + +struct vvz_volume; + +struct vvz_device +{ + /* Shufflecake-unique device ID */ + size_t dev_id; + + /* Underlying block device */ + struct dm_dev *dev; + + /* All volumes mapping to this device */ + struct mutex vols_lock; + struct vvz_volume *vols[VVZ_DEV_MAX_VOLUMES]; + size_t num_vols; + + /* Slices stats */ + u32 tot_slices; + u32 free_slices; + + /* Shuffled array of PSIs */ + struct mutex shuffled_psis_lock; + u32 *shuffled_psis; + u32 first_free_psi; /* in the shuffled array */ + bool *psi_taken; + + /* Header sizes */ + u32 vol_header_size; + u32 dev_header_size; +}; + + +int vvz_dev_init(struct vvz_device *sd, struct dm_dev *dev, u32 tot_slices); +void vvz_dev_destroy(struct vvz_device *sd); + + +#endif /* _VVZ_DEVICE_DEVICE_H_ */ diff --git a/dm-vvz/dm_target.c b/dm-vvz/dm_target.c index 939481e..2ceccfa 100644 --- a/dm-vvz/dm_target.c +++ b/dm-vvz/dm_target.c @@ -21,17 +21,49 @@ * If not, see . */ -#include +#include #include "dm_target.h" +#include "device/device.h" #include "vvz_constants.h" #include "utils/log.h" +/* Global array of devices, and next free index */ +static DEFINE_MUTEX(alldevs_lock); +static struct vvz_device **alldevs = NULL; +static size_t free_devid = 0; + + +/* Set up module-global variables */ +int vvz_target_init() +{ + alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*alldevs)); + if (!alldevs) { + DMERR("vzalloc failed: could not allocate alldevs"); + return -ENOMEM; + } + + return 0; +} + + +/* Tear down module-global variables */ +void vvz_target_exit() +{ + if (alldevs) { + vfree(alldevs); + alldevs = NULL; + } + + return; +} + + /* Create volume and, if needed, the underlying device */ int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) { - char *bdev_path; - int vol_idx; + size_t dev_id; + size_t vol_idx; char *enckey_hex; u8 enckey[VVZ_CRYPTO_KEYLEN]; u32 tot_slices; @@ -40,7 +72,7 @@ int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* * Parse arguments. * - * argv[0]: underlying block device path + * argv[0]: Shufflecake ID of the underlying block device * argv[1]: volume index within the device * argv[2]: number of 1-MiB slices in the underlying device * argv[3]: 32-byte encryption key (hex-encoded) @@ -49,13 +81,13 @@ int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->error = "Invalid argument count"; return -EINVAL; } - bdev_path = argv[0]; - sscanf(argv[1], "%d", &vol_idx); + sscanf(argv[0], "%u", &dev_id); + sscanf(argv[1], "%u", &vol_idx); sscanf(argv[2], "%u", &tot_slices); enckey_hex = argv[3]; /* Decode the encryption key */ - if (strlen(enckey_hex) != 2 * SFLC_SK_KEY_LEN) { + if (strlen(enckey_hex) != 2 * VVZ_CRYPTO_KEYLEN) { ti->error = "Invalid key length"; return -EINVAL; } diff --git a/dm-vvz/dm_target.h b/dm-vvz/dm_target.h index 0e10f45..f527e23 100644 --- a/dm-vvz/dm_target.h +++ b/dm-vvz/dm_target.h @@ -28,6 +28,9 @@ #include +int vvz_target_init(); +void vvz_target_exit(); + int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv); void vvz_dtr(struct dm_target *ti); int vvz_map(struct dm_target *ti, struct bio *bio); diff --git a/dm-vvz/module.c b/dm-vvz/module.c index 08201ad..689b7b9 100644 --- a/dm-vvz/module.c +++ b/dm-vvz/module.c @@ -43,20 +43,32 @@ static struct target_type vvz_target = { /* Module entry point: register DM target */ static int __init vvz_init(void) { - int ret; + int err; - ret = dm_register_target(&vvz_target); - if (ret < 0) - return ret; + err = vvz_target_init(); + if (err < 0) + goto bad_target_init; + + err = dm_register_target(&vvz_target); + if (err < 0) + goto bad_register_target; DMINFO("vvz loaded"); return 0; + + +bad_register_target: + vvz_target_exit(); +bad_target_init: + DMERR("vvz not loaded"); + return err; } /* Module exit point: unregister DM target */ static void __exit vvz_exit(void) { dm_unregister_target(&vvz_target); + vvz_target_exit(); DMINFO("vvz unloaded"); return; diff --git a/dm-vvz/volume/volume.h b/dm-vvz/volume/volume.h new file mode 100644 index 0000000..b2bed0b --- /dev/null +++ b/dm-vvz/volume/volume.h @@ -0,0 +1,66 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * A volume represents a single "virtual" block device, mapping onto + * a "physical" device represented by a device. + */ + +#ifndef _VVZ_VOLUME_VOLUME_H_ +#define _VVZ_VOLUME_VOLUME_H_ + + +#include "device/device.h" + + +/* The volume name is "vvz__" */ +#define VVZ_VOL_NAME_MAX_LEN 12 + + +struct vvz_device; + +struct sflc_volume_s +{ + /* Volume index within the device */ + size_t vol_idx; + + /* Backing device */ + struct vvz_device *sd; + + /* Name of the volume, sflc__*/ + char vol_name[VVZ_VOL_NAME_MAX_LEN + 1]; + + /* Position map */ + struct mutex pmap_lock; + u32 *pmap; + + /* Slices stats */ + u32 mapped_slices; +}; + + +int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u8 *enckey); +void vvz_vol_destroy(struct vvz_volume *sv); + + +#endif /* _VVZ_VOLUME_VOLUME_H_ */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 39c550c..e4ff1bc 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -42,3 +42,8 @@ #define VVZ_LOG_SECTOR_SCALE 8 /* sectors in logical block */ #define VVZ_PHYS_BLOCK_SIZE 4608 /* bytes */ #define VVZ_PHYS_SECTOR_SCALE 9 /* sectors in physical block */ + + +#define VVZ_DEV_MAX_VOLUMES 15 +#define VVZ_MAX_DEVS 1024 + From 5727031afb8aff360e0fb520e606c87144905396 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 21 Aug 2023 15:41:28 +0200 Subject: [PATCH 04/75] feat:Write crypto --- dm-vvz/crypto.c | 64 +++++++++++++++++++++++++ dm-vvz/crypto.h | 35 ++++++++++++++ dm-vvz/device.c | 90 ++++++++++++++++++++++++++++++++++++ dm-vvz/{device => }/device.h | 16 +++---- dm-vvz/dm_target.c | 10 ++-- dm-vvz/{utils => }/log.h | 6 +-- dm-vvz/volume.c | 75 ++++++++++++++++++++++++++++++ dm-vvz/{volume => }/volume.h | 26 ++++++----- 8 files changed, 294 insertions(+), 28 deletions(-) create mode 100644 dm-vvz/crypto.c create mode 100644 dm-vvz/crypto.h create mode 100644 dm-vvz/device.c rename dm-vvz/{device => }/device.h (91%) rename dm-vvz/{utils => }/log.h (93%) create mode 100644 dm-vvz/volume.c rename dm-vvz/{volume => }/volume.h (83%) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c new file mode 100644 index 0000000..2608074 --- /dev/null +++ b/dm-vvz/crypto.c @@ -0,0 +1,64 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include "crypto.h" +#include "vvz_constants.h" +#include "log.h" + + +int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u8 *iv, int rw) +{ + struct skcipher_request *req = NULL; + DECLARE_CRYPTO_WAIT(wait); + struct scatterlist dst, src; + int err; + + /* TODO: not too sure about the gfp_mask here */ + req = skcipher_request_alloc(tfm, GFP_NOWAIT); + if (!req) + return -ENOMEM; + + skcipher_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + crypto_req_done, &wait); + + /* We assume PAGE_SIZE to equal Shufflecake's block size */ + // TODO: better document this, maybe ensure it with compile-time checks + sg_init_table(&dst, 1); + sg_set_page(&dst, dst_page, VVZ_LOG_BLOCK_SIZE, 0); + sg_init_table(&src, 1); + sg_set_page(&src, src_page, VVZ_LOG_BLOCK_SIZE, 0); + + skcipher_request_set_crypt(req, &src, &dst, VVZ_LOG_BLOCK_SIZE, iv); + if (rw == READ) + err = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); + else + err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); + skcipher_request_free(req); + + return err; +} + diff --git a/dm-vvz/crypto.h b/dm-vvz/crypto.h new file mode 100644 index 0000000..8455bdc --- /dev/null +++ b/dm-vvz/crypto.h @@ -0,0 +1,35 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _VVZ_CRYPTO_H_ +#define _VVZ_CRYPTO_H_ + + +#include + + +int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u8 *iv, int rw); + + +#endif /* _VVZ_CRYPTO_H_ */ diff --git a/dm-vvz/device.c b/dm-vvz/device.c new file mode 100644 index 0000000..5846c60 --- /dev/null +++ b/dm-vvz/device.c @@ -0,0 +1,90 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include "device.h" +#include "log.h" + + +int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 tot_slices) +{ + int err; + int i; + + sd->dev_id = dev_id; + sd->dev = dev; + + for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) + sd->vols[i] = NULL; + sd->num_vols = 0; + + sd->tot_slices = tot_slices; + sd->free_slices = tot_slices; + /* TODO: compute header sizes */ + + mutex_init(&sd->shuffled_psis_lock); + sd->psi_taken = vzalloc(sd->tot_slices * sizeof(bool)); + if (!sd->psi_taken) { + DMERR("Could not allocate PSI occupation bitfield\n"); + err = -ENOMEM; + goto bad; + } + sd->shuffled_psis = vmalloc(tot_slices * sizeof(u32)); + if (!sd->shuffled_psis) { + DMERR("Could not allocate shuffled PSI array\n"); + err = -ENOMEM; + goto bad; + } + sd->first_free_psi = 0; + + /* Generate a permutation */ + for (i = 0; i < tot_slices; i++) + sd->shuffled_psis[i] = i; + // TODO: shuffle + + // TODO: complete + + return 0; + + +bad: + vvz_device_destroy(sd); + return err; +} + + +/* Can only be called once per device */ +void vvz_dev_destroy(struct vvz_device *sd) +{ + if (sd->num_vols > 0) + DMCRIT("Destroying device that still has open volumes"); + + /* No locking needed here TODO: right? */ + if (sd->shuffled_psis) + vfree(sd->shuffled_psis); + if (sd->psi_taken) + vfree(sd->psi_taken); + + return; +} + diff --git a/dm-vvz/device/device.h b/dm-vvz/device.h similarity index 91% rename from dm-vvz/device/device.h rename to dm-vvz/device.h index 629c67d..d38f3bb 100644 --- a/dm-vvz/device/device.h +++ b/dm-vvz/device.h @@ -26,8 +26,8 @@ * "virtual" volumes that map onto it. */ -#ifndef _VVZ_DEVICE_DEVICE_H_ -#define _VVZ_DEVICE_DEVICE_H_ +#ifndef _VVZ_DEVICE_H_ +#define _VVZ_DEVICE_H_ #include @@ -53,20 +53,20 @@ struct vvz_device u32 tot_slices; u32 free_slices; + /* Header sizes */ + u32 posmap_size; + u32 dev_header_size; + /* Shuffled array of PSIs */ struct mutex shuffled_psis_lock; u32 *shuffled_psis; u32 first_free_psi; /* in the shuffled array */ bool *psi_taken; - - /* Header sizes */ - u32 vol_header_size; - u32 dev_header_size; }; -int vvz_dev_init(struct vvz_device *sd, struct dm_dev *dev, u32 tot_slices); +int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 tot_slices); void vvz_dev_destroy(struct vvz_device *sd); -#endif /* _VVZ_DEVICE_DEVICE_H_ */ +#endif /* _VVZ_DEVICE_H_ */ diff --git a/dm-vvz/dm_target.c b/dm-vvz/dm_target.c index 2ceccfa..2b03fcf 100644 --- a/dm-vvz/dm_target.c +++ b/dm-vvz/dm_target.c @@ -23,9 +23,9 @@ #include #include "dm_target.h" -#include "device/device.h" +#include "device.h" #include "vvz_constants.h" -#include "utils/log.h" +#include "log.h" /* Global array of devices, and next free index */ @@ -62,7 +62,7 @@ void vvz_target_exit() /* Create volume and, if needed, the underlying device */ int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) { - size_t dev_id; + char *bdev_path; size_t vol_idx; char *enckey_hex; u8 enckey[VVZ_CRYPTO_KEYLEN]; @@ -72,7 +72,7 @@ int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* * Parse arguments. * - * argv[0]: Shufflecake ID of the underlying block device + * argv[0]: path to underlying physical device * argv[1]: volume index within the device * argv[2]: number of 1-MiB slices in the underlying device * argv[3]: 32-byte encryption key (hex-encoded) @@ -81,7 +81,7 @@ int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->error = "Invalid argument count"; return -EINVAL; } - sscanf(argv[0], "%u", &dev_id); + bdev_path = argv[0]; sscanf(argv[1], "%u", &vol_idx); sscanf(argv[2], "%u", &tot_slices); enckey_hex = argv[3]; diff --git a/dm-vvz/utils/log.h b/dm-vvz/log.h similarity index 93% rename from dm-vvz/utils/log.h rename to dm-vvz/log.h index 160454d..2ad7ea9 100644 --- a/dm-vvz/utils/log.h +++ b/dm-vvz/log.h @@ -21,11 +21,11 @@ * If not, see . */ -#ifndef _VVZ_UTILS_LOG_H_ -#define _VVZ_UTILS_LOG_H_ +#ifndef _VVZ_LOG_H_ +#define _VVZ_LOG_H_ #define DM_MSG_PREFIX "vvz" -#endif /* _VVZ_UTILS_LOG_H_ */ +#endif /* _VVZ_LOG_H_ */ diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c new file mode 100644 index 0000000..ae8d345 --- /dev/null +++ b/dm-vvz/volume.c @@ -0,0 +1,75 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include "volume.h" +#include "log.h" + + +int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u8 *enckey) +{ + int err; + + sv->sd = sd; + sv->vol_idx = vol_idx; + sprintf(sv->vol_name, "sflc_%lu_%lu", sd->dev_id, vol_idx); + + mutex_init(&sv->posmap_lock); + sv->posmap = vmalloc(sd->tot_slices * sizeof(u32)); + if (!sv->posmap) { + DMERR("Could not allocate position map"); + err = -ENOMEM; + goto bad; + } + sv->mapped_slices = 0; + + sv->tfm = crypto_alloc_skcipher("ctr(aes)", 0, 0); + if (!sv->tfm) { + DMERR("Could not allocate AES-CTR cipher handle"); + err = -EINVAL; + goto bad; + } + + // TODO: complete + + return 0; + + +bad: + vvz_vol_destroy(sv); + return err; +} + + +/* Can only be called once per volume */ +void vvz_vol_destroy(struct vvz_volume *sv) +{ + if (sv->tfm) + crypto_free_skcipher(sv->tfm); + + /* No locking needed here TODO: right? */ + if (sv->posmap) + vfree(sv->posmap); + + return; +} diff --git a/dm-vvz/volume/volume.h b/dm-vvz/volume.h similarity index 83% rename from dm-vvz/volume/volume.h rename to dm-vvz/volume.h index b2bed0b..74daada 100644 --- a/dm-vvz/volume/volume.h +++ b/dm-vvz/volume.h @@ -22,24 +22,25 @@ */ /* - * A volume represents a single "virtual" block device, mapping onto - * a "physical" device represented by a device. + * A volume represents a single "virtual" block device, mapping onto a + * "physical" device represented by a device. */ -#ifndef _VVZ_VOLUME_VOLUME_H_ -#define _VVZ_VOLUME_VOLUME_H_ +#ifndef _VVZ_VOLUME_H_ +#define _VVZ_VOLUME_H_ -#include "device/device.h" +#include +#include "device.h" -/* The volume name is "vvz__" */ +/* The volume name is "sflc__" */ #define VVZ_VOL_NAME_MAX_LEN 12 struct vvz_device; -struct sflc_volume_s +struct vvz_volume { /* Volume index within the device */ size_t vol_idx; @@ -51,11 +52,12 @@ struct sflc_volume_s char vol_name[VVZ_VOL_NAME_MAX_LEN + 1]; /* Position map */ - struct mutex pmap_lock; - u32 *pmap; - - /* Slices stats */ + struct mutex posmap_lock; + u32 *posmap; u32 mapped_slices; + + /* Crypto */ + struct crypto_skcipher *tfm; }; @@ -63,4 +65,4 @@ int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u void vvz_vol_destroy(struct vvz_volume *sv); -#endif /* _VVZ_VOLUME_VOLUME_H_ */ +#endif /* _VVZ_VOLUME_H_ */ From 94f667bef0389c144aeedad72111edaf5c049338 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 21 Aug 2023 22:02:21 +0200 Subject: [PATCH 05/75] feat:Write Fisher-Yate --- dm-vvz/device.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 5846c60..f26907c 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -22,10 +22,15 @@ */ #include +#include #include "device.h" #include "log.h" +/* Fisher-Yates shuffle */ +static void fisheryates_u32(u32 *v, u32 len); + + int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 tot_slices) { int err; @@ -60,7 +65,7 @@ int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 t /* Generate a permutation */ for (i = 0; i < tot_slices; i++) sd->shuffled_psis[i] = i; - // TODO: shuffle + fisheryates_u32(sd->shuffled_psis, tot_slices); // TODO: complete @@ -88,3 +93,21 @@ void vvz_dev_destroy(struct vvz_device *sd) return; } + +/* Fisher-Yates shuffle */ +static void fisheryates_u32(u32 *v, u32 len) +{ + u32 i; + + for (i = len-1; i >= 1; i--) { + u32 j = get_random_u32_below(i+1); + + /* Swap v[i] and v[j] (without tmp variable 'cuz we're cool) */ + v[i] ^= v[j]; // v[i] <- a XOR b + v[j] ^= v[i]; // v[j] <- b XOR (a XOR b) = a + v[i] ^= v[j]; // v[i] <- (a XOR b) XOR a = b + } + + return; +} + From 787c79a61a4e8438274154808a8118e90aa97cf6 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 22 Aug 2023 15:54:42 +0200 Subject: [PATCH 06/75] feat:Write dev_add_vol --- dm-vvz/device.c | 77 +++++++++++++--- dm-vvz/device.h | 10 +- dm-vvz/dm_target.c | 150 ------------------------------ dm-vvz/dm_target.h | 41 --------- dm-vvz/module.c | 83 ----------------- dm-vvz/volume.c | 22 +++-- dm-vvz/volume.h | 4 +- dm-vvz/vvz.c | 221 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 309 insertions(+), 299 deletions(-) delete mode 100644 dm-vvz/dm_target.c delete mode 100644 dm-vvz/dm_target.h delete mode 100644 dm-vvz/module.c create mode 100644 dm-vvz/vvz.c diff --git a/dm-vvz/device.c b/dm-vvz/device.c index f26907c..9d8a9c7 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -31,14 +31,21 @@ static void fisheryates_u32(u32 *v, u32 len); -int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 tot_slices) +struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, + u32 dev_id, u32 tot_slices) { + struct vvz_device *sd; int err; int i; + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + DMERR("Could not allocate device"); + return NULL; + } sd->dev_id = dev_id; - sd->dev = dev; + mutex_init(&sd->vols_lock); for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) sd->vols[i] = NULL; sd->num_vols = 0; @@ -47,17 +54,22 @@ int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 t sd->free_slices = tot_slices; /* TODO: compute header sizes */ + err = dm_get_device(ti, bdev_path, + dm_table_get_mode(ti->table), &sd->dev); + if (err) { + DMERR("Could not get DM device"); + goto bad; + } + mutex_init(&sd->shuffled_psis_lock); sd->psi_taken = vzalloc(sd->tot_slices * sizeof(bool)); if (!sd->psi_taken) { - DMERR("Could not allocate PSI occupation bitfield\n"); - err = -ENOMEM; + DMERR("Could not allocate PSI occupation bitfield"); goto bad; } sd->shuffled_psis = vmalloc(tot_slices * sizeof(u32)); if (!sd->shuffled_psis) { - DMERR("Could not allocate shuffled PSI array\n"); - err = -ENOMEM; + DMERR("Could not allocate shuffled PSI array"); goto bad; } sd->first_free_psi = 0; @@ -69,17 +81,16 @@ int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 t // TODO: complete - return 0; + return sd; bad: - vvz_device_destroy(sd); - return err; + vvz_dev_free(sd, ti); + return NULL; } -/* Can only be called once per device */ -void vvz_dev_destroy(struct vvz_device *sd) +void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti) { if (sd->num_vols > 0) DMCRIT("Destroying device that still has open volumes"); @@ -90,6 +101,48 @@ void vvz_dev_destroy(struct vvz_device *sd) if (sd->psi_taken) vfree(sd->psi_taken); + if (sd->dev) + dm_put_device(ti, sd->dev); + + kfree(sd); + + return; +} + + +int vvz_dev_add_volume(struct vvz_device *sd, struct vvz_volume *sv, size_t vol_idx) +{ + int ret; + + if (mutex_lock_interruptible(&sd->vols_lock)) + return -EINTR; + + if (sd->vols[vol_idx]) { + DMERR("Volume slot %lu already taken", vol_idx); + ret = -EINVAL; + } else { + sd->vols[vol_idx] = sv; + sd->num_vols += 1; + ret = 0; + } + + mutex_unlock(&sd->vols_lock); + return ret; +} + + +void vvz_dev_remove_volume(struct vvz_device *sd, size_t vol_idx) +{ + if (mutex_lock_interruptible(&sd->vols_lock)) + return; + + if (sd->vols[vol_idx]) { + sd->vols[vol_idx] = NULL; + sd->num_vols -= 1; + } else + DMERR("Volume slot %lu already free", vol_idx); + + mutex_unlock(&sd->vols_lock); return; } @@ -102,7 +155,7 @@ static void fisheryates_u32(u32 *v, u32 len) for (i = len-1; i >= 1; i--) { u32 j = get_random_u32_below(i+1); - /* Swap v[i] and v[j] (without tmp variable 'cuz we're cool) */ + /* Swap v[i] and v[j] */ v[i] ^= v[j]; // v[i] <- a XOR b v[j] ^= v[i]; // v[j] <- b XOR (a XOR b) = a v[i] ^= v[j]; // v[i] <- (a XOR b) XOR a = b diff --git a/dm-vvz/device.h b/dm-vvz/device.h index d38f3bb..3c59e42 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -39,7 +39,7 @@ struct vvz_volume; struct vvz_device { /* Shufflecake-unique device ID */ - size_t dev_id; + u32 dev_id; /* Underlying block device */ struct dm_dev *dev; @@ -65,8 +65,12 @@ struct vvz_device }; -int vvz_dev_init(struct vvz_device *sd, size_t dev_id, struct dm_dev *dev, u32 tot_slices); -void vvz_dev_destroy(struct vvz_device *sd); +struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, + u32 dev_id, u32 tot_slices); +void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti); + +int vvz_dev_add_volume(struct vvz_device *sd, struct vvz_volume *sv, size_t vol_idx); +void vvz_dev_remove_volume(struct vvz_device *sd, size_t vol_idx); #endif /* _VVZ_DEVICE_H_ */ diff --git a/dm-vvz/dm_target.c b/dm-vvz/dm_target.c deleted file mode 100644 index 2b03fcf..0000000 --- a/dm-vvz/dm_target.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include "dm_target.h" -#include "device.h" -#include "vvz_constants.h" -#include "log.h" - - -/* Global array of devices, and next free index */ -static DEFINE_MUTEX(alldevs_lock); -static struct vvz_device **alldevs = NULL; -static size_t free_devid = 0; - - -/* Set up module-global variables */ -int vvz_target_init() -{ - alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*alldevs)); - if (!alldevs) { - DMERR("vzalloc failed: could not allocate alldevs"); - return -ENOMEM; - } - - return 0; -} - - -/* Tear down module-global variables */ -void vvz_target_exit() -{ - if (alldevs) { - vfree(alldevs); - alldevs = NULL; - } - - return; -} - - -/* Create volume and, if needed, the underlying device */ -int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) -{ - char *bdev_path; - size_t vol_idx; - char *enckey_hex; - u8 enckey[VVZ_CRYPTO_KEYLEN]; - u32 tot_slices; - int err; - - /* - * Parse arguments. - * - * argv[0]: path to underlying physical device - * argv[1]: volume index within the device - * argv[2]: number of 1-MiB slices in the underlying device - * argv[3]: 32-byte encryption key (hex-encoded) - */ - if (argc != 4) { - ti->error = "Invalid argument count"; - return -EINVAL; - } - bdev_path = argv[0]; - sscanf(argv[1], "%u", &vol_idx); - sscanf(argv[2], "%u", &tot_slices); - enckey_hex = argv[3]; - - /* Decode the encryption key */ - if (strlen(enckey_hex) != 2 * VVZ_CRYPTO_KEYLEN) { - ti->error = "Invalid key length"; - return -EINVAL; - } - err = hex2bin(enckey, enckey_hex, VVZ_CRYPTO_KEYLEN); - if (err) { - ti->error = "Could not decode hexadecimal encryption key"; - return err; - } - - // TODO: create device if needed - - // TODO: create volume - - /* Only accept one block per request for simplicity TODO: improve to one slice*/ - ti->max_io_len = VVZ_LOG_SECTOR_SCALE; - /* Disable REQ_OP_FLUSH bios TODO: enable for lazy posmap syncing */ - ti->num_flush_bios = 1; - /* Disable REQ_OP_DISCARD_BIOS TODO: enable for slice reclamation */ - ti->num_discard_bios = 0; - ti->num_secure_erase_bios = 0; - ti->num_write_zeroes_bios = 0; - /* TODO: set to volume handle */ - ti->private = NULL; - - return 0; -} - - -/* Destroy volume and, if needed, the underlying device */ -void vvz_dtr(struct dm_target *ti) -{ - /* TODO: implement */ - return; -} - - -int vvz_map(struct dm_target *ti, struct bio *bio) -{ - /* TODO: implement */ - return DM_MAPIO_REMAPPED; -} - - -void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) -{ - /* TODO: don't really know what to put here */ - limits->logical_block_size = VVZ_LOG_BLOCK_SIZE; - limits->physical_block_size = VVZ_LOG_BLOCK_SIZE; - limits->io_min = VVZ_LOG_BLOCK_SIZE; - limits->io_opt = VVZ_LOG_BLOCK_SIZE; - - return; -} - - -int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) -{ - /* TODO: implement */ - return 0; -} diff --git a/dm-vvz/dm_target.h b/dm-vvz/dm_target.h deleted file mode 100644 index f527e23..0000000 --- a/dm-vvz/dm_target.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _VVZ_DM_TARGET_H_ -#define _VVZ_DM_TARGET_H_ - - -#include - - -int vvz_target_init(); -void vvz_target_exit(); - -int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv); -void vvz_dtr(struct dm_target *ti); -int vvz_map(struct dm_target *ti, struct bio *bio); -void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits); -int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data); - - -#endif /* _VVZ_DM_TARGET_H_ */ diff --git a/dm-vvz/module.c b/dm-vvz/module.c deleted file mode 100644 index 689b7b9..0000000 --- a/dm-vvz/module.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include -#include "dm_target.h" -#include "vvz_constants.h" -#include "utils/log.h" - - -static struct target_type vvz_target = { - .name = "vvz", - .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, - .module = THIS_MODULE, - .ctr = vvz_ctr, - .dtr = vvz_dtr, - .map = vvz_map, - .io_hints = vvz_io_hints, - .iterate_devices = vvz_iterate_devices, -}; - - -/* Module entry point: register DM target */ -static int __init vvz_init(void) -{ - int err; - - err = vvz_target_init(); - if (err < 0) - goto bad_target_init; - - err = dm_register_target(&vvz_target); - if (err < 0) - goto bad_register_target; - - DMINFO("vvz loaded"); - return 0; - - -bad_register_target: - vvz_target_exit(); -bad_target_init: - DMERR("vvz not loaded"); - return err; -} - -/* Module exit point: unregister DM target */ -static void __exit vvz_exit(void) -{ - dm_unregister_target(&vvz_target); - vvz_target_exit(); - - DMINFO("vvz unloaded"); - return; -} - - -module_init(vvz_init); -module_exit(vvz_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Elia Anzuoni"); -MODULE_DESCRIPTION(DM_NAME " target for Shufflecake"); diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index ae8d345..a565b43 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -26,10 +26,17 @@ #include "log.h" -int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u8 *enckey) +struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enckey) { + struct vvz_volume *sv; int err; + sv = kzalloc(sizeof(*sv), GFP_KERNEL); + if (!sv) { + DMERR("Could not allocate volume"); + return NULL; + } + sv->sd = sd; sv->vol_idx = vol_idx; sprintf(sv->vol_name, "sflc_%lu_%lu", sd->dev_id, vol_idx); @@ -38,7 +45,6 @@ int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u sv->posmap = vmalloc(sd->tot_slices * sizeof(u32)); if (!sv->posmap) { DMERR("Could not allocate position map"); - err = -ENOMEM; goto bad; } sv->mapped_slices = 0; @@ -46,23 +52,21 @@ int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u sv->tfm = crypto_alloc_skcipher("ctr(aes)", 0, 0); if (!sv->tfm) { DMERR("Could not allocate AES-CTR cipher handle"); - err = -EINVAL; goto bad; } // TODO: complete - return 0; + return sv; bad: - vvz_vol_destroy(sv); - return err; + vvz_vol_free(sv); + return NULL; } -/* Can only be called once per volume */ -void vvz_vol_destroy(struct vvz_volume *sv) +void vvz_vol_free(struct vvz_volume *sv) { if (sv->tfm) crypto_free_skcipher(sv->tfm); @@ -71,5 +75,7 @@ void vvz_vol_destroy(struct vvz_volume *sv) if (sv->posmap) vfree(sv->posmap); + kfree(sv); + return; } diff --git a/dm-vvz/volume.h b/dm-vvz/volume.h index 74daada..3d3dbeb 100644 --- a/dm-vvz/volume.h +++ b/dm-vvz/volume.h @@ -61,8 +61,8 @@ struct vvz_volume }; -int vvz_vol_init(struct vvz_volume *sv, struct vvz_device *sd, size_t vol_idx, u8 *enckey); -void vvz_vol_destroy(struct vvz_volume *sv); +struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enckey); +void vvz_vol_free(struct vvz_volume *sv); #endif /* _VVZ_VOLUME_H_ */ diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c new file mode 100644 index 0000000..90e8459 --- /dev/null +++ b/dm-vvz/vvz.c @@ -0,0 +1,221 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include +#include "device.h" +#include "vvz_constants.h" +#include "log.h" + + +/* Global array of devices, and next free index */ +static DEFINE_MUTEX(alldevs_lock); +static struct vvz_device **alldevs = NULL; +static size_t free_devid = 0; + + +/* Create volume and, if needed, the underlying device */ +static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + u32 dev_id; + char *bdev_path; + size_t vol_idx; + char *enckey_hex; + u8 enckey[VVZ_CRYPTO_KEYLEN]; + u32 tot_slices; + struct vvz_device *sd; + struct vvz_volume *sv; + int err; + + /* + * Parse arguments. + * + * argv[0]: Shufflecake-unique device ID + * argv[1]: path to underlying physical device + * argv[2]: volume index within the device + * argv[3]: number of 1-MiB slices in the underlying device + * argv[4]: 32-byte encryption key (hex-encoded) + */ + if (argc != 5) { + ti->error = "Invalid argument count"; + return -EINVAL; + } + sscanf(argv[0], "%u", &dev_id); + bdev_path = argv[1]; + sscanf(argv[2], "%u", &vol_idx); + sscanf(argv[3], "%u", &tot_slices); + enckey_hex = argv[4]; + /* Sanity checks */ + if (dev_id >= VVZ_MAX_DEVS) { + ti->error = "Invalid device ID"; + return -EINVAL; + } + if (vol_idx >= VVZ_DEV_MAX_VOLUMES) { + ti->error = "Invalid volume index"; + return -EINVAL; + } + if (strlen(enckey_hex) != 2 * VVZ_CRYPTO_KEYLEN) { + ti->error = "Invalid key length"; + return -EINVAL; + } + /* Decode the encryption key */ + err = hex2bin(enckey, enckey_hex, VVZ_CRYPTO_KEYLEN); + if (err) { + ti->error = "Could not decode hexadecimal encryption key"; + return err; + } + + /* Create device if it does not yet exist */ + if (mutex_lock_interruptible(&alldevs_lock)) + return -EINTR; + sd = alldevs[dev_id]; + if (!sd) { + sd = vvz_dev_alloc(ti, bdev_path, dev_id, tot_slices); + if (!sd) { + ti->error = "Could not instantiate device"; + mutex_unlock(&alldevs_lock); + return -ENOMEM; + } + // TODO: register to sysfs + alldevs[dev_id] = sd; + } + mutex_unlock(&alldevs_lock); + + /* Create volume */ + sv = vvz_vol_alloc(sd, vol_idx, enckey); + if (!sv) { + /* Never free sd here, for simplicity. Potential memory leak + * if vvz_vol_alloc fails on the first volume, but it's + * really a corner case. */ + ti->error = "Could not instantiate volume"; + return -ENOMEM; + } + /* TODO Insert it into the device */ + /* TODO Register to sysfs */ + + /* Only accept one block per request for simplicity TODO: improve to one slice*/ + ti->max_io_len = VVZ_LOG_SECTOR_SCALE; + ti->num_flush_bios = 1; + ti->num_discard_bios = 0; + ti->num_secure_erase_bios = 0; + ti->num_write_zeroes_bios = 0; + ti->private = sv; + + return 0; +} + + +/* Destroy volume and, if needed, the underlying device */ +static void vvz_dtr(struct dm_target *ti) +{ + /* TODO: implement */ + return; +} + + +static int vvz_map(struct dm_target *ti, struct bio *bio) +{ + /* TODO: implement */ + return DM_MAPIO_REMAPPED; +} + + +static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) +{ + /* TODO: don't really know what to put here */ + limits->logical_block_size = VVZ_LOG_BLOCK_SIZE; + limits->physical_block_size = VVZ_LOG_BLOCK_SIZE; + limits->io_min = VVZ_LOG_BLOCK_SIZE; + limits->io_opt = VVZ_LOG_BLOCK_SIZE; + + return; +} + + +static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) +{ + /* TODO: implement */ + return 0; +} + + +static struct target_type vvz_target = { + .name = "vvz", + .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, + .module = THIS_MODULE, + .ctr = vvz_ctr, + .dtr = vvz_dtr, + .map = vvz_map, + .io_hints = vvz_io_hints, + .iterate_devices = vvz_iterate_devices, +}; + + +/* Module entry point: init variables and register DM target */ +static int __init vvz_init(void) +{ + int err; + + alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*alldevs)); + if (!alldevs) { + DMERR("vzalloc failed: could not allocate alldevs"); + err = -ENOMEM; + goto bad_alldevs_alloc; + } + + err = dm_register_target(&vvz_target); + if (err < 0) { + DMERR("Could n ot register DM target"); + goto bad_register_target; + } + + DMINFO("vvz loaded"); + return 0; + + +bad_register_target: + vfree(alldevs); +bad_alldevs_alloc: + DMERR("vvz not loaded"); + return err; +} + + +/* Module exit point: de-init variables and unregister DM target */ +static void __exit vvz_exit(void) +{ + dm_unregister_target(&vvz_target); + vfree(alldevs); + + DMINFO("vvz unloaded"); + return; +} + + +module_init(vvz_init); +module_exit(vvz_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Elia Anzuoni"); +MODULE_DESCRIPTION(DM_NAME " target for Shufflecake"); From 6fad2885bac8d3c87307eefe58a0ebc307c88820 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 22 Aug 2023 20:50:54 +0200 Subject: [PATCH 07/75] feat:Write almost all ctr and dtr --- dm-vvz/vvz.c | 53 +++++++++++++++++++++++++++++++----------- dm-vvz/vvz_constants.h | 3 +++ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 90e8459..c787eef 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -32,10 +32,13 @@ /* Global array of devices, and next free index */ static DEFINE_MUTEX(alldevs_lock); static struct vvz_device **alldevs = NULL; -static size_t free_devid = 0; +static size_t free_devid = 0; /* The lowest free devID */ -/* Create volume and, if needed, the underlying device */ +/* + * Create volume and, if not existent, the underlying device. + * Register to sysfs accordingly. + */ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) { u32 dev_id; @@ -102,16 +105,21 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } mutex_unlock(&alldevs_lock); - /* Create volume */ + /* Create volume. Never free sd here, for simplicity. Potential memory + * leak if vvz_vol_alloc or vvz_dev_add_volume fail on the first volume, + * but it's really a corner case. */ sv = vvz_vol_alloc(sd, vol_idx, enckey); if (!sv) { - /* Never free sd here, for simplicity. Potential memory leak - * if vvz_vol_alloc fails on the first volume, but it's - * really a corner case. */ ti->error = "Could not instantiate volume"; return -ENOMEM; } - /* TODO Insert it into the device */ + /* Insert it into the device */ + err = vvz_dev_add_volume(sd, sv, vol_idx); + if (err) { + ti->error = "Could not add volume to device"; + vvz_vol_free(sv); + return -EINVAL; + } /* TODO Register to sysfs */ /* Only accept one block per request for simplicity TODO: improve to one slice*/ @@ -129,7 +137,24 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* Destroy volume and, if needed, the underlying device */ static void vvz_dtr(struct dm_target *ti) { - /* TODO: implement */ + struct vvz_volume *sv = ti->private; + struct vvz_device *sd = sv->sd; + + /* TODO Remove volume from sysfs */ + vvz_dev_remove_volume(sd, sv->vol_idx); + vvz_vol_free(sv); + + /* Pointless to take vols_lock here TODO discuss its utility in general */ + if (!sd->num_vols) { + /* TODO remove device from sysfs */ + /* Release devID */ + alldevs[sd->dev_id] = NULL; + if (sd->dev_id < free_devid) + free_devid = sd->dev_id; + + vvz_dev_free(sd); + } + return; } @@ -155,13 +180,15 @@ static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { - /* TODO: implement */ - return 0; + struct vvz_volume *sv = ti->private; + + /* TODO: any reason to do something else? */ + return fn(ti, sv->sd->dev, 0, ti->len, data); } static struct target_type vvz_target = { - .name = "vvz", + .name = VVZ_TARGET_NAME, .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, .module = THIS_MODULE, .ctr = vvz_ctr, @@ -179,14 +206,14 @@ static int __init vvz_init(void) alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*alldevs)); if (!alldevs) { - DMERR("vzalloc failed: could not allocate alldevs"); + DMERR("Could not allocate alldevs"); err = -ENOMEM; goto bad_alldevs_alloc; } err = dm_register_target(&vvz_target); if (err < 0) { - DMERR("Could n ot register DM target"); + DMERR("Could not register DM target"); goto bad_register_target; } diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index e4ff1bc..de09965 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -24,6 +24,9 @@ /* This is just a placeholder for defining constants and parameters that must be the same across shufflecake components (kernel module, userland tool, etc) such as block size, slice size etc */ +#define VVZ_TARGET_NAME "vvz" + + #define VVZ_VER_MAJOR 0 #define VVZ_VER_MINOR 4 #define VVZ_VER_REVISION 0 From c142410580ec7469bd770e2fb7568068cbee039e Mon Sep 17 00:00:00 2001 From: = Date: Wed, 23 Aug 2023 22:18:12 +0200 Subject: [PATCH 08/75] feat:Write message --- dm-vvz/device.c | 11 +++++++++- dm-vvz/device.h | 9 +++++--- dm-vvz/vvz.c | 49 +++++++++++++++++++++++++++++++----------- dm-vvz/vvz_constants.h | 1 + 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 9d8a9c7..18db897 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -22,11 +22,20 @@ */ #include +#include #include #include "device.h" #include "log.h" +/* Compute device header size, in 512-byte sectors */ +#define DEV_HEADER_SIZE_SECTORS(tot_slices) \ + (VVZ_PHYS_SECTOR_SCALE * \ + (1 + VVZ_DEV_MAX_VOLUMES * \ + (1 + DIV_ROUND_UP(tot_slices, POSMAP_ENTRIES_PER_BLOCK) \ + ))) + + /* Fisher-Yates shuffle */ static void fisheryates_u32(u32 *v, u32 len); @@ -52,7 +61,7 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, sd->tot_slices = tot_slices; sd->free_slices = tot_slices; - /* TODO: compute header sizes */ + sd->dev_header_size_sectors = DEV_HEADER_SIZE_SECTORS(tot_slices); err = dm_get_device(ti, bdev_path, dm_table_get_mode(ti->table), &sd->dev); diff --git a/dm-vvz/device.h b/dm-vvz/device.h index 3c59e42..11793c4 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -34,6 +34,10 @@ #include "vvz_constants.h" +/* PosMap entries are 4 bytes, therefore there are 1024 in a block */ +#define POSMAP_ENTRIES_PER_BLOCK 1024 + + struct vvz_volume; struct vvz_device @@ -53,9 +57,8 @@ struct vvz_device u32 tot_slices; u32 free_slices; - /* Header sizes */ - u32 posmap_size; - u32 dev_header_size; + /* Header size in sectors */ + u32 dev_header_size_sectors; /* Shuffled array of PSIs */ struct mutex shuffled_psis_lock; diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index c787eef..7e95556 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -32,12 +32,12 @@ /* Global array of devices, and next free index */ static DEFINE_MUTEX(alldevs_lock); static struct vvz_device **alldevs = NULL; -static size_t free_devid = 0; /* The lowest free devID */ +static u32 free_devid = 0; /* The lowest free devID */ /* * Create volume and, if not existent, the underlying device. - * Register to sysfs accordingly. + * Register entities to sysfs accordingly. */ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) { @@ -144,7 +144,7 @@ static void vvz_dtr(struct dm_target *ti) vvz_dev_remove_volume(sd, sv->vol_idx); vvz_vol_free(sv); - /* Pointless to take vols_lock here TODO discuss its utility in general */ + /* Pointless to take vols_lock here */ if (!sd->num_vols) { /* TODO remove device from sysfs */ /* Release devID */ @@ -159,6 +159,27 @@ static void vvz_dtr(struct dm_target *ti) } +static int vvz_message(struct dm_target *ti, unsigned int argc, char **argv, + char *result, unsigned int maxlen) +{ + int i; + + if (argc != 1 || strcmp(argv[0], VVZ_TARGET_MSG_DEVID)) { + DMERR("Unrecognised message"); + return -EINVAL; + } + + if (mutex_lock_interruptible(&alldevs_lock)) + return -EINTR; + sprintf(result, "%lu", free_devid); + for (i = free_devid + 1; alldevs[i] && i < VVZ_MAX_DEVS; i++); + free_devid = i; + mutex_unlock(&alldevs_lock); + + return 0; +} + + static int vvz_map(struct dm_target *ti, struct bio *bio) { /* TODO: implement */ @@ -181,21 +202,23 @@ static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { struct vvz_volume *sv = ti->private; + struct vvz_device *sd = sv->sd; - /* TODO: any reason to do something else? */ - return fn(ti, sv->sd->dev, 0, ti->len, data); + return fn(ti, sv->sd->dev, 0, sd->dev_header_size_sectors + + (ti->len * VVZ_PHYS_SECTOR_SCALE), data); } static struct target_type vvz_target = { - .name = VVZ_TARGET_NAME, - .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, - .module = THIS_MODULE, - .ctr = vvz_ctr, - .dtr = vvz_dtr, - .map = vvz_map, - .io_hints = vvz_io_hints, - .iterate_devices = vvz_iterate_devices, + .name = VVZ_TARGET_NAME, + .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, + .module = THIS_MODULE, + .ctr = vvz_ctr, + .dtr = vvz_dtr, + .message = vvz_message, + .map = vvz_map, + .io_hints = vvz_io_hints, + .iterate_devices = vvz_iterate_devices, }; diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index de09965..8d6993f 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -25,6 +25,7 @@ #define VVZ_TARGET_NAME "vvz" +#define VVZ_TARGET_MSG_DEVID "reserve_dev_id" #define VVZ_VER_MAJOR 0 From 5723761f15791e30d44691935ea678d47b0cb79b Mon Sep 17 00:00:00 2001 From: = Date: Thu, 24 Aug 2023 15:13:43 +0200 Subject: [PATCH 09/75] feat:Shift to lite --- dm-vvz/device.c | 2 +- dm-vvz/volume.c | 14 ++++++++++++-- dm-vvz/vvz.c | 4 ++-- dm-vvz/vvz_constants.h | 7 +++---- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 18db897..04b480f 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -30,7 +30,7 @@ /* Compute device header size, in 512-byte sectors */ #define DEV_HEADER_SIZE_SECTORS(tot_slices) \ - (VVZ_PHYS_SECTOR_SCALE * \ + (VVZ_SECTOR_SCALE * \ (1 + VVZ_DEV_MAX_VOLUMES * \ (1 + DIV_ROUND_UP(tot_slices, POSMAP_ENTRIES_PER_BLOCK) \ ))) diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index a565b43..c461ec7 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -29,6 +29,7 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enckey) { struct vvz_volume *sv; + u8 xts_key[2 * VVZ_CRYPTO_KEYLEN]; int err; sv = kzalloc(sizeof(*sv), GFP_KERNEL); @@ -49,9 +50,18 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enck } sv->mapped_slices = 0; - sv->tfm = crypto_alloc_skcipher("ctr(aes)", 0, 0); + sv->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (!sv->tfm) { - DMERR("Could not allocate AES-CTR cipher handle"); + DMERR("Could not allocate AES-XTS cipher handle"); + goto bad; + } + /* HOT TAKE: 512-bit keys for AES-XTS are pointless, just duplicate the + * normal 256-bit one. See extended discussion in TODO add location */ + memcpy(xts_key, enckey, VVZ_CRYPTO_KEYLEN); + memcpy(xts_key+VVZ_CRYPTO_KEYLEN, enckey, VVZ_CRYPTO_KEYLEN); + err = crypto_skcipher_setkey(sv->tfm, xts_key, 2*VVZ_CRYPTO_KEYLEN); + if (err) { + DMERR("Could not set key in crypto transform"); goto bad; } diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 7e95556..0b6fee5 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -123,7 +123,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* TODO Register to sysfs */ /* Only accept one block per request for simplicity TODO: improve to one slice*/ - ti->max_io_len = VVZ_LOG_SECTOR_SCALE; + ti->max_io_len = VVZ_SECTOR_SCALE; ti->num_flush_bios = 1; ti->num_discard_bios = 0; ti->num_secure_erase_bios = 0; @@ -205,7 +205,7 @@ static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn struct vvz_device *sd = sv->sd; return fn(ti, sv->sd->dev, 0, sd->dev_header_size_sectors + - (ti->len * VVZ_PHYS_SECTOR_SCALE), data); + (ti->len * VVZ_SECTOR_SCALE), data); } diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 8d6993f..54230e4 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -42,10 +42,9 @@ #define VVZ_CRYPTO_KEYLEN 32 /* bytes */ -#define VVZ_LOG_BLOCK_SIZE 4096 /* bytes */ -#define VVZ_LOG_SECTOR_SCALE 8 /* sectors in logical block */ -#define VVZ_PHYS_BLOCK_SIZE 4608 /* bytes */ -#define VVZ_PHYS_SECTOR_SCALE 9 /* sectors in physical block */ +#define VVZ_BLOCK_SIZE 4096 /* bytes */ +#define VVZ_BLOCK_SHIFT 3 +#define VVZ_SECTOR_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in block */ #define VVZ_DEV_MAX_VOLUMES 15 From 1dd2835d3457700454b46e24e7299bc1e7a1b38b Mon Sep 17 00:00:00 2001 From: = Date: Fri, 25 Aug 2023 11:51:31 +0200 Subject: [PATCH 10/75] feat:Refactor and declare io.h and posmap.h --- dm-vvz/crypto.c | 17 +++++-- dm-vvz/crypto.h | 6 ++- dm-vvz/device.c | 14 +++++- dm-vvz/device.h | 6 ++- dm-vvz/io.h | 42 +++++++++++++++++ dm-vvz/posmap.h | 45 ++++++++++++++++++ dm-vvz/volume.c | 38 +++++++-------- dm-vvz/vvz.c | 102 +++++++++++++++++++---------------------- dm-vvz/vvz.h | 38 +++++++++++++++ dm-vvz/vvz_constants.h | 13 ++++-- 10 files changed, 234 insertions(+), 87 deletions(-) create mode 100644 dm-vvz/io.h create mode 100644 dm-vvz/posmap.h create mode 100644 dm-vvz/vvz.h diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index 2608074..d5df767 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -28,9 +28,14 @@ #include "log.h" +/* + * The IV is constructed as the 0-padded LE representation of the block number, + * which is exactly what dm-crypt does (IV mode "plain64") + */ int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u8 *iv, int rw) + struct page *dst_page, u64 pblk_num, int rw) { + u8 iv[VVZ_CRYPTO_IVLEN]; struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); struct scatterlist dst, src; @@ -48,11 +53,15 @@ int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, /* We assume PAGE_SIZE to equal Shufflecake's block size */ // TODO: better document this, maybe ensure it with compile-time checks sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_LOG_BLOCK_SIZE, 0); + sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); sg_init_table(&src, 1); - sg_set_page(&src, src_page, VVZ_LOG_BLOCK_SIZE, 0); + sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); - skcipher_request_set_crypt(req, &src, &dst, VVZ_LOG_BLOCK_SIZE, iv); + /* Construct IV */ + memset(iv, 0, VVZ_CRYPTO_IVLEN); + *(__le64 *)iv = cpu_to_le64(pblk_num); + + skcipher_request_set_crypt(req, &src, &dst, VVZ_BLOCK_SIZE, iv); if (rw == READ) err = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); else diff --git a/dm-vvz/crypto.h b/dm-vvz/crypto.h index 8455bdc..d97d3c0 100644 --- a/dm-vvz/crypto.h +++ b/dm-vvz/crypto.h @@ -28,8 +28,12 @@ #include +#define VVZ_CRYPTO_IVLEN 16 /* bytes */ + + +/* Use the *physical* address of the 4096-byte block within the device */ int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u8 *iv, int rw); + struct page *dst_page, u64 pblk_num, int rw); #endif /* _VVZ_CRYPTO_H_ */ diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 04b480f..9282532 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -32,7 +32,7 @@ #define DEV_HEADER_SIZE_SECTORS(tot_slices) \ (VVZ_SECTOR_SCALE * \ (1 + VVZ_DEV_MAX_VOLUMES * \ - (1 + DIV_ROUND_UP(tot_slices, POSMAP_ENTRIES_PER_BLOCK) \ + (1 + DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK) \ ))) @@ -63,6 +63,13 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, sd->free_slices = tot_slices; sd->dev_header_size_sectors = DEV_HEADER_SIZE_SECTORS(tot_slices); + /* Path to device */ + if (strlen(bdev_path) > VVZ_BDEV_PATH_LEN) { + DMERR("Device path too long"); + goto bad; + } + strcpy(sd->bdev_path, bdev_path); + /* DM handle for device */ err = dm_get_device(ti, bdev_path, dm_table_get_mode(ti->table), &sd->dev); if (err) { @@ -70,6 +77,7 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, goto bad; } + /* Shuffled PSIs */ mutex_init(&sd->shuffled_psis_lock); sd->psi_taken = vzalloc(sd->tot_slices * sizeof(bool)); if (!sd->psi_taken) { @@ -88,7 +96,7 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, sd->shuffled_psis[i] = i; fisheryates_u32(sd->shuffled_psis, tot_slices); - // TODO: complete + // TODO: init sysfs return sd; @@ -104,6 +112,8 @@ void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti) if (sd->num_vols > 0) DMCRIT("Destroying device that still has open volumes"); + /* TODO remove from sysfs */ + /* No locking needed here TODO: right? */ if (sd->shuffled_psis) vfree(sd->shuffled_psis); diff --git a/dm-vvz/device.h b/dm-vvz/device.h index 11793c4..cfb4028 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -34,8 +34,9 @@ #include "vvz_constants.h" -/* PosMap entries are 4 bytes, therefore there are 1024 in a block */ -#define POSMAP_ENTRIES_PER_BLOCK 1024 +#define VVZ_BDEV_PATH_LEN 128 +/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ +#define VVZ_POSMAP_ENTRIES_PER_BLOCK 1024 struct vvz_volume; @@ -47,6 +48,7 @@ struct vvz_device /* Underlying block device */ struct dm_dev *dev; + char bdev_path[VVZ_BDEV_PATH_LEN+1]; /* All volumes mapping to this device */ struct mutex vols_lock; diff --git a/dm-vvz/io.h b/dm-vvz/io.h new file mode 100644 index 0000000..65f8514 --- /dev/null +++ b/dm-vvz/io.h @@ -0,0 +1,42 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _VVZ_IO_H_ +#define _VVZ_IO_H_ + + +#include "device.h" +#include "volume.h" + + +/* Synchronously read/write a physical block from the device. + * Only used for the position map. */ +int vvz_rwblock_sync(struct vvz_device *sd, u64 pblk_num, struct page *page, int rw); + +/* Handlers for the logical bio's submitted to a volume */ +int vvz_read(struct vvz_volume *sv, struct bio *bio); +int vvz_write(struct vvz_volume *sv, struct bio *bio); +int vvz_flush(struct vvz_volume *sv, struct bio *bio); + + +#endif /* _VVZ_IO_H_ */ diff --git a/dm-vvz/posmap.h b/dm-vvz/posmap.h new file mode 100644 index 0000000..0933492 --- /dev/null +++ b/dm-vvz/posmap.h @@ -0,0 +1,45 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _VVZ_POSMAP_H_ +#define _VVZ_POSMAP_H_ + + +#include "volume.h" + + +#define VVZ_POSMAP_INVALID 0xFFFFFFFF + + +/* At volume creation */ +int vvz_load_entire_posmap(struct vvz_volume *sv); +/* On FLUSH request. Actually stores a whole block of 1024 entries. */ +int vvz_store_posmap_entry(struct vvz_volume *sv, u32 lsi); + +/* Returns INVALID (in *psi) if mapping does not exist */ +int vvz_get_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi); +/* Does not persist mapping on disk (only done on FLUSH requests) */ +int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi); + + +#endif /* _VVZ_POSMAP_H_ */ diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index c461ec7..3290c42 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -29,7 +29,6 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enckey) { struct vvz_volume *sv; - u8 xts_key[2 * VVZ_CRYPTO_KEYLEN]; int err; sv = kzalloc(sizeof(*sv), GFP_KERNEL); @@ -42,6 +41,19 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enck sv->vol_idx = vol_idx; sprintf(sv->vol_name, "sflc_%lu_%lu", sd->dev_id, vol_idx); + /* Crypto */ + sv->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); + if (!sv->tfm) { + DMERR("Could not allocate AES-XTS cipher handle"); + goto bad; + } + err = crypto_skcipher_setkey(sv->tfm, enckey, VVZ_XTS_KEYLEN); + if (err) { + DMERR("Could not set key in crypto transform"); + goto bad; + } + + /* Position map */ mutex_init(&sv->posmap_lock); sv->posmap = vmalloc(sd->tot_slices * sizeof(u32)); if (!sv->posmap) { @@ -49,23 +61,9 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enck goto bad; } sv->mapped_slices = 0; + // TODO load posmap (must have crypto tfm initialised) - sv->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); - if (!sv->tfm) { - DMERR("Could not allocate AES-XTS cipher handle"); - goto bad; - } - /* HOT TAKE: 512-bit keys for AES-XTS are pointless, just duplicate the - * normal 256-bit one. See extended discussion in TODO add location */ - memcpy(xts_key, enckey, VVZ_CRYPTO_KEYLEN); - memcpy(xts_key+VVZ_CRYPTO_KEYLEN, enckey, VVZ_CRYPTO_KEYLEN); - err = crypto_skcipher_setkey(sv->tfm, xts_key, 2*VVZ_CRYPTO_KEYLEN); - if (err) { - DMERR("Could not set key in crypto transform"); - goto bad; - } - - // TODO: complete + // TODO: init sysfs return sv; @@ -78,13 +76,15 @@ bad: void vvz_vol_free(struct vvz_volume *sv) { - if (sv->tfm) - crypto_free_skcipher(sv->tfm); + /* TODO remove from sysfs */ /* No locking needed here TODO: right? */ if (sv->posmap) vfree(sv->posmap); + if (sv->tfm) + crypto_free_skcipher(sv->tfm); + kfree(sv); return; diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 0b6fee5..4572941 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -26,18 +26,18 @@ #include #include "device.h" #include "vvz_constants.h" +#include "vvz.h" #include "log.h" /* Global array of devices, and next free index */ -static DEFINE_MUTEX(alldevs_lock); -static struct vvz_device **alldevs = NULL; -static u32 free_devid = 0; /* The lowest free devID */ +DEFINE_MUTEX(vvz_alldevs_lock); +struct vvz_device **vvz_alldevs = NULL; +u32 vvz_free_devid = 0; /* The lowest free devID */ /* * Create volume and, if not existent, the underlying device. - * Register entities to sysfs accordingly. */ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) { @@ -45,7 +45,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) char *bdev_path; size_t vol_idx; char *enckey_hex; - u8 enckey[VVZ_CRYPTO_KEYLEN]; + u8 enckey[VVZ_XTS_KEYLEN]; u32 tot_slices; struct vvz_device *sd; struct vvz_volume *sv; @@ -58,7 +58,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) * argv[1]: path to underlying physical device * argv[2]: volume index within the device * argv[3]: number of 1-MiB slices in the underlying device - * argv[4]: 32-byte encryption key (hex-encoded) + * argv[4]: 64-byte encryption key (hex-encoded) */ if (argc != 5) { ti->error = "Invalid argument count"; @@ -78,36 +78,47 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->error = "Invalid volume index"; return -EINVAL; } - if (strlen(enckey_hex) != 2 * VVZ_CRYPTO_KEYLEN) { + if (strlen(enckey_hex) != 2 * VVZ_XTS_KEYLEN) { ti->error = "Invalid key length"; return -EINVAL; } /* Decode the encryption key */ - err = hex2bin(enckey, enckey_hex, VVZ_CRYPTO_KEYLEN); + err = hex2bin(enckey, enckey_hex, VVZ_XTS_KEYLEN); if (err) { ti->error = "Could not decode hexadecimal encryption key"; return err; } - /* Create device if it does not yet exist */ - if (mutex_lock_interruptible(&alldevs_lock)) + /* Create device if it doesn't exist yet (or check consistency if it does) */ + if (mutex_lock_interruptible(&vvz_alldevs_lock)) return -EINTR; - sd = alldevs[dev_id]; + sd = vvz_alldevs[dev_id]; if (!sd) { + /* Create */ sd = vvz_dev_alloc(ti, bdev_path, dev_id, tot_slices); if (!sd) { ti->error = "Could not instantiate device"; - mutex_unlock(&alldevs_lock); + mutex_unlock(&vvz_alldevs_lock); return -ENOMEM; } - // TODO: register to sysfs - alldevs[dev_id] = sd; + /* Insert in alldevs, and advance free_devid */ + vvz_alldevs[dev_id] = sd; + int i; + for (i = dev_id + 1; vvz_alldevs[i] && i < VVZ_MAX_DEVS; i++); + vvz_free_devid = i; + } else { + /* Check for uniqueness */ + if (strncmp(sd->bdev_path, bdev_path, VVZ_BDEV_PATH_LEN) != 0) { + ti->error = "Device ID already used for another device"; + mutex_unlock(&vvz_alldevs_lock); + return -EINVAL; + } } - mutex_unlock(&alldevs_lock); + mutex_unlock(&vvz_alldevs_lock); /* Create volume. Never free sd here, for simplicity. Potential memory * leak if vvz_vol_alloc or vvz_dev_add_volume fail on the first volume, - * but it's really a corner case. */ + * but it's really a corner case. TODO discuss */ sv = vvz_vol_alloc(sd, vol_idx, enckey); if (!sv) { ti->error = "Could not instantiate volume"; @@ -118,9 +129,8 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (err) { ti->error = "Could not add volume to device"; vvz_vol_free(sv); - return -EINVAL; + return err; } - /* TODO Register to sysfs */ /* Only accept one block per request for simplicity TODO: improve to one slice*/ ti->max_io_len = VVZ_SECTOR_SCALE; @@ -139,47 +149,28 @@ static void vvz_dtr(struct dm_target *ti) { struct vvz_volume *sv = ti->private; struct vvz_device *sd = sv->sd; + u32 dev_id = sd->dev_id; - /* TODO Remove volume from sysfs */ vvz_dev_remove_volume(sd, sv->vol_idx); vvz_vol_free(sv); /* Pointless to take vols_lock here */ if (!sd->num_vols) { - /* TODO remove device from sysfs */ - /* Release devID */ - alldevs[sd->dev_id] = NULL; - if (sd->dev_id < free_devid) - free_devid = sd->dev_id; - vvz_dev_free(sd); + + /* Release devID */ + if (mutex_lock_interruptible(&vvz_alldevs_lock)) + return; + vvz_alldevs[dev_id] = NULL; + if (dev_id < vvz_free_devid) + vvz_free_devid = dev_id; + mutex_unlock(&vvz_alldevs_lock); } return; } -static int vvz_message(struct dm_target *ti, unsigned int argc, char **argv, - char *result, unsigned int maxlen) -{ - int i; - - if (argc != 1 || strcmp(argv[0], VVZ_TARGET_MSG_DEVID)) { - DMERR("Unrecognised message"); - return -EINVAL; - } - - if (mutex_lock_interruptible(&alldevs_lock)) - return -EINTR; - sprintf(result, "%lu", free_devid); - for (i = free_devid + 1; alldevs[i] && i < VVZ_MAX_DEVS; i++); - free_devid = i; - mutex_unlock(&alldevs_lock); - - return 0; -} - - static int vvz_map(struct dm_target *ti, struct bio *bio) { /* TODO: implement */ @@ -190,10 +181,10 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) { /* TODO: don't really know what to put here */ - limits->logical_block_size = VVZ_LOG_BLOCK_SIZE; - limits->physical_block_size = VVZ_LOG_BLOCK_SIZE; - limits->io_min = VVZ_LOG_BLOCK_SIZE; - limits->io_opt = VVZ_LOG_BLOCK_SIZE; + limits->logical_block_size = VVZ_BLOCK_SIZE; + limits->physical_block_size = VVZ_BLOCK_SIZE; + limits->io_min = VVZ_BLOCK_SIZE; + limits->io_opt = VVZ_BLOCK_SIZE; return; } @@ -215,7 +206,6 @@ static struct target_type vvz_target = { .module = THIS_MODULE, .ctr = vvz_ctr, .dtr = vvz_dtr, - .message = vvz_message, .map = vvz_map, .io_hints = vvz_io_hints, .iterate_devices = vvz_iterate_devices, @@ -227,9 +217,9 @@ static int __init vvz_init(void) { int err; - alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*alldevs)); - if (!alldevs) { - DMERR("Could not allocate alldevs"); + vvz_alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*vvz_alldevs)); + if (!vvz_alldevs) { + DMERR("Could not allocate vvz_alldevs"); err = -ENOMEM; goto bad_alldevs_alloc; } @@ -245,7 +235,7 @@ static int __init vvz_init(void) bad_register_target: - vfree(alldevs); + vfree(vvz_alldevs); bad_alldevs_alloc: DMERR("vvz not loaded"); return err; @@ -256,7 +246,7 @@ bad_alldevs_alloc: static void __exit vvz_exit(void) { dm_unregister_target(&vvz_target); - vfree(alldevs); + vfree(vvz_alldevs); DMINFO("vvz unloaded"); return; diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h new file mode 100644 index 0000000..5f4e39f --- /dev/null +++ b/dm-vvz/vvz.h @@ -0,0 +1,38 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _VVZ_H +#define _VVZ_H + + +#include +#include "device.h" + + +/* Global array of devices, and next free index */ +extern struct mutex vvz_alldevs_lock; +extern struct vvz_device **vvz_alldevs; +extern u32 vvz_free_devid; /* The lowest free devID */ + + +#endif /* _VVZ_H */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 54230e4..474f545 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -21,11 +21,15 @@ * If not, see . */ -/* This is just a placeholder for defining constants and parameters that must be the same across shufflecake components (kernel module, userland tool, etc) such as block size, slice size etc */ +/* This is just a placeholder for defining constants and parameters that must + * be the same across Shufflecake components (kernel module, userland tool) + * such as block size, slice size etc */ + +#ifndef _VVZ_CONSTANTS_H_ +#define _VVZ_CONSTANTS_H_ #define VVZ_TARGET_NAME "vvz" -#define VVZ_TARGET_MSG_DEVID "reserve_dev_id" #define VVZ_VER_MAJOR 0 @@ -39,7 +43,8 @@ #define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL -#define VVZ_CRYPTO_KEYLEN 32 /* bytes */ +/* XTS "requires" (per the standard, at least) doubling the key size */ +#define VVZ_XTS_KEYLEN 64 /* bytes */ #define VVZ_BLOCK_SIZE 4096 /* bytes */ @@ -50,3 +55,5 @@ #define VVZ_DEV_MAX_VOLUMES 15 #define VVZ_MAX_DEVS 1024 + +#endif /* _VVZ_CONSTANTS_H_ */ From 6c76af0a3e04d7218583c07074a9ff0d7ddf5c8b Mon Sep 17 00:00:00 2001 From: = Date: Fri, 25 Aug 2023 11:56:46 +0200 Subject: [PATCH 11/75] feat:Define posmap's dirty bit --- dm-vvz/volume.c | 7 +++++++ dm-vvz/volume.h | 1 + 2 files changed, 8 insertions(+) diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 3290c42..e7c0de1 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -60,6 +60,11 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enck DMERR("Could not allocate position map"); goto bad; } + sv->pme_unsynced = vmalloc(sd->tot_slices * sizeof(u8)); + if (!sv->pme_unsynced) { + DMERR("Could not allocate dirty bitfield for position map"); + goto bad; + } sv->mapped_slices = 0; // TODO load posmap (must have crypto tfm initialised) @@ -79,6 +84,8 @@ void vvz_vol_free(struct vvz_volume *sv) /* TODO remove from sysfs */ /* No locking needed here TODO: right? */ + if (sv->pme_unsynced) + vfree(sv->pme_unsynced); if (sv->posmap) vfree(sv->posmap); diff --git a/dm-vvz/volume.h b/dm-vvz/volume.h index 3d3dbeb..67015fb 100644 --- a/dm-vvz/volume.h +++ b/dm-vvz/volume.h @@ -54,6 +54,7 @@ struct vvz_volume /* Position map */ struct mutex posmap_lock; u32 *posmap; + bool *pme_unsynced; /* Dirty bit */ u32 mapped_slices; /* Crypto */ From 18f032aaa7b1de5e9d1ed8bd8001e23b665af72b Mon Sep 17 00:00:00 2001 From: = Date: Fri, 25 Aug 2023 17:18:39 +0200 Subject: [PATCH 12/75] feat:Write first posmap functions --- dm-vvz/crypto.h | 2 +- dm-vvz/device.c | 2 +- dm-vvz/device.h | 16 +++---- dm-vvz/io.h | 2 +- dm-vvz/posmap.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ dm-vvz/volume.h | 9 ++-- dm-vvz/vvz.h | 1 - 7 files changed, 128 insertions(+), 18 deletions(-) create mode 100644 dm-vvz/posmap.c diff --git a/dm-vvz/crypto.h b/dm-vvz/crypto.h index d97d3c0..4d07521 100644 --- a/dm-vvz/crypto.h +++ b/dm-vvz/crypto.h @@ -31,7 +31,7 @@ #define VVZ_CRYPTO_IVLEN 16 /* bytes */ -/* Use the *physical* address of the 4096-byte block within the device */ +/* Use the *physical* address of the 4096-byte block, within the device, as IV */ int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, struct page *dst_page, u64 pblk_num, int rw); diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 9282532..6b6f493 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -89,7 +89,7 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, DMERR("Could not allocate shuffled PSI array"); goto bad; } - sd->first_free_psi = 0; + sd->first_free_psi_idx = 0; /* Generate a permutation */ for (i = 0; i < tot_slices; i++) diff --git a/dm-vvz/device.h b/dm-vvz/device.h index cfb4028..1adcd1a 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -49,29 +49,27 @@ struct vvz_device /* Underlying block device */ struct dm_dev *dev; char bdev_path[VVZ_BDEV_PATH_LEN+1]; + u32 tot_slices; + + /* Header size in 512-byte sectors */ + u32 dev_header_size_sectors; /* All volumes mapping to this device */ struct mutex vols_lock; struct vvz_volume *vols[VVZ_DEV_MAX_VOLUMES]; size_t num_vols; - /* Slices stats */ - u32 tot_slices; - u32 free_slices; - - /* Header size in sectors */ - u32 dev_header_size_sectors; - /* Shuffled array of PSIs */ struct mutex shuffled_psis_lock; u32 *shuffled_psis; - u32 first_free_psi; /* in the shuffled array */ + u32 first_free_psi_idx; /* in the shuffled array */ bool *psi_taken; + u32 free_slices; }; struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, - u32 dev_id, u32 tot_slices); + u32 dev_id, u32 tot_slices); void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti); int vvz_dev_add_volume(struct vvz_device *sd, struct vvz_volume *sv, size_t vol_idx); diff --git a/dm-vvz/io.h b/dm-vvz/io.h index 65f8514..ddc6e4e 100644 --- a/dm-vvz/io.h +++ b/dm-vvz/io.h @@ -29,7 +29,7 @@ #include "volume.h" -/* Synchronously read/write a physical block from the device. +/* Synchronously read/write a physical block from/to the device. * Only used for the position map. */ int vvz_rwblock_sync(struct vvz_device *sd, u64 pblk_num, struct page *page, int rw); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c new file mode 100644 index 0000000..2511883 --- /dev/null +++ b/dm-vvz/posmap.c @@ -0,0 +1,114 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "posmap.h" + + +/* Get the next free PSI in the device's shuffled array, and mark it taken */ +static int take_free_psi(struct vvz_device *sd, u32 *psi); + + +/* Returns INVALID (in *psi) if mapping does not exist */ +int vvz_get_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) +{ + /* Sanity check (redundant?) */ + if(unlikely(lsi >= sv->sd->tot_slices)) + return -EINVAL; + + if (mutex_lock_interruptible(&sv->posmap_lock)) + return -EINTR; + *psi = sv->posmap[lsi]; + mutex_unlock(&sv->posmap_lock); + + return 0; +} + + +/* Does not persist mapping on disk (only done on FLUSH requests) */ +int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) +{ + int err; + + /* Sanity check (redundant?) */ + if(unlikely(lsi >= sv->sd->tot_slices)) + return -EINVAL; + + if (mutex_lock_interruptible(&sv->posmap_lock)) + return -EINTR; + + /* Check mapping not existent */ + if (unlikely(sv->posmap[lsi] != VVZ_POSMAP_INVALID)){ + err = -EINVAL; + goto out; + } + + /* Create it in the device */ + err = take_free_psi(sv->sd, psi); + if (err) + goto out; + /* And in the volume */ + sv->posmap[lsi] = *psi; + sv->mapped_slices += 1; + sv->pme_unsynced[lsi] = true; + + err = 0; + +out: + mutex_unlock(&sv->posmap_lock); + return err; +} + + +/* Get the next free PSI in the device's shuffled array, and mark it taken. + * This specific algorithm, that never wraps first_free_psi_idx around, + * only works because slices are never freed up. */ +static int take_free_psi(struct vvz_device *sd, u32 *psi) +{ + int err; + + if (mutex_lock_interruptible(&sd->shuffled_psis_lock)) + return -EINTR; + + /* PSI to return */ + if (unlikely(!sd->free_slices)) { + err = -ENOSPC; + goto out; + } + *psi = sd->shuffled_psis[sd->first_free_psi_idx]; + if (unlikely(sd->psi_taken[*psi])) { + err = -EINVAL; // TODO make it more tragic + goto out; + } + + /* Update device state */ + int i; + for (i = sd->first_free_psi_idx + 1; + i < sd->tot_slices && sd->psi_taken[i]; i++); + sd->first_free_psi_idx = i; + sd->free_slices -= 1; + sd->psi_taken[*psi] = true; + +out: + mutex_unlock(&sd->shuffled_psis_lock); + return err; +} diff --git a/dm-vvz/volume.h b/dm-vvz/volume.h index 67015fb..f5ff498 100644 --- a/dm-vvz/volume.h +++ b/dm-vvz/volume.h @@ -22,8 +22,8 @@ */ /* - * A volume represents a single "virtual" block device, mapping onto a - * "physical" device represented by a device. + * A volume represents a single "logical" storage unit, mapping onto an + * underlying "physical" device. */ #ifndef _VVZ_VOLUME_H_ @@ -42,12 +42,11 @@ struct vvz_device; struct vvz_volume { - /* Volume index within the device */ - size_t vol_idx; - /* Backing device */ struct vvz_device *sd; + /* Volume index within the device */ + size_t vol_idx; /* Name of the volume, sflc__*/ char vol_name[VVZ_VOL_NAME_MAX_LEN + 1]; diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 5f4e39f..0de1e69 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -25,7 +25,6 @@ #define _VVZ_H -#include #include "device.h" From 7d10c2aad554ba4be4835dec11ff6fc6456e328e Mon Sep 17 00:00:00 2001 From: = Date: Tue, 29 Aug 2023 12:52:09 +0200 Subject: [PATCH 13/75] feat:Minor nits --- dm-vvz/crypto.c | 2 +- dm-vvz/io.h | 4 ---- dm-vvz/posmap.c | 2 +- dm-vvz/vvz.c | 23 +++++++++++++++++++---- dm-vvz/vvz_constants.h | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index d5df767..040adde 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -42,7 +42,7 @@ int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, int err; /* TODO: not too sure about the gfp_mask here */ - req = skcipher_request_alloc(tfm, GFP_NOWAIT); + req = skcipher_request_alloc(tfm, GFP_NOIO); if (!req) return -ENOMEM; diff --git a/dm-vvz/io.h b/dm-vvz/io.h index ddc6e4e..8e4e110 100644 --- a/dm-vvz/io.h +++ b/dm-vvz/io.h @@ -29,10 +29,6 @@ #include "volume.h" -/* Synchronously read/write a physical block from/to the device. - * Only used for the position map. */ -int vvz_rwblock_sync(struct vvz_device *sd, u64 pblk_num, struct page *page, int rw); - /* Handlers for the logical bio's submitted to a volume */ int vvz_read(struct vvz_volume *sv, struct bio *bio); int vvz_write(struct vvz_volume *sv, struct bio *bio); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 2511883..cacb039 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -56,7 +56,7 @@ int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) if (mutex_lock_interruptible(&sv->posmap_lock)) return -EINTR; - /* Check mapping not existent */ + /* Check mapping not existent (redundant?) */ if (unlikely(sv->posmap[lsi] != VVZ_POSMAP_INVALID)){ err = -EINVAL; goto out; diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 4572941..a734528 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -25,6 +25,8 @@ #include #include #include "device.h" +#include "volume.h" +#include "io.h" #include "vvz_constants.h" #include "vvz.h" #include "log.h" @@ -89,7 +91,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) return err; } - /* Create device if it doesn't exist yet (or check consistency if it does) */ + /* Create device if it doesn't exist yet (or check uniqueness if it does) */ if (mutex_lock_interruptible(&vvz_alldevs_lock)) return -EINTR; sd = vvz_alldevs[dev_id]; @@ -133,7 +135,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* Only accept one block per request for simplicity TODO: improve to one slice*/ - ti->max_io_len = VVZ_SECTOR_SCALE; + ti->max_io_len = VVZ_BLOCK_SCALE; ti->num_flush_bios = 1; ti->num_discard_bios = 0; ti->num_secure_erase_bios = 0; @@ -173,7 +175,20 @@ static void vvz_dtr(struct dm_target *ti) static int vvz_map(struct dm_target *ti, struct bio *bio) { - /* TODO: implement */ + struct vvz_volume *sv = ti->private; + + /* Bio type checks (redundant?) */ + if (unlikely(bio_op(bio) != REQ_OP_READ && + bio_op(bio) != REQ_OP_WRITE)) + return DM_MAPIO_KILL; /* TODO log it? */ + /* Bio size and bvec alignment checks (redundant?) */ + if (unlikely(bio->bi_iter.bi_size && + (bio->bi_iter.bi_size != VVZ_BLOCK_SIZE || + bio->bi_vcnt != 1))) + return DM_MAPIO_KILL; /* TODO log it? */ + + // TODO dispatch + return DM_MAPIO_REMAPPED; } @@ -196,7 +211,7 @@ static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn struct vvz_device *sd = sv->sd; return fn(ti, sv->sd->dev, 0, sd->dev_header_size_sectors + - (ti->len * VVZ_SECTOR_SCALE), data); + (ti->len * VVZ_BLOCK_SCALE), data); } diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 474f545..a8bcfda 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -49,7 +49,7 @@ #define VVZ_BLOCK_SIZE 4096 /* bytes */ #define VVZ_BLOCK_SHIFT 3 -#define VVZ_SECTOR_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in block */ +#define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in block */ #define VVZ_DEV_MAX_VOLUMES 15 From 7129b4017454ca10753aa641df61cb9d42889be2 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Aug 2023 15:44:50 +0200 Subject: [PATCH 14/75] feat:Make posmap load/store sync and non-granular --- dm-vvz/device.c | 10 +++++++++- dm-vvz/device.h | 3 +++ dm-vvz/io.h | 6 +++--- dm-vvz/map_flush.c | 37 +++++++++++++++++++++++++++++++++++++ dm-vvz/posmap.c | 2 +- dm-vvz/posmap.h | 6 +++--- dm-vvz/volume.c | 8 +------- dm-vvz/volume.h | 2 +- dm-vvz/vvz.c | 22 ++++++++++++++++------ 9 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 dm-vvz/map_flush.c diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 6b6f493..18dc167 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -28,9 +28,11 @@ #include "log.h" +/* Depth of the mempool backing the bio_set */ +#define VVZ_BIOSET_BIOS 64 /* Compute device header size, in 512-byte sectors */ #define DEV_HEADER_SIZE_SECTORS(tot_slices) \ - (VVZ_SECTOR_SCALE * \ + (VVZ_BLOCK_SCALE * \ (1 + VVZ_DEV_MAX_VOLUMES * \ (1 + DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK) \ ))) @@ -96,6 +98,9 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, sd->shuffled_psis[i] = i; fisheryates_u32(sd->shuffled_psis, tot_slices); + /* Bioset */ + bioset_init(&sd->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + // TODO: init sysfs return sd; @@ -114,6 +119,9 @@ void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti) /* TODO remove from sysfs */ + /* Safe to call on zeroed bio_set */ + bioset_exit(&sd->bs); + /* No locking needed here TODO: right? */ if (sd->shuffled_psis) vfree(sd->shuffled_psis); diff --git a/dm-vvz/device.h b/dm-vvz/device.h index 1adcd1a..1d1fa3f 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -65,6 +65,9 @@ struct vvz_device u32 first_free_psi_idx; /* in the shuffled array */ bool *psi_taken; u32 free_slices; + + /* TODO should this be per-device? */ + struct bio_set bs; }; diff --git a/dm-vvz/io.h b/dm-vvz/io.h index 8e4e110..3b8e87a 100644 --- a/dm-vvz/io.h +++ b/dm-vvz/io.h @@ -30,9 +30,9 @@ /* Handlers for the logical bio's submitted to a volume */ -int vvz_read(struct vvz_volume *sv, struct bio *bio); -int vvz_write(struct vvz_volume *sv, struct bio *bio); -int vvz_flush(struct vvz_volume *sv, struct bio *bio); +int vvz_map_read(struct vvz_volume *sv, struct bio *bio); +int vvz_map_write(struct vvz_volume *sv, struct bio *bio); +int vvz_map_flush(struct vvz_volume *sv, struct bio *bio); #endif /* _VVZ_IO_H_ */ diff --git a/dm-vvz/map_flush.c b/dm-vvz/map_flush.c new file mode 100644 index 0000000..6182d18 --- /dev/null +++ b/dm-vvz/map_flush.c @@ -0,0 +1,37 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/** + * We treat logical FLUSH requests as follows. + * + */ + +#include "io.h" +#include "posmap.h" +#include "log.h" + + +int vvz_map_flush(struct vvz_volume *sv, struct bio *bio) +{ + +} diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index cacb039..b3931ec 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -69,7 +69,7 @@ int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) /* And in the volume */ sv->posmap[lsi] = *psi; sv->mapped_slices += 1; - sv->pme_unsynced[lsi] = true; + sv->posmap_dirty = true; err = 0; diff --git a/dm-vvz/posmap.h b/dm-vvz/posmap.h index 0933492..451b99c 100644 --- a/dm-vvz/posmap.h +++ b/dm-vvz/posmap.h @@ -32,9 +32,9 @@ /* At volume creation */ -int vvz_load_entire_posmap(struct vvz_volume *sv); -/* On FLUSH request. Actually stores a whole block of 1024 entries. */ -int vvz_store_posmap_entry(struct vvz_volume *sv, u32 lsi); +int vvz_load_posmap(struct vvz_volume *sv); +/* On FLUSH request */ +int vvz_store_posmap(struct vvz_volume *sv); /* Returns INVALID (in *psi) if mapping does not exist */ int vvz_get_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi); diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index e7c0de1..fdb4d74 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -60,11 +60,7 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enck DMERR("Could not allocate position map"); goto bad; } - sv->pme_unsynced = vmalloc(sd->tot_slices * sizeof(u8)); - if (!sv->pme_unsynced) { - DMERR("Could not allocate dirty bitfield for position map"); - goto bad; - } + sv->posmap_dirty = false; sv->mapped_slices = 0; // TODO load posmap (must have crypto tfm initialised) @@ -84,8 +80,6 @@ void vvz_vol_free(struct vvz_volume *sv) /* TODO remove from sysfs */ /* No locking needed here TODO: right? */ - if (sv->pme_unsynced) - vfree(sv->pme_unsynced); if (sv->posmap) vfree(sv->posmap); diff --git a/dm-vvz/volume.h b/dm-vvz/volume.h index f5ff498..582f363 100644 --- a/dm-vvz/volume.h +++ b/dm-vvz/volume.h @@ -53,7 +53,7 @@ struct vvz_volume /* Position map */ struct mutex posmap_lock; u32 *posmap; - bool *pme_unsynced; /* Dirty bit */ + bool posmap_dirty; u32 mapped_slices; /* Crypto */ diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index a734528..cd3da30 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -136,10 +136,13 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* Only accept one block per request for simplicity TODO: improve to one slice*/ ti->max_io_len = VVZ_BLOCK_SCALE; + ti->flush_supported = true; ti->num_flush_bios = 1; + ti->discards_supported = false; ti->num_discard_bios = 0; ti->num_secure_erase_bios = 0; ti->num_write_zeroes_bios = 0; + ti->accounts_remapped_io = true; ti->private = sv; return 0; @@ -176,20 +179,27 @@ static void vvz_dtr(struct dm_target *ti) static int vvz_map(struct dm_target *ti, struct bio *bio) { struct vvz_volume *sv = ti->private; + enum req_op op = bio_op(bio); - /* Bio type checks (redundant?) */ - if (unlikely(bio_op(bio) != REQ_OP_READ && - bio_op(bio) != REQ_OP_WRITE)) - return DM_MAPIO_KILL; /* TODO log it? */ /* Bio size and bvec alignment checks (redundant?) */ if (unlikely(bio->bi_iter.bi_size && (bio->bi_iter.bi_size != VVZ_BLOCK_SIZE || bio->bi_vcnt != 1))) return DM_MAPIO_KILL; /* TODO log it? */ - // TODO dispatch + /* Dispatch */ + if (bio->bi_opf & REQ_PREFLUSH) { + /* DM core should only send empty flush requests */ + if (unlikely(bio->bi_iter.bi_size)) + return DM_MAPIO_KILL; // TODO log it? + return vvz_map_flush(sv, bio); + } else if (op == REQ_OP_READ) + return vvz_map_read(sv, bio); + else if (op == REQ_OP_WRITE) + return vvz_map_write(sv, bio); - return DM_MAPIO_REMAPPED; + DMWARN("Unrecognised bio: bio_op(bio) = %d", op); + return DM_MAPIO_KILL; } From 3ca7fe54e6c81693f1b495a6603b8e782b233b66 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Aug 2023 15:49:31 +0200 Subject: [PATCH 15/75] feat:Add dm-io client --- dm-vvz/device.c | 10 ++++++++++ dm-vvz/device.h | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 18dc167..a707167 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -100,6 +100,13 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, /* Bioset */ bioset_init(&sd->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + /* Client for dm-io */ + sd->io_client = dm_io_client_create(); + if (IS_ERR(sd->io_client)) { + DMERR("Could not create dm-io client"); + sd->io_client = NULL; + goto bad; + } // TODO: init sysfs @@ -119,6 +126,9 @@ void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti) /* TODO remove from sysfs */ + /* Needs to be zeroed out in the ctor, on failure */ + if (sd->io_client) + dm_io_client_destroy(sd->io_client); /* Safe to call on zeroed bio_set */ bioset_exit(&sd->bs); diff --git a/dm-vvz/device.h b/dm-vvz/device.h index 1d1fa3f..7f03745 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -31,6 +31,7 @@ #include +#include #include "vvz_constants.h" @@ -66,8 +67,9 @@ struct vvz_device bool *psi_taken; u32 free_slices; - /* TODO should this be per-device? */ + /* TODO should these be per-device? */ struct bio_set bs; + struct dm_io_client *io_client; }; From aeb1d7145883ce93f3268aa063aa3163ffe15d62 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Aug 2023 16:31:03 +0200 Subject: [PATCH 16/75] feat:Add crypt_page and crypt_buf --- dm-vvz/crypto.c | 48 +++++++++++++++++++++++++++++++++++++----------- dm-vvz/crypto.h | 11 +++++++++-- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index 040adde..052db00 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -28,17 +28,50 @@ #include "log.h" +static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, + struct scatterlist *dst, u64 pblk_num, int rw); + + +/* Encrypt-decrypt a whole memory page */ +int vvz_crypt_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw) +{ + struct scatterlist dst, src; + + sg_init_table(&src, 1); + sg_set_page(&src, src_page, PAGE_SIZE, 0); + sg_init_table(&dst, 1); + sg_set_page(&dst, dst_page, PAGE_SIZE, 0); + + return crypt_sg(tfm, &src, &dst, pblk_num, rw); +} + + +/* Encrypt-decrypt a (possibly vmalloc'ed) buffer */ +int vvz_crypt_buf(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, + size_t buflen, u64 pblk_num, int rw) +{ + struct scatterlist dst, src; + + sg_init_table(&src, 1); + sg_set_buf(&src, src_buf, buflen); + sg_init_table(&dst, 1); + sg_set_buf(&dst, dst_buf, buflen); + + return crypt_sg(tfm, &src, &dst, pblk_num, rw); +} + + /* * The IV is constructed as the 0-padded LE representation of the block number, * which is exactly what dm-crypt does (IV mode "plain64") */ -int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw) +static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, + struct scatterlist *dst, u64 pblk_num, int rw) { u8 iv[VVZ_CRYPTO_IVLEN]; struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); - struct scatterlist dst, src; int err; /* TODO: not too sure about the gfp_mask here */ @@ -50,18 +83,11 @@ int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, &wait); - /* We assume PAGE_SIZE to equal Shufflecake's block size */ - // TODO: better document this, maybe ensure it with compile-time checks - sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); - sg_init_table(&src, 1); - sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); - /* Construct IV */ memset(iv, 0, VVZ_CRYPTO_IVLEN); *(__le64 *)iv = cpu_to_le64(pblk_num); - skcipher_request_set_crypt(req, &src, &dst, VVZ_BLOCK_SIZE, iv); + skcipher_request_set_crypt(req, src, dst, VVZ_BLOCK_SIZE, iv); if (rw == READ) err = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); else diff --git a/dm-vvz/crypto.h b/dm-vvz/crypto.h index 4d07521..68ace42 100644 --- a/dm-vvz/crypto.h +++ b/dm-vvz/crypto.h @@ -21,6 +21,9 @@ * If not, see . */ +/* For AES-XTS-256, we use the *physical* address of the 4096-byte block, + * within the device, as IV (little-endian, zero-padded). */ + #ifndef _VVZ_CRYPTO_H_ #define _VVZ_CRYPTO_H_ @@ -31,9 +34,13 @@ #define VVZ_CRYPTO_IVLEN 16 /* bytes */ -/* Use the *physical* address of the 4096-byte block, within the device, as IV */ -int vvz_crypt_block(struct crypto_skcipher *tfm, struct page *src_page, +/* Encrypt-decrypt a whole memory page */ +int vvz_crypt_page(struct crypto_skcipher *tfm, struct page *src_page, struct page *dst_page, u64 pblk_num, int rw); +/* Encrypt-decrypt a (possibly vmalloc'ed) buffer */ +int vvz_crypt_buf(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, + size_t buflen, u64 pblk_num, int rw); + #endif /* _VVZ_CRYPTO_H_ */ From b0de8b9caed2763bfd1256381b51e4ebd92e3ab0 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Aug 2023 17:42:39 +0200 Subject: [PATCH 17/75] feat:Add to posmpa.c --- dm-vvz/device.c | 9 +++++++- dm-vvz/device.h | 6 ++++-- dm-vvz/{io.h => map_bio.h} | 0 dm-vvz/map_flush.c | 2 +- dm-vvz/posmap.c | 44 ++++++++++++++++++++++++++++++++++++++ dm-vvz/vvz.c | 2 +- 6 files changed, 58 insertions(+), 5 deletions(-) rename dm-vvz/{io.h => map_bio.h} (100%) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index a707167..5c6c61b 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -63,7 +63,14 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, sd->tot_slices = tot_slices; sd->free_slices = tot_slices; - sd->dev_header_size_sectors = DEV_HEADER_SIZE_SECTORS(tot_slices); + /* Enough blocks to fit all the entries */ + sd->posmap_size_sectors = VVZ_BLOCK_SCALE * + DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK); + /* PosMap + VMB */ + sd->vol_header_size_sectors = VVZ_BLOCK_SCALE + sd->posmap_size_sectors; + /* Volume headers + DMB */ + sd->dev_header_size_sectors = VVZ_BLOCK_SCALE + + VVZ_DEV_MAX_VOLUMES * sd->vol_header_size_sectors; /* Path to device */ if (strlen(bdev_path) > VVZ_BDEV_PATH_LEN) { diff --git a/dm-vvz/device.h b/dm-vvz/device.h index 7f03745..fc5b046 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -52,8 +52,10 @@ struct vvz_device char bdev_path[VVZ_BDEV_PATH_LEN+1]; u32 tot_slices; - /* Header size in 512-byte sectors */ - u32 dev_header_size_sectors; + /* Header sizes in 512-byte sectors */ + sector_t posmap_size_sectors; + sector_t vol_header_size_sectors; + sector_t dev_header_size_sectors; /* All volumes mapping to this device */ struct mutex vols_lock; diff --git a/dm-vvz/io.h b/dm-vvz/map_bio.h similarity index 100% rename from dm-vvz/io.h rename to dm-vvz/map_bio.h diff --git a/dm-vvz/map_flush.c b/dm-vvz/map_flush.c index 6182d18..fc7337f 100644 --- a/dm-vvz/map_flush.c +++ b/dm-vvz/map_flush.c @@ -26,7 +26,7 @@ * */ -#include "io.h" +#include "map_bio.h" #include "posmap.h" #include "log.h" diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index b3931ec..e345af0 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -24,6 +24,11 @@ #include "posmap.h" +/******************************************************************************* + * In-memory operations on the position map + ******************************************************************************/ + + /* Get the next free PSI in the device's shuffled array, and mark it taken */ static int take_free_psi(struct vvz_device *sd, u32 *psi); @@ -112,3 +117,42 @@ out: mutex_unlock(&sd->shuffled_psis_lock); return err; } + + +/******************************************************************************* + * On-disk operations on the position map + ******************************************************************************/ + + +/* Synchronously read/write the entire on-disk encrypted position map */ +static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw); + + +/* Read position map from disk and decrypt in place */ +int vvz_load_posmap(struct vvz_volume *sv); + + +/* Encrypt position map out of place, onto a buffer, and write it on disk */ +int vvz_store_posmap(struct vvz_volume *sv); + + +/* Synchronously read/write the entire on-disk encrypted position map */ +static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw) +{ + struct dm_io_request io_req = { + .bi_opf = (rw == READ) ? REQ_OP_READ : REQ_OP_WRITE, + .mem.type = DM_IO_VMA, + .mem.ptr.vma = buf, + .notify.fn = NULL, + .client = sv->sd->io_client + }; + struct dm_io_region io_region = { + .bdev = sv->sd->dev->bdev, + .sector = 1 + VVZ_DEV_MAX_VOLUMES + + (sv->vol_idx * sv->sd->posmap_size_sectors), + .count = sv->sd->posmap_size_sectors + }; + + return dm_io(&io_req, 1, &io_region, NULL); +} + diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index cd3da30..19301ac 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -26,7 +26,7 @@ #include #include "device.h" #include "volume.h" -#include "io.h" +#include "map_bio.h" #include "vvz_constants.h" #include "vvz.h" #include "log.h" From c78d71c756f73221ca23828a7396f3996c0fa08a Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Aug 2023 19:05:24 +0200 Subject: [PATCH 18/75] fix:Crypto --- dm-vvz/crypto.c | 37 +++++++++++++++++++++++++------------ dm-vvz/crypto.h | 10 +++++----- dm-vvz/device.c | 8 +++----- dm-vvz/device.h | 1 - dm-vvz/posmap.c | 5 ++++- dm-vvz/volume.c | 3 ++- 6 files changed, 39 insertions(+), 25 deletions(-) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index 052db00..0107b10 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -32,33 +32,46 @@ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, struct scatterlist *dst, u64 pblk_num, int rw); -/* Encrypt-decrypt a whole memory page */ -int vvz_crypt_page(struct crypto_skcipher *tfm, struct page *src_page, +/* Encrypt-decrypt a single block (memory buffer is a page) */ +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, struct page *dst_page, u64 pblk_num, int rw) { struct scatterlist dst, src; + /* We assume PAGE_SIZE == VVZ_BLOCK_SIZE TODO better document this */ sg_init_table(&src, 1); - sg_set_page(&src, src_page, PAGE_SIZE, 0); + sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, PAGE_SIZE, 0); + sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); return crypt_sg(tfm, &src, &dst, pblk_num, rw); } -/* Encrypt-decrypt a (possibly vmalloc'ed) buffer */ -int vvz_crypt_buf(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, - size_t buflen, u64 pblk_num, int rw) +/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ +int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, + size_t num_blocks, u64 first_pblk_num, int rw) { struct scatterlist dst, src; + size_t block; + u64 pblk_num; + int err; - sg_init_table(&src, 1); - sg_set_buf(&src, src_buf, buflen); - sg_init_table(&dst, 1); - sg_set_buf(&dst, dst_buf, buflen); + pblk_num = first_pblk_num; + for (block = 0; block < num_blocks; block++) { + sg_init_one(&src, src_buf, VVZ_BLOCK_SIZE); + sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); - return crypt_sg(tfm, &src, &dst, pblk_num, rw); + err = crypt_sg(tfm, &src, &dst, pblk_num, rw); + if (err) + return err; + + src_buf += VVZ_BLOCK_SIZE; + dst_buf += VVZ_BLOCK_SIZE; + pblk_num += 1; + } + + return 0; } diff --git a/dm-vvz/crypto.h b/dm-vvz/crypto.h index 68ace42..c3a83c3 100644 --- a/dm-vvz/crypto.h +++ b/dm-vvz/crypto.h @@ -34,13 +34,13 @@ #define VVZ_CRYPTO_IVLEN 16 /* bytes */ -/* Encrypt-decrypt a whole memory page */ -int vvz_crypt_page(struct crypto_skcipher *tfm, struct page *src_page, +/* Encrypt-decrypt a single block (memory buffer is a page) */ +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, struct page *dst_page, u64 pblk_num, int rw); -/* Encrypt-decrypt a (possibly vmalloc'ed) buffer */ -int vvz_crypt_buf(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, - size_t buflen, u64 pblk_num, int rw); +/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ +int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, + size_t num_blocks, u64 first_pblk_num, int rw); #endif /* _VVZ_CRYPTO_H_ */ diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 5c6c61b..b9aec7d 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -66,11 +66,9 @@ struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, /* Enough blocks to fit all the entries */ sd->posmap_size_sectors = VVZ_BLOCK_SCALE * DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK); - /* PosMap + VMB */ - sd->vol_header_size_sectors = VVZ_BLOCK_SCALE + sd->posmap_size_sectors; - /* Volume headers + DMB */ - sd->dev_header_size_sectors = VVZ_BLOCK_SCALE + - VVZ_DEV_MAX_VOLUMES * sd->vol_header_size_sectors; + /* VMBs + PosMaps + DMB */ + sd->dev_header_size_sectors = VVZ_BLOCK_SCALE + VVZ_DEV_MAX_VOLUMES * + (VVZ_BLOCK_SCALE + sd->posmap_size_sectors); /* Path to device */ if (strlen(bdev_path) > VVZ_BDEV_PATH_LEN) { diff --git a/dm-vvz/device.h b/dm-vvz/device.h index fc5b046..62231fd 100644 --- a/dm-vvz/device.h +++ b/dm-vvz/device.h @@ -54,7 +54,6 @@ struct vvz_device /* Header sizes in 512-byte sectors */ sector_t posmap_size_sectors; - sector_t vol_header_size_sectors; sector_t dev_header_size_sectors; /* All volumes mapping to this device */ diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index e345af0..2d62150 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -129,7 +129,10 @@ static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw); /* Read position map from disk and decrypt in place */ -int vvz_load_posmap(struct vvz_volume *sv); +int vvz_load_posmap(struct vvz_volume *sv) +{ + +} /* Encrypt position map out of place, onto a buffer, and write it on disk */ diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index fdb4d74..27a56b2 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -55,7 +55,8 @@ struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enck /* Position map */ mutex_init(&sv->posmap_lock); - sv->posmap = vmalloc(sd->tot_slices * sizeof(u32)); + /* Slight over-allocation, to fit a whole number of blocks */ + sv->posmap = vmalloc(sd->posmap_size_sectors * SECTOR_SIZE); if (!sv->posmap) { DMERR("Could not allocate position map"); goto bad; From d34df4f3888ee956a5690d2ae6aecc0e598631a3 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Aug 2023 19:18:02 +0200 Subject: [PATCH 19/75] feat:Write load_posmap --- dm-vvz/posmap.c | 19 +++++++++++++++++-- dm-vvz/posmap.h | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 2d62150..2244588 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -22,6 +22,7 @@ */ #include "posmap.h" +#include "crypto.h" /******************************************************************************* @@ -131,7 +132,22 @@ static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw); /* Read position map from disk and decrypt in place */ int vvz_load_posmap(struct vvz_volume *sv) { + int err; + /* No locking needed (we are in the constructor) */ + err = rw_posmap(sv, sv->posmap, READ); + if (err) + return err; + + /* Decrypt in place */ + err = vvz_crypt_blocks_vm(sv->tfm, sv->posmap, sv->posmap, + sv->sd->posmap_size_sectors >> VVZ_BLOCK_SHIFT, + VVZ_POSMAP_START_SECTOR(sv) >> VVZ_BLOCK_SHIFT, + READ); + if (err) + return err; + + return 0; } @@ -151,8 +167,7 @@ static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw) }; struct dm_io_region io_region = { .bdev = sv->sd->dev->bdev, - .sector = 1 + VVZ_DEV_MAX_VOLUMES + - (sv->vol_idx * sv->sd->posmap_size_sectors), + .sector = VVZ_POSMAP_START_SECTOR(sv), .count = sv->sd->posmap_size_sectors }; diff --git a/dm-vvz/posmap.h b/dm-vvz/posmap.h index 451b99c..df6c3a3 100644 --- a/dm-vvz/posmap.h +++ b/dm-vvz/posmap.h @@ -29,6 +29,10 @@ #define VVZ_POSMAP_INVALID 0xFFFFFFFF +/* Starting sector of position map */ +#define VVZ_POSMAP_START_SECTOR(sv) \ + (VVZ_BLOCK_SCALE * (1 + VVZ_DEV_MAX_VOLUMES) + \ + (sv)->vol_idx * (sv)->sd->posmap_size_sectors) /* At volume creation */ From 00037ee89eb629581dc62bf88fd239c59e536cdc Mon Sep 17 00:00:00 2001 From: = Date: Sat, 4 Nov 2023 11:04:09 +0100 Subject: [PATCH 20/75] feat:Implement storePosmap --- dm-vvz/map_flush.c | 6 ++++-- dm-vvz/posmap.c | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/dm-vvz/map_flush.c b/dm-vvz/map_flush.c index fc7337f..f4dd419 100644 --- a/dm-vvz/map_flush.c +++ b/dm-vvz/map_flush.c @@ -22,8 +22,10 @@ */ /** - * We treat logical FLUSH requests as follows. - * + * We process FLUSH requests synchronously, for simplicity. + * First we store the position map, if it has been updated since the last FLUSH, + * and we wait for the operation to finish. Then, we forward the FLUSH to the + * underlying device. */ #include "map_bio.h" diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 2244588..0eae38e 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -152,7 +152,26 @@ int vvz_load_posmap(struct vvz_volume *sv) /* Encrypt position map out of place, onto a buffer, and write it on disk */ -int vvz_store_posmap(struct vvz_volume *sv); +int vvz_store_posmap(struct vvz_volume *sv) +{ + u8 *enc_posmap; + int err; + + /* Allocate it every time TODO evaluate alternatives */ + enc_posmap = vmalloc(sv->sd->posmap_size_sectors * SECTOR_SIZE); + if (!enc_posmap) + return -ENOMEM; + + if (mutex_lock_interruptible&sv->posmap_lock) { + err = -EINTR; + goto out_vfree; + } + + +out_vfree: + vfree(enc_posmap); + return err; +} /* Synchronously read/write the entire on-disk encrypted position map */ From 898834850cc7708c38e6b060b2d405924f8ca6d9 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 2 Jan 2024 18:21:01 +0100 Subject: [PATCH 21/75] Add notes --- dm-vvz/SCHOLIA.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 dm-vvz/SCHOLIA.md diff --git a/dm-vvz/SCHOLIA.md b/dm-vvz/SCHOLIA.md new file mode 100644 index 0000000..e15e14a --- /dev/null +++ b/dm-vvz/SCHOLIA.md @@ -0,0 +1,10 @@ +Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, dm-crypt uses a bound io_queue for bio mapping; it also has a crypt_queue for encryption/decryption, that is WQ_CPU_INTENSIVE: that wq is either bound or unbound, based on the flag DM_CRYPT_SAME_CPU. Both these workqueues are WQ_MEM_RECLAIM, and we probably need that for Shufflecake too. +As for granularity, almost no DM target uses the kernel-global wq (with schedule_work()); many allocate a per-target wq, while some use a module-wide wq. This latter choice is probably the easiest, so it's a good first attempt; we might hit the concurrency limit (set by max_active) in the future, so that's one thing to look out for. +All in all, we can use a single module-wide bound wq, that is WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, and whose work items process bio's start-to-finish. + +Let's talk about flush requests. Main references are the comments in [this source file](https://elixir.bootlin.com/linux/v6.6.9/source/block/blk-flush.c), as well as [these docs](https://www.kernel.org/doc/Documentation/block/writeback_cache_control.txt). The point seems to be that we are unlikely to see REQ_OP_FLUSH bio's incoming: rather, we'll receive an empty bio with REQ_OP_WRITE | REQ_PREFLUSH. Indeed, that's what dm-crypt checks for (there's also a comment that reads "for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight", although I couldn't confirm that myself). REQ_FUA might be set on some bio's, and we should pass it down. +Now, how to handle them? In this first implementation, we have nothing to flush, so we just pass them down. This is because there is no volatile cache: the in-memory view of the position map is write-through. This is unlikely to change in the future, so it's relatively safe to say we'll always be able to just passthrough the flush requests. + +About the posmap view being write-through, there is something to add. This first implementation is very crude: when we create a new slice mapping, we hold onto the posmap_lock until the new mapping is persisted on-disk. This approach unnecessarily blocks all new bio's, even unrelated ones (i.e. falling in a different slice); also, the new bio's falling in that same slice could at least start processing, and only wait for the slice mapping to be persisted once they are done, before returning. +There is a fix to both these problems, but it results in the locking scheme for the position map to be a bit more convoluted, so it's better to resist the urge of premature optimisation. We would also reserve the MSB of the posmap entry (which is a u32) to signal that the entry "is being written to disk": this limits the range of usable PSIs to 0x00000000 to 0x7FFFFFFE (with 0x7FFFFFFF and 0xFFFFFFFF being the "unmapped LSI" symbol), so we can have at most 2^31-1 PSIs. +The optimised posmap would work as follows. The function create_slice_mapping() takes the posmap_lock, then samples a new PSIs, then writes it in the posmap **with the MSB set**, then releases the posmap_lock (so other bio's can use the posmap), then writes the updated posmap block on the disk. If a new incoming bio falls in the same LSI, it can still proceed even if the MSB of the entry is set ("speculating" that the update of the posmap block will succeed) and use the slice mapping normally to launch the mapped bio; then, just before returning, it waits for the MSB to clear using a waitqueue (as explained in [LDD](https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch05s02.html)). The waitqueue is declared in the volume struct alongside the posmap, and is woken up by create_slice_mapping() once the update of the posmap block finishes successfully, after clearing the MSB. From fa0b61f821357abc7b3edde154341a01f4479814 Mon Sep 17 00:00:00 2001 From: toninov Date: Tue, 2 Jan 2024 17:25:38 +0000 Subject: [PATCH 22/75] Update dm-vvz/SCHOLIA.md --- dm-vvz/SCHOLIA.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dm-vvz/SCHOLIA.md b/dm-vvz/SCHOLIA.md index e15e14a..bb305ec 100644 --- a/dm-vvz/SCHOLIA.md +++ b/dm-vvz/SCHOLIA.md @@ -1,10 +1,10 @@ -Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, dm-crypt uses a bound io_queue for bio mapping; it also has a crypt_queue for encryption/decryption, that is WQ_CPU_INTENSIVE: that wq is either bound or unbound, based on the flag DM_CRYPT_SAME_CPU. Both these workqueues are WQ_MEM_RECLAIM, and we probably need that for Shufflecake too. -As for granularity, almost no DM target uses the kernel-global wq (with schedule_work()); many allocate a per-target wq, while some use a module-wide wq. This latter choice is probably the easiest, so it's a good first attempt; we might hit the concurrency limit (set by max_active) in the future, so that's one thing to look out for. -All in all, we can use a single module-wide bound wq, that is WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, and whose work items process bio's start-to-finish. +Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, `dm-crypt` uses a bound `io_queue` for bio mapping; it also has a `crypt_queue` for encryption/decryption, that is `WQ_CPU_INTENSIVE`: that wq is either bound or unbound, based on the flag `DM_CRYPT_SAME_CPU`. Both these workqueues are `WQ_MEM_RECLAIM`, and we probably need that for Shufflecake too. +As for granularity, almost no DM target uses the kernel-global wq (with `schedule_work()`); many allocate a per-target wq, while some use a module-wide wq. This latter choice is probably the easiest, so it's a good first attempt; we might hit the concurrency limit (set by `max_active`) in the future, so that's one thing to look out for. +All in all, we can use a single module-wide bound wq, that is `WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE`, and whose work items process bio's start-to-finish. -Let's talk about flush requests. Main references are the comments in [this source file](https://elixir.bootlin.com/linux/v6.6.9/source/block/blk-flush.c), as well as [these docs](https://www.kernel.org/doc/Documentation/block/writeback_cache_control.txt). The point seems to be that we are unlikely to see REQ_OP_FLUSH bio's incoming: rather, we'll receive an empty bio with REQ_OP_WRITE | REQ_PREFLUSH. Indeed, that's what dm-crypt checks for (there's also a comment that reads "for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight", although I couldn't confirm that myself). REQ_FUA might be set on some bio's, and we should pass it down. +Let's talk about flush requests. Main references are the comments in [this source file](https://elixir.bootlin.com/linux/v6.6.9/source/block/blk-flush.c), as well as [these docs](https://www.kernel.org/doc/Documentation/block/writeback_cache_control.txt). The point seems to be that we are unlikely to see `REQ_OP_FLUSH` bio's incoming: rather, we'll receive an empty bio with `REQ_OP_WRITE | REQ_PREFLUSH`. Indeed, that's what `dm-crypt` checks for (there's also a comment that reads "for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight", although I couldn't confirm that myself). `REQ_FUA` might be set on some bio's, and we should pass it down. Now, how to handle them? In this first implementation, we have nothing to flush, so we just pass them down. This is because there is no volatile cache: the in-memory view of the position map is write-through. This is unlikely to change in the future, so it's relatively safe to say we'll always be able to just passthrough the flush requests. -About the posmap view being write-through, there is something to add. This first implementation is very crude: when we create a new slice mapping, we hold onto the posmap_lock until the new mapping is persisted on-disk. This approach unnecessarily blocks all new bio's, even unrelated ones (i.e. falling in a different slice); also, the new bio's falling in that same slice could at least start processing, and only wait for the slice mapping to be persisted once they are done, before returning. -There is a fix to both these problems, but it results in the locking scheme for the position map to be a bit more convoluted, so it's better to resist the urge of premature optimisation. We would also reserve the MSB of the posmap entry (which is a u32) to signal that the entry "is being written to disk": this limits the range of usable PSIs to 0x00000000 to 0x7FFFFFFE (with 0x7FFFFFFF and 0xFFFFFFFF being the "unmapped LSI" symbol), so we can have at most 2^31-1 PSIs. -The optimised posmap would work as follows. The function create_slice_mapping() takes the posmap_lock, then samples a new PSIs, then writes it in the posmap **with the MSB set**, then releases the posmap_lock (so other bio's can use the posmap), then writes the updated posmap block on the disk. If a new incoming bio falls in the same LSI, it can still proceed even if the MSB of the entry is set ("speculating" that the update of the posmap block will succeed) and use the slice mapping normally to launch the mapped bio; then, just before returning, it waits for the MSB to clear using a waitqueue (as explained in [LDD](https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch05s02.html)). The waitqueue is declared in the volume struct alongside the posmap, and is woken up by create_slice_mapping() once the update of the posmap block finishes successfully, after clearing the MSB. +About the posmap view being write-through, there is something to add. This first implementation is very crude: when we create a new slice mapping, we hold onto the `posmap_lock` until the new mapping is persisted on-disk. This approach unnecessarily blocks all new bio's, even unrelated ones (i.e. falling in a different slice); also, the new bio's falling in that same slice could at least start processing, and only wait for the slice mapping to be persisted once they are done, before returning. +There is a fix to both these problems, but it results in the locking scheme for the position map to be a bit more convoluted, so it's better to resist the urge of premature optimisation. We would also reserve the MSB of the posmap entry (which is a `u32`) to signal that the entry "is being written to disk": this limits the range of usable PSIs to 0x00000000 to 0x7FFFFFFE (with 0x7FFFFFFF and 0xFFFFFFFF being the "unmapped LSI" symbol), so we can have at most 2^31-1 PSIs. +The optimised posmap would work as follows. The function `create_slice_mapping()` takes the `posmap_lock`, then samples a new PSIs, then writes it in the posmap **with the MSB set**, then releases the `posmap_lock` (so other bio's can use the posmap), then writes the updated posmap block on the disk. If a new incoming bio falls in the same LSI, it can still proceed even if the MSB of the entry is set ("speculating" that the update of the posmap block will succeed) and use the slice mapping normally to launch the mapped bio; then, just before returning, it waits for the MSB to clear using a waitqueue (as explained in [LDD](https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch05s02.html)). The waitqueue is declared in the volume struct alongside the posmap, and is woken up by `create_slice_mapping()` once the update of the posmap block finishes successfully, after clearing the MSB. From ac84ffade8d7a5bcb2c283cf314fd7fa03ebcc78 Mon Sep 17 00:00:00 2001 From: toninov Date: Tue, 2 Jan 2024 22:16:58 +0000 Subject: [PATCH 23/75] Update dm-vvz/SCHOLIA.md --- dm-vvz/SCHOLIA.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dm-vvz/SCHOLIA.md b/dm-vvz/SCHOLIA.md index bb305ec..f32f15d 100644 --- a/dm-vvz/SCHOLIA.md +++ b/dm-vvz/SCHOLIA.md @@ -1,10 +1,18 @@ -Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, `dm-crypt` uses a bound `io_queue` for bio mapping; it also has a `crypt_queue` for encryption/decryption, that is `WQ_CPU_INTENSIVE`: that wq is either bound or unbound, based on the flag `DM_CRYPT_SAME_CPU`. Both these workqueues are `WQ_MEM_RECLAIM`, and we probably need that for Shufflecake too. -As for granularity, almost no DM target uses the kernel-global wq (with `schedule_work()`); many allocate a per-target wq, while some use a module-wide wq. This latter choice is probably the easiest, so it's a good first attempt; we might hit the concurrency limit (set by `max_active`) in the future, so that's one thing to look out for. +#### Workqueues +Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, `dm-crypt` uses a bound `io_queue` for bio mapping; it also has a `crypt_queue` for encryption/decryption, that is `WQ_CPU_INTENSIVE`: that wq is either bound or unbound, based on the flag `DM_CRYPT_SAME_CPU`. Both these workqueues are `WQ_MEM_RECLAIM`, and we probably need that for Shufflecake too. +As for granularity, almost no DM target uses the kernel-global wq (with `schedule_work()`); many allocate a per-target wq, while some use a module-wide wq. This latter choice is probably the easiest, so it's a good first attempt; we might hit the concurrency limit (set by `max_active`) in the future, so that's one thing to look out for. All in all, we can use a single module-wide bound wq, that is `WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE`, and whose work items process bio's start-to-finish. -Let's talk about flush requests. Main references are the comments in [this source file](https://elixir.bootlin.com/linux/v6.6.9/source/block/blk-flush.c), as well as [these docs](https://www.kernel.org/doc/Documentation/block/writeback_cache_control.txt). The point seems to be that we are unlikely to see `REQ_OP_FLUSH` bio's incoming: rather, we'll receive an empty bio with `REQ_OP_WRITE | REQ_PREFLUSH`. Indeed, that's what `dm-crypt` checks for (there's also a comment that reads "for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight", although I couldn't confirm that myself). `REQ_FUA` might be set on some bio's, and we should pass it down. -Now, how to handle them? In this first implementation, we have nothing to flush, so we just pass them down. This is because there is no volatile cache: the in-memory view of the position map is write-through. This is unlikely to change in the future, so it's relatively safe to say we'll always be able to just passthrough the flush requests. +#### Position map: write-back or write-through? +A first idea was to have slice allocation happen exclusively in memory, and only synchronise the position map to disk upon FLUSH requests (write-back posmap), but this gives the scheme a weird and inconsistent *crash behaviour*. +Suppose, for example, that the upper-layer FS keeps an `index` block with a list of all allocated data blocks; suppose that a new data block is written at a position falling in a yet-unmapped slice (triggering slice allocation); the `index` block is consequently updated so that the list also contains a pointer to the new data block; suppose that, by Satan's inscrutable will, the update of the `index` block gets persisted to disk but the system crashes right afterwards, before the on-disk position map is updated; when the system boots back up, the FS will legitimately believe that the data block is allocated (because that's what the `index` block says) and contains all zeros (because READ requests to blocks in unmapped slices return all-zeros, for good reasons). This is bad. +On the other hand, one might possibly argue that the upper layer employed an unsafe sequence of operations, and should have only updated the `index` after a FLUSH request. After all, the all-zeros was just the previous (logical) content of the data block, before it was written by the FS, so it's just as if our driver reordered the two WRITE requests and failed in the middle, which is perfectly legit. Right now, I can't think of a more compelling argument against a write-back position map, but the fact that a WRITE request can complete, only for the affected block to then become "unreachable" (i.e. contain all-zeros) again, is fishy. +Anyway, to avoid headaches, we'll probably go for a write-through position map at first, at least until we discuss this more accurately with someone. Also, this simplifies handling of FLUSH requests: we have nothing to flush, so we just pass them down. This is because there is no volatile cache, since the in-memory view of the position map is write-through. -About the posmap view being write-through, there is something to add. This first implementation is very crude: when we create a new slice mapping, we hold onto the `posmap_lock` until the new mapping is persisted on-disk. This approach unnecessarily blocks all new bio's, even unrelated ones (i.e. falling in a different slice); also, the new bio's falling in that same slice could at least start processing, and only wait for the slice mapping to be persisted once they are done, before returning. -There is a fix to both these problems, but it results in the locking scheme for the position map to be a bit more convoluted, so it's better to resist the urge of premature optimisation. We would also reserve the MSB of the posmap entry (which is a `u32`) to signal that the entry "is being written to disk": this limits the range of usable PSIs to 0x00000000 to 0x7FFFFFFE (with 0x7FFFFFFF and 0xFFFFFFFF being the "unmapped LSI" symbol), so we can have at most 2^31-1 PSIs. +#### FLUSH requests and where to find them +How do we even know if a bio is a FLUSH? Main references are the comments in [this source file](https://elixir.bootlin.com/linux/v6.6.9/source/block/blk-flush.c), as well as [these docs](https://www.kernel.org/doc/Documentation/block/writeback_cache_control.txt). The point seems to be that we are unlikely to see `REQ_OP_FLUSH` bio's incoming: rather, we'll receive an empty bio with `REQ_OP_WRITE | REQ_PREFLUSH`. Indeed, that's what `dm-crypt` checks for; there's also a comment there that reads `for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight` although I couldn't confirm that myself. `REQ_FUA` might be set on some bio's, and we should pass it down; I've read somewhere that the device-mapper core will strip it and just send an emtpy FLUSH afterwards, but I haven't found many confirmations of that. + +#### Locking of write-through posmap +About the posmap view being write-through, there is something to add. This first implementation is very crude: when we create a new slice mapping, we hold onto the `posmap_lock` for dear life until the new mapping is persisted on-disk. This approach unnecessarily blocks all new bio's, even unrelated ones (i.e. falling in a different slice); also, the new bio's falling in that same slice could at least start processing, and only wait for the slice mapping to be persisted once they are done, before returning. +There is a fix to both these problems, but it results in the locking scheme for the position map to be a bit more convoluted, so it's better to resist the urge of premature optimisation. We would also reserve the MSB of the posmap entry (which is a `u32`) to signal that the entry "is being written to disk": this limits the range of usable PSIs to `0x00000000` to `0x7FFFFFFE` (with `0x7FFFFFFF` and `0xFFFFFFFF` being the "unmapped LSI" symbol), so we can have at most 2^31-1 PSIs. The optimised posmap would work as follows. The function `create_slice_mapping()` takes the `posmap_lock`, then samples a new PSIs, then writes it in the posmap **with the MSB set**, then releases the `posmap_lock` (so other bio's can use the posmap), then writes the updated posmap block on the disk. If a new incoming bio falls in the same LSI, it can still proceed even if the MSB of the entry is set ("speculating" that the update of the posmap block will succeed) and use the slice mapping normally to launch the mapped bio; then, just before returning, it waits for the MSB to clear using a waitqueue (as explained in [LDD](https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch05s02.html)). The waitqueue is declared in the volume struct alongside the posmap, and is woken up by `create_slice_mapping()` once the update of the posmap block finishes successfully, after clearing the MSB. From e8f162cbab6519defa185e381a7b1fbb22703a1f Mon Sep 17 00:00:00 2001 From: = Date: Sun, 7 Jan 2024 18:14:11 +0100 Subject: [PATCH 24/75] Use a single .h --- dm-vvz/device.c | 171 +++++++++++++++++++---------------------- dm-vvz/device.h | 85 -------------------- dm-vvz/log.h | 31 -------- dm-vvz/map_bio.h | 38 --------- dm-vvz/map_flush.c | 39 ---------- dm-vvz/posmap.c | 4 +- dm-vvz/volume.c | 54 ++++++------- dm-vvz/volume.h | 68 ---------------- dm-vvz/vvz.c | 153 +++++++++++++++++++++++------------- dm-vvz/vvz.h | 106 ++++++++++++++++++++++++- dm-vvz/vvz_constants.h | 6 +- 11 files changed, 312 insertions(+), 443 deletions(-) delete mode 100644 dm-vvz/device.h delete mode 100644 dm-vvz/log.h delete mode 100644 dm-vvz/map_bio.h delete mode 100644 dm-vvz/map_flush.c delete mode 100644 dm-vvz/volume.h diff --git a/dm-vvz/device.c b/dm-vvz/device.c index b9aec7d..b3c3e4c 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -24,8 +24,7 @@ #include #include #include -#include "device.h" -#include "log.h" +#include "vvz.h" /* Depth of the mempool backing the bio_set */ @@ -39,170 +38,154 @@ /* Fisher-Yates shuffle */ -static void fisheryates_u32(u32 *v, u32 len); - - -struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, - u32 dev_id, u32 tot_slices) +static void fisheryates_u32(u32 *v, u32 len) { - struct vvz_device *sd; + u32 i, j, tmp; + + for (i = len-1; i >= 1; i--) { + j = get_random_u32_below(i+1); + + /* Swap v[i] and v[j] */ + tmp = v[i]; + v[i] = v[j]; + v[j] = tmp; + } + + return; +} + +struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) +{ + struct vvz_device *sdev; int err; int i; - sd = kzalloc(sizeof(*sd), GFP_KERNEL); - if (!sd) { + sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + if (!sdev) { DMERR("Could not allocate device"); - return NULL; + return ERR_PTR(-ENOMEM); } - sd->dev_id = dev_id; + sdev->dev_id = dev_id; - mutex_init(&sd->vols_lock); + mutex_init(&sdev->volumes_lock); for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) - sd->vols[i] = NULL; - sd->num_vols = 0; + sdev->volumes[i] = NULL; + sdev->num_volumes = 0; - sd->tot_slices = tot_slices; - sd->free_slices = tot_slices; - /* Enough blocks to fit all the entries */ - sd->posmap_size_sectors = VVZ_BLOCK_SCALE * + /* Compute sizes */ + sdev->tot_slices = tot_slices; + sdev->free_slices = tot_slices; + /* Enough posmap blocks to fit all the entries */ + sdev->posmap_size_sectors = VVZ_BLOCK_SCALE * DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK); - /* VMBs + PosMaps + DMB */ - sd->dev_header_size_sectors = VVZ_BLOCK_SCALE + VVZ_DEV_MAX_VOLUMES * - (VVZ_BLOCK_SCALE + sd->posmap_size_sectors); + /* DMB + VMBs + PosMaps */ + sdev->dev_header_size_sectors = VVZ_BLOCK_SCALE + + (VVZ_DEV_MAX_VOLUMES * VVZ_BLOCK_SCALE) + + (VVZ_DEV_MAX_VOLUMES * sdev->posmap_size_sectors); - /* Path to device */ - if (strlen(bdev_path) > VVZ_BDEV_PATH_LEN) { - DMERR("Device path too long"); - goto bad; - } - strcpy(sd->bdev_path, bdev_path); - /* DM handle for device */ - err = dm_get_device(ti, bdev_path, - dm_table_get_mode(ti->table), &sd->dev); - if (err) { - DMERR("Could not get DM device"); - goto bad; - } + /* The calling ->ctr() will set sdev->dm_dev */ /* Shuffled PSIs */ - mutex_init(&sd->shuffled_psis_lock); - sd->psi_taken = vzalloc(sd->tot_slices * sizeof(bool)); - if (!sd->psi_taken) { + mutex_init(&sdev->slices_lock); + sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); + if (!sdev->slices_ofld) { DMERR("Could not allocate PSI occupation bitfield"); + err = -ENOMEM; goto bad; } - sd->shuffled_psis = vmalloc(tot_slices * sizeof(u32)); - if (!sd->shuffled_psis) { + sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); + if (!sdev->prmslices) { DMERR("Could not allocate shuffled PSI array"); + err = -ENOMEM; goto bad; } - sd->first_free_psi_idx = 0; - + sdev->prmslices_octr = 0; /* Generate a permutation */ for (i = 0; i < tot_slices; i++) - sd->shuffled_psis[i] = i; - fisheryates_u32(sd->shuffled_psis, tot_slices); + sdev->prmslices[i] = i; + fisheryates_u32(sdev->prmslices, tot_slices); /* Bioset */ - bioset_init(&sd->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + bioset_init(&sdev->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + /* Client for dm-io */ - sd->io_client = dm_io_client_create(); - if (IS_ERR(sd->io_client)) { + sdev->io_client = dm_io_client_create(); + if (IS_ERR(sdev->io_client)) { DMERR("Could not create dm-io client"); - sd->io_client = NULL; + err = PTR_ERR(sdev->io_client); + sdev->io_client = NULL; goto bad; } // TODO: init sysfs - return sd; + return sdev; bad: - vvz_dev_free(sd, ti); - return NULL; + vvz_dev_destroy(sdev); + return ERR_PTR(err); } -void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti) +void vvz_dev_destroy(struct vvz_device *sdev) { - if (sd->num_vols > 0) + if (sdev->num_volumes > 0) DMCRIT("Destroying device that still has open volumes"); /* TODO remove from sysfs */ /* Needs to be zeroed out in the ctor, on failure */ - if (sd->io_client) - dm_io_client_destroy(sd->io_client); + if (sdev->io_client) + dm_io_client_destroy(sdev->io_client); /* Safe to call on zeroed bio_set */ - bioset_exit(&sd->bs); + bioset_exit(&sdev->bs); /* No locking needed here TODO: right? */ - if (sd->shuffled_psis) - vfree(sd->shuffled_psis); - if (sd->psi_taken) - vfree(sd->psi_taken); + if (sdev->prmslices) + vfree(sdev->prmslices); + if (sdev->slices_ofld) + vfree(sdev->slices_ofld); - if (sd->dev) - dm_put_device(ti, sd->dev); - - kfree(sd); + kfree(sdev); return; } -int vvz_dev_add_volume(struct vvz_device *sd, struct vvz_volume *sv, size_t vol_idx) +int vvz_dev_add_volume(struct vvz_device *sdev, struct vvz_volume *svol, size_t vol_idx) { int ret; - if (mutex_lock_interruptible(&sd->vols_lock)) + if (mutex_lock_interruptible(&sdev->volumes_lock)) return -EINTR; - if (sd->vols[vol_idx]) { + if (sdev->volumes[vol_idx]) { DMERR("Volume slot %lu already taken", vol_idx); ret = -EINVAL; } else { - sd->vols[vol_idx] = sv; - sd->num_vols += 1; + sdev->volumes[vol_idx] = svol; + sdev->num_volumes += 1; ret = 0; } - mutex_unlock(&sd->vols_lock); + mutex_unlock(&sdev->volumes_lock); return ret; } -void vvz_dev_remove_volume(struct vvz_device *sd, size_t vol_idx) +void vvz_dev_remove_volume(struct vvz_device *sdev, size_t vol_idx) { - if (mutex_lock_interruptible(&sd->vols_lock)) + if (mutex_lock_interruptible(&sdev->volumes_lock)) return; - if (sd->vols[vol_idx]) { - sd->vols[vol_idx] = NULL; - sd->num_vols -= 1; + if (sdev->volumes[vol_idx]) { + sdev->volumes[vol_idx] = NULL; + sdev->num_volumes -= 1; } else DMERR("Volume slot %lu already free", vol_idx); - mutex_unlock(&sd->vols_lock); - return; -} - - -/* Fisher-Yates shuffle */ -static void fisheryates_u32(u32 *v, u32 len) -{ - u32 i; - - for (i = len-1; i >= 1; i--) { - u32 j = get_random_u32_below(i+1); - - /* Swap v[i] and v[j] */ - v[i] ^= v[j]; // v[i] <- a XOR b - v[j] ^= v[i]; // v[j] <- b XOR (a XOR b) = a - v[i] ^= v[j]; // v[i] <- (a XOR b) XOR a = b - } - + mutex_unlock(&sdev->volumes_lock); return; } diff --git a/dm-vvz/device.h b/dm-vvz/device.h deleted file mode 100644 index 62231fd..0000000 --- a/dm-vvz/device.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * A device represents the underlying "physical" block device, common to all - * "virtual" volumes that map onto it. - */ - -#ifndef _VVZ_DEVICE_H_ -#define _VVZ_DEVICE_H_ - - -#include -#include -#include "vvz_constants.h" - - -#define VVZ_BDEV_PATH_LEN 128 -/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ -#define VVZ_POSMAP_ENTRIES_PER_BLOCK 1024 - - -struct vvz_volume; - -struct vvz_device -{ - /* Shufflecake-unique device ID */ - u32 dev_id; - - /* Underlying block device */ - struct dm_dev *dev; - char bdev_path[VVZ_BDEV_PATH_LEN+1]; - u32 tot_slices; - - /* Header sizes in 512-byte sectors */ - sector_t posmap_size_sectors; - sector_t dev_header_size_sectors; - - /* All volumes mapping to this device */ - struct mutex vols_lock; - struct vvz_volume *vols[VVZ_DEV_MAX_VOLUMES]; - size_t num_vols; - - /* Shuffled array of PSIs */ - struct mutex shuffled_psis_lock; - u32 *shuffled_psis; - u32 first_free_psi_idx; /* in the shuffled array */ - bool *psi_taken; - u32 free_slices; - - /* TODO should these be per-device? */ - struct bio_set bs; - struct dm_io_client *io_client; -}; - - -struct vvz_device *vvz_dev_alloc(struct dm_target *ti, char *bdev_path, - u32 dev_id, u32 tot_slices); -void vvz_dev_free(struct vvz_device *sd, struct dm_target *ti); - -int vvz_dev_add_volume(struct vvz_device *sd, struct vvz_volume *sv, size_t vol_idx); -void vvz_dev_remove_volume(struct vvz_device *sd, size_t vol_idx); - - -#endif /* _VVZ_DEVICE_H_ */ diff --git a/dm-vvz/log.h b/dm-vvz/log.h deleted file mode 100644 index 2ad7ea9..0000000 --- a/dm-vvz/log.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _VVZ_LOG_H_ -#define _VVZ_LOG_H_ - - -#define DM_MSG_PREFIX "vvz" - - -#endif /* _VVZ_LOG_H_ */ diff --git a/dm-vvz/map_bio.h b/dm-vvz/map_bio.h deleted file mode 100644 index 3b8e87a..0000000 --- a/dm-vvz/map_bio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _VVZ_IO_H_ -#define _VVZ_IO_H_ - - -#include "device.h" -#include "volume.h" - - -/* Handlers for the logical bio's submitted to a volume */ -int vvz_map_read(struct vvz_volume *sv, struct bio *bio); -int vvz_map_write(struct vvz_volume *sv, struct bio *bio); -int vvz_map_flush(struct vvz_volume *sv, struct bio *bio); - - -#endif /* _VVZ_IO_H_ */ diff --git a/dm-vvz/map_flush.c b/dm-vvz/map_flush.c deleted file mode 100644 index f4dd419..0000000 --- a/dm-vvz/map_flush.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/** - * We process FLUSH requests synchronously, for simplicity. - * First we store the position map, if it has been updated since the last FLUSH, - * and we wait for the operation to finish. Then, we forward the FLUSH to the - * underlying device. - */ - -#include "map_bio.h" -#include "posmap.h" -#include "log.h" - - -int vvz_map_flush(struct vvz_volume *sv, struct bio *bio) -{ - -} diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 0eae38e..e5526df 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -92,7 +92,7 @@ static int take_free_psi(struct vvz_device *sd, u32 *psi) { int err; - if (mutex_lock_interruptible(&sd->shuffled_psis_lock)) + if (mutex_lock_interruptible(&sd->prmslices_lock)) return -EINTR; /* PSI to return */ @@ -115,7 +115,7 @@ static int take_free_psi(struct vvz_device *sd, u32 *psi) sd->psi_taken[*psi] = true; out: - mutex_unlock(&sd->shuffled_psis_lock); + mutex_unlock(&sd->prmslices_lock); return err; } diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 27a56b2..9344d49 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -22,72 +22,72 @@ */ #include -#include "volume.h" -#include "log.h" +#include "vvz.h" -struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enckey) +struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *enckey) { - struct vvz_volume *sv; + struct vvz_volume *svol; int err; - sv = kzalloc(sizeof(*sv), GFP_KERNEL); - if (!sv) { + svol = kzalloc(sizeof(*svol), GFP_KERNEL); + if (!svol) { DMERR("Could not allocate volume"); - return NULL; + return ERR_PTR(-ENOMEM); } - sv->sd = sd; - sv->vol_idx = vol_idx; - sprintf(sv->vol_name, "sflc_%lu_%lu", sd->dev_id, vol_idx); + svol->sdev = sdev; + svol->vol_idx = vol_idx; /* Crypto */ - sv->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); - if (!sv->tfm) { + svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); + if (IS_ERR(svol->tfm)) { DMERR("Could not allocate AES-XTS cipher handle"); + err = ERR_PTR(svol->tfm); + svol->tfm = NULL; goto bad; } - err = crypto_skcipher_setkey(sv->tfm, enckey, VVZ_XTS_KEYLEN); + err = crypto_skcipher_setkey(svol->tfm, enckey, VVZ_XTS_KEYLEN); if (err) { DMERR("Could not set key in crypto transform"); goto bad; } /* Position map */ - mutex_init(&sv->posmap_lock); + mutex_init(&svol->posmap_lock); /* Slight over-allocation, to fit a whole number of blocks */ - sv->posmap = vmalloc(sd->posmap_size_sectors * SECTOR_SIZE); - if (!sv->posmap) { + svol->posmap = vmalloc(sdev->posmap_size_sectors * SECTOR_SIZE); + if (!svol->posmap) { DMERR("Could not allocate position map"); + err = -ENOMEM; goto bad; } - sv->posmap_dirty = false; - sv->mapped_slices = 0; + svol->mapped_slices = 0; // TODO load posmap (must have crypto tfm initialised) // TODO: init sysfs - return sv; + return svol; bad: - vvz_vol_free(sv); - return NULL; + vvz_vol_free(svol); + return ERR_PTR(err); } -void vvz_vol_free(struct vvz_volume *sv) +void vvz_vol_free(struct vvz_volume *svol) { /* TODO remove from sysfs */ /* No locking needed here TODO: right? */ - if (sv->posmap) - vfree(sv->posmap); + if (svol->posmap) + vfree(svol->posmap); - if (sv->tfm) - crypto_free_skcipher(sv->tfm); + if (svol->tfm) + crypto_free_skcipher(svol->tfm); - kfree(sv); + kfree(svol); return; } diff --git a/dm-vvz/volume.h b/dm-vvz/volume.h deleted file mode 100644 index 582f363..0000000 --- a/dm-vvz/volume.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * A volume represents a single "logical" storage unit, mapping onto an - * underlying "physical" device. - */ - -#ifndef _VVZ_VOLUME_H_ -#define _VVZ_VOLUME_H_ - - -#include -#include "device.h" - - -/* The volume name is "sflc__" */ -#define VVZ_VOL_NAME_MAX_LEN 12 - - -struct vvz_device; - -struct vvz_volume -{ - /* Backing device */ - struct vvz_device *sd; - - /* Volume index within the device */ - size_t vol_idx; - /* Name of the volume, sflc__*/ - char vol_name[VVZ_VOL_NAME_MAX_LEN + 1]; - - /* Position map */ - struct mutex posmap_lock; - u32 *posmap; - bool posmap_dirty; - u32 mapped_slices; - - /* Crypto */ - struct crypto_skcipher *tfm; -}; - - -struct vvz_volume *vvz_vol_alloc(struct vvz_device *sd, size_t vol_idx, u8 *enckey); -void vvz_vol_free(struct vvz_volume *sv); - - -#endif /* _VVZ_VOLUME_H_ */ diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 19301ac..25e0dc2 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -24,20 +24,27 @@ #include #include #include -#include "device.h" -#include "volume.h" -#include "map_bio.h" #include "vvz_constants.h" #include "vvz.h" -#include "log.h" -/* Global array of devices, and next free index */ +/* + *---------------------------- + * Global variables + *---------------------------- + */ + DEFINE_MUTEX(vvz_alldevs_lock); struct vvz_device **vvz_alldevs = NULL; u32 vvz_free_devid = 0; /* The lowest free devID */ +/* + *---------------------------- + * Device mapper target + *---------------------------- + */ + /* * Create volume and, if not existent, the underlying device. */ @@ -49,8 +56,8 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) char *enckey_hex; u8 enckey[VVZ_XTS_KEYLEN]; u32 tot_slices; - struct vvz_device *sd; - struct vvz_volume *sv; + struct vvz_device *sdev; + struct vvz_volume *svol; int err; /* @@ -73,11 +80,11 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) enckey_hex = argv[4]; /* Sanity checks */ if (dev_id >= VVZ_MAX_DEVS) { - ti->error = "Invalid device ID"; + ti->error = "Device ID out of bounds"; return -EINVAL; } if (vol_idx >= VVZ_DEV_MAX_VOLUMES) { - ti->error = "Invalid volume index"; + ti->error = "Volume index out of bounds"; return -EINVAL; } if (strlen(enckey_hex) != 2 * VVZ_XTS_KEYLEN) { @@ -91,47 +98,53 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) return err; } - /* Create device if it doesn't exist yet (or check uniqueness if it does) */ + /* Create device, only if this is the first volume */ if (mutex_lock_interruptible(&vvz_alldevs_lock)) return -EINTR; - sd = vvz_alldevs[dev_id]; - if (!sd) { - /* Create */ - sd = vvz_dev_alloc(ti, bdev_path, dev_id, tot_slices); - if (!sd) { - ti->error = "Could not instantiate device"; - mutex_unlock(&vvz_alldevs_lock); - return -ENOMEM; - } - /* Insert in alldevs, and advance free_devid */ - vvz_alldevs[dev_id] = sd; - int i; - for (i = dev_id + 1; vvz_alldevs[i] && i < VVZ_MAX_DEVS; i++); - vvz_free_devid = i; - } else { - /* Check for uniqueness */ - if (strncmp(sd->bdev_path, bdev_path, VVZ_BDEV_PATH_LEN) != 0) { - ti->error = "Device ID already used for another device"; + sdev = vvz_alldevs[dev_id]; + if (vol_idx == 0) { + /* Check for dev_id conflict, possible if next_dev_id is read + * from sysfs again before it is advanced here */ + if (vvz_alldevs[dev_id]) { mutex_unlock(&vvz_alldevs_lock); + ti->error = "A device with this ID already exists. Retry"; return -EINVAL; } + /* Create device */ + sdev = vvz_dev_create(ti, bdev_path, dev_id, tot_slices); + if (IS_ERR(sdev)) { + mutex_unlock(&vvz_alldevs_lock); + ti->error = "Could not instantiate device"; + return PTR_ERR(sdev); + } + /* Set dm_dev */ + err = dm_get_device(ti, bdev_path, dm_table_get_mode(ti->table), &sdev->dm_dev); + if (err) { + mutex_unlock(&vvz_alldevs_lock); + vvz_dev_destroy(sdev); + ti->error = "Device lookup failed"; + return err; + } + /* Insert in alldevs, and advance free_devid */ + vvz_alldevs[dev_id] = sdev; + int i; + for (i = vvz_free_devid; i < VVZ_MAX_DEVS && vvz_alldevs[i]; i++); + vvz_free_devid = i; } mutex_unlock(&vvz_alldevs_lock); - /* Create volume. Never free sd here, for simplicity. Potential memory - * leak if vvz_vol_alloc or vvz_dev_add_volume fail on the first volume, - * but it's really a corner case. TODO discuss */ - sv = vvz_vol_alloc(sd, vol_idx, enckey); - if (!sv) { + /* Create volume */ + svol = vvz_vol_create(sdev, vol_idx, enckey); + if (IS_ERR(svol)) { ti->error = "Could not instantiate volume"; - return -ENOMEM; + err = PTR_ERR(svol); + goto bad_vol_create; } /* Insert it into the device */ - err = vvz_dev_add_volume(sd, sv, vol_idx); + err = vvz_dev_add_volume(sdev, svol, vol_idx); if (err) { ti->error = "Could not add volume to device"; - vvz_vol_free(sv); - return err; + goto bad_add_volume; } /* Only accept one block per request for simplicity TODO: improve to one slice*/ @@ -143,26 +156,41 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->num_secure_erase_bios = 0; ti->num_write_zeroes_bios = 0; ti->accounts_remapped_io = true; - ti->private = sv; + ti->private = svol; return 0; + + +bad_add_volume: + vvz_vol_destroy(svol); +bad_vol_create: + if (vol_idx == 0) { + /* Release devID */ + if (mutex_lock_interruptible(&vvz_alldevs_lock)) + return -EINTR; + vvz_alldevs[dev_id] = NULL; + if (dev_id < vvz_free_devid) + vvz_free_devid = dev_id; + mutex_unlock(&vvz_alldevs_lock); + /* Destroy device */ + vvz_dev_destroy(sdev); + } + return err; } /* Destroy volume and, if needed, the underlying device */ static void vvz_dtr(struct dm_target *ti) { - struct vvz_volume *sv = ti->private; - struct vvz_device *sd = sv->sd; - u32 dev_id = sd->dev_id; + struct vvz_volume *svol = ti->private; + struct vvz_device *sdev = svol->sdev; + u32 dev_id = sdev->dev_id; - vvz_dev_remove_volume(sd, sv->vol_idx); - vvz_vol_free(sv); - - /* Pointless to take vols_lock here */ - if (!sd->num_vols) { - vvz_dev_free(sd); + vvz_dev_remove_volume(sdev, svol->vol_idx); + vvz_vol_destroy(svol); + /* Pointless to take volumes_lock here */ + if (!sdev->num_volumes) { /* Release devID */ if (mutex_lock_interruptible(&vvz_alldevs_lock)) return; @@ -170,6 +198,8 @@ static void vvz_dtr(struct dm_target *ti) if (dev_id < vvz_free_devid) vvz_free_devid = dev_id; mutex_unlock(&vvz_alldevs_lock); + /* Destroy device */ + vvz_dev_destroy(sdev); } return; @@ -217,14 +247,20 @@ static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { - struct vvz_volume *sv = ti->private; - struct vvz_device *sd = sv->sd; + struct vvz_volume *svol = ti->private; + struct vvz_device *sdev = svol->sdev; - return fn(ti, sv->sd->dev, 0, sd->dev_header_size_sectors + + return fn(ti, svol->sdev->dm_dev, 0, sdev->dev_header_size_sectors + (ti->len * VVZ_BLOCK_SCALE), data); } +/* + *---------------------------- + * Kernel module + *---------------------------- + */ + static struct target_type vvz_target = { .name = VVZ_TARGET_NAME, .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, @@ -249,20 +285,28 @@ static int __init vvz_init(void) goto bad_alldevs_alloc; } + err = vvz_sysfs_init(); + if (err) { + DMERR("Could not init sysfs; error %d", err); + goto bad_sysfs_init; + } + err = dm_register_target(&vvz_target); if (err < 0) { DMERR("Could not register DM target"); goto bad_register_target; } - DMINFO("vvz loaded"); + DMINFO("loaded"); return 0; bad_register_target: + vvz_sysfs_exit(); +bad_sysfs_init: vfree(vvz_alldevs); bad_alldevs_alloc: - DMERR("vvz not loaded"); + DMERR("not loaded"); return err; } @@ -271,9 +315,10 @@ bad_alldevs_alloc: static void __exit vvz_exit(void) { dm_unregister_target(&vvz_target); + vvz_sysfs_exit(); vfree(vvz_alldevs); - DMINFO("vvz unloaded"); + DMINFO("unloaded"); return; } @@ -282,5 +327,5 @@ module_init(vvz_init); module_exit(vvz_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Elia Anzuoni"); +MODULE_AUTHOR("Shufflecake authors"); MODULE_DESCRIPTION(DM_NAME " target for Shufflecake"); diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 0de1e69..94f4d27 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -25,13 +25,115 @@ #define _VVZ_H -#include "device.h" +#include +#include +#include +#include "vvz_constants.h" -/* Global array of devices, and next free index */ +/* + *---------------------------- + * Constants + *---------------------------- + */ + +#define DM_MSG_PREFIX "vvz" + +/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ +#define VVZ_POSMAP_ENTRIES_PER_BLOCK 1024 + + +/* + *---------------------------- + * Structs + *---------------------------- + */ + +struct vvz_volume; + +struct vvz_device +{ + /* Shufflecake-unique device ID */ + u32 dev_id; + + /* Underlying block device */ + struct dm_dev *dm_dev; + u32 tot_slices; + + /* Header sizes in 512-byte sectors */ + sector_t posmap_size_sectors; + sector_t dev_header_size_sectors; + + /* All volumes mapping to this device */ + struct mutex volumes_lock; // TODO can ctr/dtr be actually called concurrently? + struct vvz_volume *volumes[VVZ_DEV_MAX_VOLUMES]; + size_t num_volumes; + + /* Shuffled array of PSIs */ + struct mutex slices_lock; + u32 *prmslices; + u32 prmslices_octr; + bool *slices_ofld; + u32 free_slices; + + /* TODO should these be per-device? */ + struct bio_set bs; + struct dm_io_client *io_client; +}; + +struct vvz_volume +{ + /* Backing device */ + struct vvz_device *sdev; + + /* Volume index within the device */ + size_t vol_idx; + + /* Position map */ + struct mutex posmap_lock; + u32 *posmap; + u32 mapped_slices; + + /* Crypto */ + struct crypto_skcipher *tfm; +}; + + +/* + *---------------------------- + * Global variables + *---------------------------- + */ + +/* Array of devices, and next free id */ extern struct mutex vvz_alldevs_lock; extern struct vvz_device **vvz_alldevs; extern u32 vvz_free_devid; /* The lowest free devID */ +/* + *---------------------------- + * Functions + *---------------------------- + */ + +/* Device */ +struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices); +void vvz_dev_destroy(struct vvz_device *sdev, struct dm_target *ti); +int vvz_dev_add_volume(struct vvz_device *sdev, struct vvz_volume *sv, size_t vol_idx); +void vvz_dev_remove_volume(struct vvz_device *sdev, size_t vol_idx); + +/* Volume */ +struct vvz_volume *vvz_vol_create(struct vvz_device *sd, size_t vol_idx, u8 *enckey); +void vvz_vol_destroy(struct vvz_volume *sv); + +/* Sysfs */ +int vvz_sysfs_init(); +void vvz_sysfs_exit(); +int vvz_sysfs_add_device(struct vvz_device *sdev); +void vvz_sysfs_remove_device(struct vvz_device *sdev); +int vvz_sysfs_add_volume(struct vvz_volume *svol); +void vvz_sysfs_remove_volume(struct vvz_volume *svol); + + #endif /* _VVZ_H */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index a8bcfda..544f9b5 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -43,12 +43,12 @@ #define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL -/* XTS "requires" (per the standard, at least) doubling the key size */ +/* XTS requires doubling the key size */ #define VVZ_XTS_KEYLEN 64 /* bytes */ -#define VVZ_BLOCK_SIZE 4096 /* bytes */ -#define VVZ_BLOCK_SHIFT 3 +#define VVZ_BLOCK_SIZE 4096 /* bytes */ +#define VVZ_BLOCK_SHIFT 3 #define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in block */ From 1760c8cf6ba6fdc7afc5d71aa8054ab049eb7c7e Mon Sep 17 00:00:00 2001 From: = Date: Tue, 9 Jan 2024 19:22:38 +0100 Subject: [PATCH 25/75] Begin sysfs --- .gitignore | 6 ++++ dm-vvz/Kbuild | 4 +-- dm-vvz/Makefile | 9 ++--- dm-vvz/device.c | 2 +- dm-vvz/posmap.c | 6 ++-- dm-vvz/sysfs.c | 82 ++++++++++++++++++++++++++++++++++++++++++ dm-vvz/volume.c | 8 ++--- dm-vvz/vvz.c | 25 ++----------- dm-vvz/vvz.h | 23 +++++++----- dm-vvz/vvz_constants.h | 16 ++++++--- 10 files changed, 129 insertions(+), 52 deletions(-) create mode 100644 dm-vvz/sysfs.c diff --git a/.gitignore b/.gitignore index 52695bf..d56891f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,9 @@ dkms.conf # Shufflecake binaries shufflecake +# Build directory +bin/ + +# Test images +disks/ + diff --git a/dm-vvz/Kbuild b/dm-vvz/Kbuild index 352db93..d9ab37a 100644 --- a/dm-vvz/Kbuild +++ b/dm-vvz/Kbuild @@ -21,11 +21,11 @@ # If not, see . # -MODULE_NAME := vvz +MODULE_NAME := dm_vvz obj-m := $(MODULE_NAME).o -OBJ_LIST := module.o +OBJ_LIST := vvz.o device.o volume.o sysfs.o $(MODULE_NAME)-y += $(OBJ_LIST) diff --git a/dm-vvz/Makefile b/dm-vvz/Makefile index 45cdc18..982f8ab 100644 --- a/dm-vvz/Makefile +++ b/dm-vvz/Makefile @@ -29,16 +29,13 @@ BUILD_DIR_MAKEFILE = $(BUILD_DIR)/Makefile default: $(BUILD_DIR_MAKEFILE) make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) modules -$(BUILD_DIR_MAKEFILE): $(BUILD_DIR) - echo "# This Makefile is here because of Kbuild" > $@ +$(BUILD_DIR_MAKEFILE): | $(BUILD_DIR) + echo "# This Makefile does nothing, but Kbuild needs one in this directory" > $@ $(BUILD_DIR): - mkdir -p $@ + mkdir $@ -install: - make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) modules_install - clean: rm -rf $(BUILD_DIR) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index b3c3e4c..81e9d40 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -74,7 +74,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) /* Compute sizes */ sdev->tot_slices = tot_slices; - sdev->free_slices = tot_slices; + sdev->nr_free_slices = tot_slices; /* Enough posmap blocks to fit all the entries */ sdev->posmap_size_sectors = VVZ_BLOCK_SCALE * DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index e5526df..17bc965 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -74,7 +74,7 @@ int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) goto out; /* And in the volume */ sv->posmap[lsi] = *psi; - sv->mapped_slices += 1; + sv->nr_mapped_slices += 1; sv->posmap_dirty = true; err = 0; @@ -96,7 +96,7 @@ static int take_free_psi(struct vvz_device *sd, u32 *psi) return -EINTR; /* PSI to return */ - if (unlikely(!sd->free_slices)) { + if (unlikely(!sd->nr_free_slices)) { err = -ENOSPC; goto out; } @@ -111,7 +111,7 @@ static int take_free_psi(struct vvz_device *sd, u32 *psi) for (i = sd->first_free_psi_idx + 1; i < sd->tot_slices && sd->psi_taken[i]; i++); sd->first_free_psi_idx = i; - sd->free_slices -= 1; + sd->nr_free_slices -= 1; sd->psi_taken[*psi] = true; out: diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c new file mode 100644 index 0000000..9a1d583 --- /dev/null +++ b/dm-vvz/sysfs.c @@ -0,0 +1,82 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "vvz.h" + + +/* + *---------------------------- + * Top-level entries + *---------------------------- + */ + +static ssize_t devid_show(struct module_attribute *mattr, struct module_kobject *mkobj, char *buf) +{ + ssize_t ret; + + if (mutex_lock_interruptible(&vvz_alldevs_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", vvz_free_devid); + mutex_unlock(&vvz_alldevs_lock); + + return ret; +} + + +static struct kobject *bdevs_kobj; +static struct module_attribute devid_mattr = __ATTR(VVZ_SYSFS_DEVID_RAW, 0444, devid_show, NULL); + + +int vvz_sysfs_init() +{ + int err; + + bdevs_kobj = kobject_create_and_add(VVZ_SYSFS_BDEVS, &THIS_MODULE->mkobj.kobj); + if (!bdevs_kobj) { + err = -ENOMEM; + DMERR("Could not create %s kobject", VVZ_SYSFS_BDEVS); + goto bad_bdevs; + } + + err = sysfs_create_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); + if (err) { + DMERR("Could not create %s file", VVZ_SYSFS_DEVID); + goto bad_devid; + } + + return 0; + + +bad_devid: + kobject_put(bdevs_kobj); +bad_bdevs: + return err; +} + + +void vvz_sysfs_exit() +{ + sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); + kobject_put(bdevs_kobj); +} + diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 9344d49..9a7b7ee 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -43,7 +43,7 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (IS_ERR(svol->tfm)) { DMERR("Could not allocate AES-XTS cipher handle"); - err = ERR_PTR(svol->tfm); + err = PTR_ERR(svol->tfm); svol->tfm = NULL; goto bad; } @@ -62,7 +62,7 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e err = -ENOMEM; goto bad; } - svol->mapped_slices = 0; + svol->nr_mapped_slices = 0; // TODO load posmap (must have crypto tfm initialised) // TODO: init sysfs @@ -71,12 +71,12 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e bad: - vvz_vol_free(svol); + vvz_vol_destroy(svol); return ERR_PTR(err); } -void vvz_vol_free(struct vvz_volume *svol) +void vvz_vol_destroy(struct vvz_volume *svol) { /* TODO remove from sysfs */ diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 25e0dc2..b97ff97 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -75,7 +75,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } sscanf(argv[0], "%u", &dev_id); bdev_path = argv[1]; - sscanf(argv[2], "%u", &vol_idx); + sscanf(argv[2], "%lu", &vol_idx); sscanf(argv[3], "%u", &tot_slices); enckey_hex = argv[4]; /* Sanity checks */ @@ -111,7 +111,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } /* Create device */ - sdev = vvz_dev_create(ti, bdev_path, dev_id, tot_slices); + sdev = vvz_dev_create(dev_id, tot_slices); if (IS_ERR(sdev)) { mutex_unlock(&vvz_alldevs_lock); ti->error = "Could not instantiate device"; @@ -208,27 +208,6 @@ static void vvz_dtr(struct dm_target *ti) static int vvz_map(struct dm_target *ti, struct bio *bio) { - struct vvz_volume *sv = ti->private; - enum req_op op = bio_op(bio); - - /* Bio size and bvec alignment checks (redundant?) */ - if (unlikely(bio->bi_iter.bi_size && - (bio->bi_iter.bi_size != VVZ_BLOCK_SIZE || - bio->bi_vcnt != 1))) - return DM_MAPIO_KILL; /* TODO log it? */ - - /* Dispatch */ - if (bio->bi_opf & REQ_PREFLUSH) { - /* DM core should only send empty flush requests */ - if (unlikely(bio->bi_iter.bi_size)) - return DM_MAPIO_KILL; // TODO log it? - return vvz_map_flush(sv, bio); - } else if (op == REQ_OP_READ) - return vvz_map_read(sv, bio); - else if (op == REQ_OP_WRITE) - return vvz_map_write(sv, bio); - - DMWARN("Unrecognised bio: bio_op(bio) = %d", op); return DM_MAPIO_KILL; } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 94f4d27..499618b 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -27,6 +27,7 @@ #include #include +#include #include #include "vvz_constants.h" @@ -74,7 +75,10 @@ struct vvz_device u32 *prmslices; u32 prmslices_octr; bool *slices_ofld; - u32 free_slices; + u32 nr_free_slices; + + /* Sysfs */ + struct kobject kobj; /* TODO should these be per-device? */ struct bio_set bs; @@ -92,7 +96,10 @@ struct vvz_volume /* Position map */ struct mutex posmap_lock; u32 *posmap; - u32 mapped_slices; + u32 nr_mapped_slices; + + /* Sysfs */ + struct kobject kobj; /* Crypto */ struct crypto_skcipher *tfm; @@ -119,17 +126,17 @@ extern u32 vvz_free_devid; /* The lowest free devID */ /* Device */ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices); -void vvz_dev_destroy(struct vvz_device *sdev, struct dm_target *ti); -int vvz_dev_add_volume(struct vvz_device *sdev, struct vvz_volume *sv, size_t vol_idx); +void vvz_dev_destroy(struct vvz_device *sdev); +int vvz_dev_add_volume(struct vvz_device *sdev, struct vvz_volume *svol, size_t vol_idx); void vvz_dev_remove_volume(struct vvz_device *sdev, size_t vol_idx); /* Volume */ -struct vvz_volume *vvz_vol_create(struct vvz_device *sd, size_t vol_idx, u8 *enckey); -void vvz_vol_destroy(struct vvz_volume *sv); +struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *enckey); +void vvz_vol_destroy(struct vvz_volume *svol); /* Sysfs */ -int vvz_sysfs_init(); -void vvz_sysfs_exit(); +int vvz_sysfs_init(void); +void vvz_sysfs_exit(void); int vvz_sysfs_add_device(struct vvz_device *sdev); void vvz_sysfs_remove_device(struct vvz_device *sdev); int vvz_sysfs_add_volume(struct vvz_volume *svol); diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 544f9b5..f93cf35 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -43,17 +43,23 @@ #define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL -/* XTS requires doubling the key size */ -#define VVZ_XTS_KEYLEN 64 /* bytes */ - - #define VVZ_BLOCK_SIZE 4096 /* bytes */ #define VVZ_BLOCK_SHIFT 3 -#define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in block */ +#define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in a block */ + + +/* XTS requires doubling the key size */ +#define VVZ_XTS_KEYLEN 64 /* bytes */ #define VVZ_DEV_MAX_VOLUMES 15 #define VVZ_MAX_DEVS 1024 +/* Sysfs entries under /sys/module/dm_vvz/ */ +#define VVZ_SYSFS_BDEVS "bdevs" +#define VVZ_SYSFS_DEVID_RAW next_dev_id +#define VVZ_SYSFS_DEVID STRINGIFY(VVZ_SYSFS_DEVID_RAW) + + #endif /* _VVZ_CONSTANTS_H_ */ From 437316db74e0262201797231388e0ef503620009 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 10 Jan 2024 00:01:06 +0100 Subject: [PATCH 26/75] Use kset --- dm-vvz/sysfs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index 9a1d583..e226c38 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -43,7 +43,7 @@ static ssize_t devid_show(struct module_attribute *mattr, struct module_kobject } -static struct kobject *bdevs_kobj; +static struct kset *bdevs_kset; static struct module_attribute devid_mattr = __ATTR(VVZ_SYSFS_DEVID_RAW, 0444, devid_show, NULL); @@ -51,10 +51,10 @@ int vvz_sysfs_init() { int err; - bdevs_kobj = kobject_create_and_add(VVZ_SYSFS_BDEVS, &THIS_MODULE->mkobj.kobj); - if (!bdevs_kobj) { + bdevs_kset = kset_create_and_add(VVZ_SYSFS_BDEVS, NULL, &THIS_MODULE->mkobj.kobj); + if (!bdevs_kset) { err = -ENOMEM; - DMERR("Could not create %s kobject", VVZ_SYSFS_BDEVS); + DMERR("Could not create %s kset", VVZ_SYSFS_BDEVS); goto bad_bdevs; } @@ -68,7 +68,7 @@ int vvz_sysfs_init() bad_devid: - kobject_put(bdevs_kobj); + kset_unregister(bdevs_kset); bad_bdevs: return err; } From 409e6da1b4cf199c01da0a8443c4941e000ff38c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 10 Jan 2024 00:11:12 +0100 Subject: [PATCH 27/75] Use kset --- dm-vvz/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index e226c38..5d6032c 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -77,6 +77,6 @@ bad_bdevs: void vvz_sysfs_exit() { sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); - kobject_put(bdevs_kobj); + kset_unregister(bdevs_kset); } From 95b813769ebcc9f56aabce3a05913029df1dd46a Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 11:47:17 +0100 Subject: [PATCH 28/75] Begin sysfs --- dm-vvz/device.c | 96 ++++++++------------------------- dm-vvz/sysfs.c | 5 +- dm-vvz/vvz.c | 139 +++++++++++++++++++++++++----------------------- dm-vvz/vvz.h | 17 +++--- 4 files changed, 105 insertions(+), 152 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 81e9d40..3845066 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -29,12 +29,6 @@ /* Depth of the mempool backing the bio_set */ #define VVZ_BIOSET_BIOS 64 -/* Compute device header size, in 512-byte sectors */ -#define DEV_HEADER_SIZE_SECTORS(tot_slices) \ - (VVZ_BLOCK_SCALE * \ - (1 + VVZ_DEV_MAX_VOLUMES * \ - (1 + DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK) \ - ))) /* Fisher-Yates shuffle */ @@ -57,8 +51,8 @@ static void fisheryates_u32(u32 *v, u32 len) struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) { struct vvz_device *sdev; - int err; int i; + int err; sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); if (!sdev) { @@ -67,10 +61,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) } sdev->dev_id = dev_id; - mutex_init(&sdev->volumes_lock); - for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) - sdev->volumes[i] = NULL; - sdev->num_volumes = 0; + /* The calling ->ctr() will set sdev->dm_dev */ /* Compute sizes */ sdev->tot_slices = tot_slices; @@ -83,38 +74,39 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) (VVZ_DEV_MAX_VOLUMES * VVZ_BLOCK_SCALE) + (VVZ_DEV_MAX_VOLUMES * sdev->posmap_size_sectors); - /* The calling ->ctr() will set sdev->dm_dev */ - /* Shuffled PSIs */ mutex_init(&sdev->slices_lock); sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); if (!sdev->slices_ofld) { DMERR("Could not allocate PSI occupation bitfield"); err = -ENOMEM; - goto bad; + goto bad_ofld; } sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); if (!sdev->prmslices) { DMERR("Could not allocate shuffled PSI array"); err = -ENOMEM; - goto bad; + goto bad_prmslices; } - sdev->prmslices_octr = 0; /* Generate a permutation */ for (i = 0; i < tot_slices; i++) sdev->prmslices[i] = i; fisheryates_u32(sdev->prmslices, tot_slices); + sdev->prmslices_octr = 0; /* Bioset */ - bioset_init(&sdev->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + err = bioset_init(&sdev->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + if (err) { + DMERR("Could not init bioset; error %d", err); + goto bad_bioset; + } /* Client for dm-io */ sdev->io_client = dm_io_client_create(); if (IS_ERR(sdev->io_client)) { - DMERR("Could not create dm-io client"); err = PTR_ERR(sdev->io_client); - sdev->io_client = NULL; - goto bad; + DMERR("Could not create dm-io client; error %d", err); + goto bad_dmio_client; } // TODO: init sysfs @@ -122,70 +114,28 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) return sdev; -bad: - vvz_dev_destroy(sdev); +bad_dmio_client: + bioset_exit(sdev->bs); +bad_bioset: + vfree(sdev->prmslices); +bad_prmslices: + vfree(sdev->slices_ofld); +bad_ofld: + kfree(sdev); return ERR_PTR(err); } void vvz_dev_destroy(struct vvz_device *sdev) { - if (sdev->num_volumes > 0) - DMCRIT("Destroying device that still has open volumes"); - /* TODO remove from sysfs */ - /* Needs to be zeroed out in the ctor, on failure */ - if (sdev->io_client) - dm_io_client_destroy(sdev->io_client); - /* Safe to call on zeroed bio_set */ + dm_io_client_destroy(sdev->io_client); bioset_exit(&sdev->bs); - - /* No locking needed here TODO: right? */ - if (sdev->prmslices) - vfree(sdev->prmslices); - if (sdev->slices_ofld) - vfree(sdev->slices_ofld); - + vfree(sdev->prmslices); + vfree(sdev->slices_ofld); kfree(sdev); return; } - -int vvz_dev_add_volume(struct vvz_device *sdev, struct vvz_volume *svol, size_t vol_idx) -{ - int ret; - - if (mutex_lock_interruptible(&sdev->volumes_lock)) - return -EINTR; - - if (sdev->volumes[vol_idx]) { - DMERR("Volume slot %lu already taken", vol_idx); - ret = -EINVAL; - } else { - sdev->volumes[vol_idx] = svol; - sdev->num_volumes += 1; - ret = 0; - } - - mutex_unlock(&sdev->volumes_lock); - return ret; -} - - -void vvz_dev_remove_volume(struct vvz_device *sdev, size_t vol_idx) -{ - if (mutex_lock_interruptible(&sdev->volumes_lock)) - return; - - if (sdev->volumes[vol_idx]) { - sdev->volumes[vol_idx] = NULL; - sdev->num_volumes -= 1; - } else - DMERR("Volume slot %lu already free", vol_idx); - - mutex_unlock(&sdev->volumes_lock); - return; -} - diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index 5d6032c..0112c0a 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -30,7 +30,7 @@ *---------------------------- */ -static ssize_t devid_show(struct module_attribute *mattr, struct module_kobject *mkobj, char *buf) +static ssize_t next_dev_id_show(struct module_attribute *mattr, struct module_kobject *mkobj, char *buf) { ssize_t ret; @@ -44,7 +44,8 @@ static ssize_t devid_show(struct module_attribute *mattr, struct module_kobject static struct kset *bdevs_kset; -static struct module_attribute devid_mattr = __ATTR(VVZ_SYSFS_DEVID_RAW, 0444, devid_show, NULL); +static struct module_attribute devid_mattr = + __ATTR(VVZ_SYSFS_DEVID_RAW, 0444, next_dev_id_show, NULL); int vvz_sysfs_init() diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index b97ff97..3a2cfc3 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -30,7 +30,7 @@ /* *---------------------------- - * Global variables + * Device mapper target *---------------------------- */ @@ -39,11 +39,42 @@ struct vvz_device **vvz_alldevs = NULL; u32 vvz_free_devid = 0; /* The lowest free devID */ -/* - *---------------------------- - * Device mapper target - *---------------------------- - */ +/* Add a device to the global array, and advance next_dev_id */ +static int vvz_add_device_global(u32 dev_id, struct vvz_device *sdev) +{ + int i; + + if (mutex_lock_interruptible(&vvz_alldevs_lock)) + return -ERESTARTSYS; + + /* Check for dev_id conflict, possible because a read() to next_dev_id + * in sysfs can return the same value to two processes */ + if (vvz_alldevs[dev_id]) { + mutex_unlock(&vvz_alldevs_lock); + DMERR("A device with this ID already exists. Retry"); + return -EINVAL; + } + // Add to the global array, and advance free_devid + vvz_alldevs[dev_id] = sdev; + for (i = vvz_free_devid; i < VVZ_MAX_DEVS && vvz_alldevs[i]; i++); + vvz_free_devid = i; + + mutex_unlock(&vvz_alldevs_lock); + + return 0; +} + +/* Remove a device from the global array, and update next_dev_id */ +static void vvz_remove_device_global(u32 dev_id) +{ + if (mutex_lock_interruptible(&vvz_alldevs_lock)) + return; + vvz_alldevs[dev_id] = NULL; + if (dev_id < vvz_free_devid) + vvz_free_devid = dev_id; + mutex_unlock(&vvz_alldevs_lock); +} + /* * Create volume and, if not existent, the underlying device. @@ -60,15 +91,15 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) struct vvz_volume *svol; int err; - /* - * Parse arguments. - * - * argv[0]: Shufflecake-unique device ID - * argv[1]: path to underlying physical device - * argv[2]: volume index within the device - * argv[3]: number of 1-MiB slices in the underlying device - * argv[4]: 64-byte encryption key (hex-encoded) - */ + /** + * Parse arguments. + * + * argv[0]: Shufflecake-unique device ID + * argv[1]: path to underlying physical device + * argv[2]: volume index within the device + * argv[3]: number of 1-MiB slices in the underlying device + * argv[4]: 64-byte encryption key (hex-encoded) + */ if (argc != 5) { ti->error = "Invalid argument count"; return -EINVAL; @@ -98,40 +129,37 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) return err; } - /* Create device, only if this is the first volume */ - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return -EINTR; - sdev = vvz_alldevs[dev_id]; + /* Create device, if this is the first volume, otherwise retrieve it */ if (vol_idx == 0) { - /* Check for dev_id conflict, possible if next_dev_id is read - * from sysfs again before it is advanced here */ - if (vvz_alldevs[dev_id]) { - mutex_unlock(&vvz_alldevs_lock); - ti->error = "A device with this ID already exists. Retry"; - return -EINVAL; - } - /* Create device */ sdev = vvz_dev_create(dev_id, tot_slices); if (IS_ERR(sdev)) { - mutex_unlock(&vvz_alldevs_lock); ti->error = "Could not instantiate device"; return PTR_ERR(sdev); } /* Set dm_dev */ err = dm_get_device(ti, bdev_path, dm_table_get_mode(ti->table), &sdev->dm_dev); if (err) { - mutex_unlock(&vvz_alldevs_lock); - vvz_dev_destroy(sdev); ti->error = "Device lookup failed"; - return err; + goto bad_dm_dev; + } + /* Insert in global array */ + err = vvz_add_device_global(dev_id, sdev); + if (err) { + ti->error = "Could not add device to global array"; + goto bad_dev_global; + } + + } else { + if (mutex_lock_interruptible(&vvz_alldevs_lock)) + return -ERESTARTSYS; + sdev = vvz_alldevs[dev_id]; + mutex_unlock(&vvz_alldevs_lock); + + if (!sdev) { + ti->error = "Could not find device"; + return -EINVAL; } - /* Insert in alldevs, and advance free_devid */ - vvz_alldevs[dev_id] = sdev; - int i; - for (i = vvz_free_devid; i < VVZ_MAX_DEVS && vvz_alldevs[i]; i++); - vvz_free_devid = i; } - mutex_unlock(&vvz_alldevs_lock); /* Create volume */ svol = vvz_vol_create(sdev, vol_idx, enckey); @@ -140,12 +168,6 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) err = PTR_ERR(svol); goto bad_vol_create; } - /* Insert it into the device */ - err = vvz_dev_add_volume(sdev, svol, vol_idx); - if (err) { - ti->error = "Could not add volume to device"; - goto bad_add_volume; - } /* Only accept one block per request for simplicity TODO: improve to one slice*/ ti->max_io_len = VVZ_BLOCK_SCALE; @@ -161,18 +183,12 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) return 0; -bad_add_volume: - vvz_vol_destroy(svol); bad_vol_create: if (vol_idx == 0) { - /* Release devID */ - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return -EINTR; - vvz_alldevs[dev_id] = NULL; - if (dev_id < vvz_free_devid) - vvz_free_devid = dev_id; - mutex_unlock(&vvz_alldevs_lock); - /* Destroy device */ + vvz_remove_device_global(dev_id); +bad_dev_global: + dm_put_device(ti, sdev->dm_dev); +bad_dm_dev: vvz_dev_destroy(sdev); } return err; @@ -184,21 +200,12 @@ static void vvz_dtr(struct dm_target *ti) { struct vvz_volume *svol = ti->private; struct vvz_device *sdev = svol->sdev; - u32 dev_id = sdev->dev_id; + size_t vol_idx = svol->vol_idx; - vvz_dev_remove_volume(sdev, svol->vol_idx); vvz_vol_destroy(svol); - - /* Pointless to take volumes_lock here */ - if (!sdev->num_volumes) { - /* Release devID */ - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return; - vvz_alldevs[dev_id] = NULL; - if (dev_id < vvz_free_devid) - vvz_free_devid = dev_id; - mutex_unlock(&vvz_alldevs_lock); - /* Destroy device */ + if (vol_idx == 0) { + vvz_remove_device_global(sdev->dev_id); + dm_put_device(ti, sdev->dm_dev); vvz_dev_destroy(sdev); } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 499618b..b8e8083 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -65,11 +65,6 @@ struct vvz_device sector_t posmap_size_sectors; sector_t dev_header_size_sectors; - /* All volumes mapping to this device */ - struct mutex volumes_lock; // TODO can ctr/dtr be actually called concurrently? - struct vvz_volume *volumes[VVZ_DEV_MAX_VOLUMES]; - size_t num_volumes; - /* Shuffled array of PSIs */ struct mutex slices_lock; u32 *prmslices; @@ -79,6 +74,7 @@ struct vvz_device /* Sysfs */ struct kobject kobj; + struct completion kobj_released; /* TODO should these be per-device? */ struct bio_set bs; @@ -100,6 +96,7 @@ struct vvz_volume /* Sysfs */ struct kobject kobj; + struct completion kobj_released; /* Crypto */ struct crypto_skcipher *tfm; @@ -127,8 +124,6 @@ extern u32 vvz_free_devid; /* The lowest free devID */ /* Device */ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices); void vvz_dev_destroy(struct vvz_device *sdev); -int vvz_dev_add_volume(struct vvz_device *sdev, struct vvz_volume *svol, size_t vol_idx); -void vvz_dev_remove_volume(struct vvz_device *sdev, size_t vol_idx); /* Volume */ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *enckey); @@ -137,10 +132,10 @@ void vvz_vol_destroy(struct vvz_volume *svol); /* Sysfs */ int vvz_sysfs_init(void); void vvz_sysfs_exit(void); -int vvz_sysfs_add_device(struct vvz_device *sdev); -void vvz_sysfs_remove_device(struct vvz_device *sdev); -int vvz_sysfs_add_volume(struct vvz_volume *svol); -void vvz_sysfs_remove_volume(struct vvz_volume *svol); +int vvz_sysfs_register_device(struct vvz_device *sdev); +void vvz_sysfs_unregister_device(struct vvz_device *sdev); +int vvz_sysfs_register_volume(struct vvz_volume *svol); +void vvz_sysfs_unregister_volume(struct vvz_volume *svol); #endif /* _VVZ_H */ From be34b3909262fe9ea848c0d07529c70cf2cda648 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 11:56:27 +0100 Subject: [PATCH 29/75] Fix volume --- dm-vvz/volume.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 9a7b7ee..cbe155c 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -42,15 +42,14 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e /* Crypto */ svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (IS_ERR(svol->tfm)) { - DMERR("Could not allocate AES-XTS cipher handle"); err = PTR_ERR(svol->tfm); - svol->tfm = NULL; - goto bad; + DMERR("Could not allocate AES-XTS cipher handle; error %d", err); + goto bad_tfm_alloc; } err = crypto_skcipher_setkey(svol->tfm, enckey, VVZ_XTS_KEYLEN); if (err) { - DMERR("Could not set key in crypto transform"); - goto bad; + DMERR("Could not set key in crypto transform; error %d", err); + goto bad_tfm_setkey; } /* Position map */ @@ -60,7 +59,7 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e if (!svol->posmap) { DMERR("Could not allocate position map"); err = -ENOMEM; - goto bad; + goto bad_posmap_alloc; } svol->nr_mapped_slices = 0; // TODO load posmap (must have crypto tfm initialised) @@ -70,8 +69,11 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e return svol; -bad: - vvz_vol_destroy(svol); +bad_posmap_alloc: +bad_tfm_setkey: + crypto_free_skcipher(svol->tfm); +bad_tfm_alloc: + kfree(svol); return ERR_PTR(err); } @@ -80,13 +82,8 @@ void vvz_vol_destroy(struct vvz_volume *svol) { /* TODO remove from sysfs */ - /* No locking needed here TODO: right? */ - if (svol->posmap) - vfree(svol->posmap); - - if (svol->tfm) - crypto_free_skcipher(svol->tfm); - + vfree(svol->posmap); + crypto_free_skcipher(svol->tfm); kfree(svol); return; From 7599ede924460a6ed4ce15c80d38510804af1a7d Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 15:20:56 +0100 Subject: [PATCH 30/75] Add sysfs device --- dm-vvz/sysfs.c | 95 +++++++++++++++++++++++++++++++++++++++--- dm-vvz/vvz_constants.h | 3 +- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index 0112c0a..08e075f 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -42,11 +42,8 @@ static ssize_t next_dev_id_show(struct module_attribute *mattr, struct module_ko return ret; } - static struct kset *bdevs_kset; -static struct module_attribute devid_mattr = - __ATTR(VVZ_SYSFS_DEVID_RAW, 0444, next_dev_id_show, NULL); - +static struct module_attribute devid_mattr = __ATTR_RO(next_dev_id); int vvz_sysfs_init() { @@ -74,10 +71,98 @@ bad_bdevs: return err; } - void vvz_sysfs_exit() { sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); kset_unregister(bdevs_kset); } + +/* + *---------------------------- + * Device entries + *---------------------------- + */ + +static ssize_t dev_id_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); + + return sysfs_emit(buf, "%u\n", sdev->dev_id); +} + +static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); + + return sysfs_emit(buf, "%u\n", sdev->tot_slices); +} + +static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); + int ret; + + if (mutex_lock_interruptible(&sdev->slices_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", sdev->nr_free_slices); + mutex_unlock(&sdev->slices_lock); + + return ret; +} + +static struct kobj_attribute dev_id_kattr = __ATTR_RO(dev_id); +static struct kobj_attribute tot_slices_kattr = __ATTR_RO(tot_slices); +static struct kobj_attribute free_slices_kattr = __ATTR_RO(free_slices); +static struct attribute *vvz_device_default_attrs[] = { + &dev_id_kattr.attr, + &tot_slices_kattr.attr, + &free_slices_kattr.attr, + NULL +}; +ATTRIBUTE_GROUPS(vvz_device_default); + +static void vvz_device_kobj_release(struct kobject *kobj) +{ + struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); + + complete(&sdev->kobj_released); +} + +static struct kobj_type vvz_device_ktype = { + .release = vvz_device_kobj_release, + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = vvz_device_default_groups +}; + +int vvz_sysfs_register_device(struct vvz_device *sdev) +{ + int err; + + /* Completion */ + init_completion(&sdev->kobj_released); + + /* Register directory :/ under bdevs/ */ + sdev->kobj.kset = bdevs_kset; + err = kobject_init_and_add(&sdev->kobj, &vvz_device_ktype, NULL, + "%s", sdev->dm_dev->name); + if (err) + goto bad; + /* Emit uevent */ + kobject_uevent(&sdev->kobj, KOBJ_ADD); + + return 0; + + +bad: + kobject_put(&sdev->kobj); + wait_for_completion(&sdev->kobj_released); + return err; +} + +void vvz_sysfs_unregister_device(struct vvz_device *sdev) +{ + kobject_put(&sdev->kobj); + wait_for_completion(&sdev->kobj_released); +} + diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index f93cf35..b2bfe0c 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -58,8 +58,7 @@ /* Sysfs entries under /sys/module/dm_vvz/ */ #define VVZ_SYSFS_BDEVS "bdevs" -#define VVZ_SYSFS_DEVID_RAW next_dev_id -#define VVZ_SYSFS_DEVID STRINGIFY(VVZ_SYSFS_DEVID_RAW) +#define VVZ_SYSFS_DEVID "next_dev_id" #endif /* _VVZ_CONSTANTS_H_ */ From 11db7f252661fca41659b8c97e1c3bb756310a87 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 15:37:35 +0100 Subject: [PATCH 31/75] Add sysfs volume --- dm-vvz/sysfs.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ dm-vvz/volume.c | 1 + dm-vvz/vvz.h | 2 ++ 3 files changed, 72 insertions(+) diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index 08e075f..d234331 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -166,3 +166,72 @@ void vvz_sysfs_unregister_device(struct vvz_device *sdev) wait_for_completion(&sdev->kobj_released); } + +/* + *---------------------------- + * Volume entries + *---------------------------- + */ + +static ssize_t mapped_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct vvz_volume *svol = container_of(kobj, struct vvz_volume, kobj); + int ret; + + if (mutex_lock_interruptible(&svol->posmap_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", svol->nr_mapped_slices); + mutex_unlock(&svol->posmap_lock); + + return ret; +} + +static struct kobj_attribute mapped_slices_kattr = __ATTR_RO(mapped_slices); +static struct attribute *vvz_volume_default_attrs[] = { + &mapped_slices_kattr.attr, + NULL +}; +ATTRIBUTE_GROUPS(vvz_volume_default); + +static void vvz_volume_kobj_release(struct kobject *kobj) +{ + struct vvz_volume *svol = container_of(kobj, struct vvz_volume, kobj); + + complete(&svol->kobj_released); +} + +static struct kobj_type vvz_volume_ktype = { + .release = vvz_volume_kobj_release, + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = vvz_volume_default_groups +}; + +int vvz_sysfs_register_volume(struct vvz_volume *svol) +{ + int err; + + /* Completion */ + init_completion(&svol->kobj_released); + + /* Register directory name>/ under device directory */ + err = kobject_init_and_add(&svol->kobj, &vvz_volume_ktype, &svol->sdev->kobj, + "%s", svol->name); + if (err) + goto bad; + /* Emit uevent */ + kobject_uevent(&svol->kobj, KOBJ_ADD); + + return 0; + + +bad: + kobject_put(&svol->kobj); + wait_for_completion(&svol->kobj_released); + return err; +} + +void vvz_sysfs_unregister_volume(struct vvz_volume *svol) +{ + kobject_put(&svol->kobj); + wait_for_completion(&svol->kobj_released); +} diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index cbe155c..982d9a2 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -38,6 +38,7 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e svol->sdev = sdev; svol->vol_idx = vol_idx; + sprintf(svol->name, "vvz_%u_%lu", sdev->dev_id, vol_idx); /* Crypto */ svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index b8e8083..85ae622 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -88,6 +88,8 @@ struct vvz_volume /* Volume index within the device */ size_t vol_idx; + /* Name: vvz__ */ + char name[16]; /* Position map */ struct mutex posmap_lock; From 73664e349c8d54b9337544b6821e1d07b818eea6 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 15:42:26 +0100 Subject: [PATCH 32/75] Utilise sysfs --- dm-vvz/device.c | 12 +++++++++--- dm-vvz/volume.c | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 3845066..b1a742d 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -109,11 +109,18 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) goto bad_dmio_client; } - // TODO: init sysfs + /* Register to sysfs, once initialised */ + err = vvz_sysfs_register_device(sdev); + if (err) { + DMERR("Could not register device with sysfs; error %d", err); + goto bad_sysfs; + } return sdev; +bad_sysfs: + dm_io_client_destroy(sdev->io_client); bad_dmio_client: bioset_exit(sdev->bs); bad_bioset: @@ -128,8 +135,7 @@ bad_ofld: void vvz_dev_destroy(struct vvz_device *sdev) { - /* TODO remove from sysfs */ - + vvz_sysfs_unregister_device(sdev); dm_io_client_destroy(sdev->io_client); bioset_exit(&sdev->bs); vfree(sdev->prmslices); diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 982d9a2..110a7aa 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -65,11 +65,18 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e svol->nr_mapped_slices = 0; // TODO load posmap (must have crypto tfm initialised) - // TODO: init sysfs + /* Register to sysfs, once initialised */ + err = vvz_sysfs_register_volume(svol); + if (err) { + DMERR("Could not register volume with sysfs; error %d", err); + goto bad_sysfs; + } return svol; +bad_sysfs: + vfree(svol->posmap); bad_posmap_alloc: bad_tfm_setkey: crypto_free_skcipher(svol->tfm); @@ -81,8 +88,7 @@ bad_tfm_alloc: void vvz_vol_destroy(struct vvz_volume *svol) { - /* TODO remove from sysfs */ - + vvz_sysfs_unregister_volume(svol); vfree(svol->posmap); crypto_free_skcipher(svol->tfm); kfree(svol); From c563841e4ea0210e1768069f413433647a10f315 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 16:36:36 +0100 Subject: [PATCH 33/75] Update wq in scholia --- dm-vvz/SCHOLIA.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dm-vvz/SCHOLIA.md b/dm-vvz/SCHOLIA.md index f32f15d..a8b2439 100644 --- a/dm-vvz/SCHOLIA.md +++ b/dm-vvz/SCHOLIA.md @@ -1,7 +1,7 @@ #### Workqueues Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, `dm-crypt` uses a bound `io_queue` for bio mapping; it also has a `crypt_queue` for encryption/decryption, that is `WQ_CPU_INTENSIVE`: that wq is either bound or unbound, based on the flag `DM_CRYPT_SAME_CPU`. Both these workqueues are `WQ_MEM_RECLAIM`, and we probably need that for Shufflecake too. -As for granularity, almost no DM target uses the kernel-global wq (with `schedule_work()`); many allocate a per-target wq, while some use a module-wide wq. This latter choice is probably the easiest, so it's a good first attempt; we might hit the concurrency limit (set by `max_active`) in the future, so that's one thing to look out for. -All in all, we can use a single module-wide bound wq, that is `WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE`, and whose work items process bio's start-to-finish. +As for granularity, almost no DM target uses the kernel-global wq (with `schedule_work()`); many allocate a per-target wq, while some use a module-wide wq. At this first stage, we use a per-device wq, since we imagine the device as the unit of resource sharing; we might hit the concurrency limit (set by `max_active`) in the future, so that's one thing to look out for. +All in all, we can use a per-device bound wq, that is `WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE`, and whose work items process bio's start-to-finish. #### Position map: write-back or write-through? A first idea was to have slice allocation happen exclusively in memory, and only synchronise the position map to disk upon FLUSH requests (write-back posmap), but this gives the scheme a weird and inconsistent *crash behaviour*. From 9d159d62520870b44bb2475f921c4b023c44b4f7 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 11 Jan 2024 16:53:25 +0100 Subject: [PATCH 34/75] Stub bio map --- dm-vvz/device.c | 11 +++++++++++ dm-vvz/vvz.c | 19 ++++++++++++++++++- dm-vvz/vvz.h | 15 ++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index b1a742d..e81d9f3 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -109,6 +109,14 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) goto bad_dmio_client; } + /* Workqueue */ + sdev->wq = alloc_workqueue("vvz_%s", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->dm_dev->name); + if (!sdev->wq) { + err = -ENOMEM; + DMERR("Could not allocate workqueue"); + goto bad_wq; + } + /* Register to sysfs, once initialised */ err = vvz_sysfs_register_device(sdev); if (err) { @@ -120,6 +128,8 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) bad_sysfs: + destroy_workqueue(sdev->wq); +bad_wq: dm_io_client_destroy(sdev->io_client); bad_dmio_client: bioset_exit(sdev->bs); @@ -136,6 +146,7 @@ bad_ofld: void vvz_dev_destroy(struct vvz_device *sdev) { vvz_sysfs_unregister_device(sdev); + destroy_workqueue(sdev->wq); dm_io_client_destroy(sdev->io_client); bioset_exit(&sdev->bs); vfree(sdev->prmslices); diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 3a2cfc3..9461493 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -178,6 +178,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->num_secure_erase_bios = 0; ti->num_write_zeroes_bios = 0; ti->accounts_remapped_io = true; + ti->per_io_data_size = sizeof(struct vvz_io); ti->private = svol; return 0; @@ -215,7 +216,23 @@ static void vvz_dtr(struct dm_target *ti) static int vvz_map(struct dm_target *ti, struct bio *bio) { - return DM_MAPIO_KILL; + struct vvz_io *sio = dm_per_bio_data(bio, sizeof(struct vvz_io)); + struct vvz_volume *svol = ti->private; + + // TODO check flush + + /* Set fields */ + sio->orig_bio = bio; + sio->svol = svol; + + /* Enqueue */ + if (bio_data_dir(bio) == READ) + INIT_WORK(&sio->work, vvz_read_work_fn); + else + INIT_WORK(&sio->work, vvz_write_work_fn); + queue_work(svol->sdev->wq, &sio->work); + + return DM_MAPIO_SUBMITTED; } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 85ae622..6241b77 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -76,9 +76,10 @@ struct vvz_device struct kobject kobj; struct completion kobj_released; - /* TODO should these be per-device? */ + /* Resource sharing */ struct bio_set bs; struct dm_io_client *io_client; + struct workqueue_struct *wq; }; struct vvz_volume @@ -104,6 +105,14 @@ struct vvz_volume struct crypto_skcipher *tfm; }; +struct vvz_io +{ + struct vvz_volume *svol; + struct bio *orig_bio; + + struct work_struct work; +}; + /* *---------------------------- @@ -139,5 +148,9 @@ void vvz_sysfs_unregister_device(struct vvz_device *sdev); int vvz_sysfs_register_volume(struct vvz_volume *svol); void vvz_sysfs_unregister_volume(struct vvz_volume *svol); +/* Bio mapping */ +void vvz_read_work_fn(struct work_struct *work); +void vvz_write_work_fn(struct work_struct *work); + #endif /* _VVZ_H */ From b49865d004c51e9e593b440262f27a2e9cf992a9 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 19 Jan 2024 17:53:20 +0100 Subject: [PATCH 35/75] Conclude posmap.c --- dm-vvz/crypto.c | 106 +++++----- dm-vvz/crypto.h | 46 ----- dm-vvz/device.c | 6 +- dm-vvz/posmap.c | 426 ++++++++++++++++++++++++++++------------- dm-vvz/posmap.h | 49 ----- dm-vvz/vvz.c | 2 +- dm-vvz/vvz.h | 22 ++- dm-vvz/vvz_constants.h | 5 + 8 files changed, 374 insertions(+), 288 deletions(-) delete mode 100644 dm-vvz/crypto.h delete mode 100644 dm-vvz/posmap.h diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index 0107b10..cdf0528 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -23,71 +23,26 @@ #include #include -#include "crypto.h" #include "vvz_constants.h" -#include "log.h" -static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, - struct scatterlist *dst, u64 pblk_num, int rw); - - -/* Encrypt-decrypt a single block (memory buffer is a page) */ -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw) -{ - struct scatterlist dst, src; - - /* We assume PAGE_SIZE == VVZ_BLOCK_SIZE TODO better document this */ - sg_init_table(&src, 1); - sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); - sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); - - return crypt_sg(tfm, &src, &dst, pblk_num, rw); -} - - -/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ -int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, - size_t num_blocks, u64 first_pblk_num, int rw) -{ - struct scatterlist dst, src; - size_t block; - u64 pblk_num; - int err; - - pblk_num = first_pblk_num; - for (block = 0; block < num_blocks; block++) { - sg_init_one(&src, src_buf, VVZ_BLOCK_SIZE); - sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); - - err = crypt_sg(tfm, &src, &dst, pblk_num, rw); - if (err) - return err; - - src_buf += VVZ_BLOCK_SIZE; - dst_buf += VVZ_BLOCK_SIZE; - pblk_num += 1; - } - - return 0; -} - - -/* - * The IV is constructed as the 0-padded LE representation of the block number, - * which is exactly what dm-crypt does (IV mode "plain64") +/** + * Encrypt/decrypt exactly one block, already encoded in the scatterlist. + * All other crypto functions reduce to this one. + * The IV is constructed as the right-0-padded LE representation of the + * physical block number, which is exactly what dm-crypt does when using the + * IV mode "plain64". */ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, struct scatterlist *dst, u64 pblk_num, int rw) { - u8 iv[VVZ_CRYPTO_IVLEN]; + u8 iv[VVZ_XTS_IVLEN]; struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); int err; - /* TODO: not too sure about the gfp_mask here */ + // TODO not too sure about the gfp_mask here + // TODO move @req into struct vvz_io? req = skcipher_request_alloc(tfm, GFP_NOIO); if (!req) return -ENOMEM; @@ -97,7 +52,7 @@ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, crypto_req_done, &wait); /* Construct IV */ - memset(iv, 0, VVZ_CRYPTO_IVLEN); + memset(iv, 0, VVZ_XTS_IVLEN); *(__le64 *)iv = cpu_to_le64(pblk_num); skcipher_request_set_crypt(req, src, dst, VVZ_BLOCK_SIZE, iv); @@ -110,3 +65,44 @@ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, return err; } +/* Encrypt-decrypt a single block (memory buffer is a page) */ +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw) +{ + struct scatterlist dst, src; + + /* We assume PAGE_SIZE >= VVZ_BLOCK_SIZE TODO better document this */ + sg_init_table(&src, 1); + sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); + sg_init_table(&dst, 1); + sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); + + return crypt_sg(tfm, &src, &dst, pblk_num, rw); +} + + +/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ +int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, + u64 num_blocks, u64 first_pblk_num, int rw) +{ + struct scatterlist dst, src; + u64 pblk_num; + int err; + + for (pblk_num = first_pblk_num; + pblk_num < first_pblk_num + num_blocks; + pblk_num++) { + sg_init_one(&src, src_buf, VVZ_BLOCK_SIZE); + sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); + + err = crypt_sg(tfm, &src, &dst, pblk_num, rw); + if (err) + return err; + + src_buf += VVZ_BLOCK_SIZE; + dst_buf += VVZ_BLOCK_SIZE; + } + + return 0; +} + diff --git a/dm-vvz/crypto.h b/dm-vvz/crypto.h deleted file mode 100644 index c3a83c3..0000000 --- a/dm-vvz/crypto.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* For AES-XTS-256, we use the *physical* address of the 4096-byte block, - * within the device, as IV (little-endian, zero-padded). */ - -#ifndef _VVZ_CRYPTO_H_ -#define _VVZ_CRYPTO_H_ - - -#include - - -#define VVZ_CRYPTO_IVLEN 16 /* bytes */ - - -/* Encrypt-decrypt a single block (memory buffer is a page) */ -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw); - -/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ -int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, u8 *src_buf, u8 *dst_buf, - size_t num_blocks, u64 first_pblk_num, int rw); - - -#endif /* _VVZ_CRYPTO_H_ */ diff --git a/dm-vvz/device.c b/dm-vvz/device.c index e81d9f3..3681fff 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -95,7 +95,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) sdev->prmslices_octr = 0; /* Bioset */ - err = bioset_init(&sdev->bs, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + err = bioset_init(&sdev->bioset, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); if (err) { DMERR("Could not init bioset; error %d", err); goto bad_bioset; @@ -132,7 +132,7 @@ bad_sysfs: bad_wq: dm_io_client_destroy(sdev->io_client); bad_dmio_client: - bioset_exit(sdev->bs); + bioset_exit(sdev->bioset); bad_bioset: vfree(sdev->prmslices); bad_prmslices: @@ -148,7 +148,7 @@ void vvz_dev_destroy(struct vvz_device *sdev) vvz_sysfs_unregister_device(sdev); destroy_workqueue(sdev->wq); dm_io_client_destroy(sdev->io_client); - bioset_exit(&sdev->bs); + bioset_exit(&sdev->bioset); vfree(sdev->prmslices); vfree(sdev->slices_ofld); kfree(sdev); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 17bc965..e5ca102 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -21,175 +21,337 @@ * If not, see . */ -#include "posmap.h" -#include "crypto.h" +#include "vvz.h" -/******************************************************************************* - * In-memory operations on the position map - ******************************************************************************/ +/* + *---------------------------- + * Create slice mapping + *---------------------------- + */ - -/* Get the next free PSI in the device's shuffled array, and mark it taken */ -static int take_free_psi(struct vvz_device *sd, u32 *psi); - - -/* Returns INVALID (in *psi) if mapping does not exist */ -int vvz_get_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) +/** + * Grab the specified PSI in the device: mark as occupied, decrease the number + * of free slices, advance the occupation counter. This specific algorithm, + * that never wraps @prmslices_octr around, only works because slices are never + * freed up. + * Sanity checks to be performed by the caller. + * + * MUTEX: @sdev->slices_lock must be held. + */ +static void _grab_psi(struct vvz_device *sdev, u32 psi) { - /* Sanity check (redundant?) */ - if(unlikely(lsi >= sv->sd->tot_slices)) - return -EINVAL; + u32 i; - if (mutex_lock_interruptible(&sv->posmap_lock)) - return -EINTR; - *psi = sv->posmap[lsi]; - mutex_unlock(&sv->posmap_lock); + sdev->slices_ofld[*psi] = true; + sdev->nr_free_slices--; + + /* Preserve the invariant: @prmslices_octr must point to a free slice */ + for (i = sdev->prmslices_octr; + i < sdev->tot_slices && sdev->slices_ofld[i]; + i++); + sdev->prmslices_octr = i; +} + +/** + * Return the next free PSI in the device's shuffled array, but don't modify + * the device state. + * + * MUTEX: @sdev->slices_lock must be held. + */ +static int peek_next_free_psi(struct vvz_device *sdev, u32 *psi) +{ + int err; + + if (unlikely(!sdev->nr_free_slices)) + return -ENOSPC; + if (unlikely(sdev->prmslices_octr >= sdev->tot_slices)) + return -ENOTRECOVERABLE; // Grave inconsistency + + /* Invariant: @prmslices_octr points to a free slice */ + *psi = sdev->prmslices[sdev->prmslices_octr]; + if (unlikely(sdev->slices_ofld[*psi])) + return -ENOTRECOVERABLE; // Grave inconsistency return 0; } - -/* Does not persist mapping on disk (only done on FLUSH requests) */ -int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi) +/** + * Map LSI => PSI, only in memory. + * Sanity checks to be performed by the caller. + * + * MUTEX: @sdev->slices_lock must be held. + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + */ +static void _create_local_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 psi) { - int err; + /* Grab it from the device */ + _grab_psi(svol->sdev, psi); + /* Insert in the volume */ + svol->posmap[lsi] = *psi; + svol->nr_mapped_slices++; - /* Sanity check (redundant?) */ - if(unlikely(lsi >= sv->sd->tot_slices)) - return -EINVAL; - - if (mutex_lock_interruptible(&sv->posmap_lock)) - return -EINTR; - - /* Check mapping not existent (redundant?) */ - if (unlikely(sv->posmap[lsi] != VVZ_POSMAP_INVALID)){ - err = -EINVAL; - goto out; - } - - /* Create it in the device */ - err = take_free_psi(sv->sd, psi); - if (err) - goto out; - /* And in the volume */ - sv->posmap[lsi] = *psi; - sv->nr_mapped_slices += 1; - sv->posmap_dirty = true; - - err = 0; - -out: - mutex_unlock(&sv->posmap_lock); - return err; + return; } - -/* Get the next free PSI in the device's shuffled array, and mark it taken. - * This specific algorithm, that never wraps first_free_psi_idx around, - * only works because slices are never freed up. */ -static int take_free_psi(struct vvz_device *sd, u32 *psi) +/** + * Delete mapping for the given LSI, only in memory. + * Sanity checks to be performed by the caller. + * + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + */ +static void _delete_local_slice_mapping(struct vvz_volume *svol, u32 lsi) { - int err; + /* Delete mapping in the volume */ + svol->posmap[lsi] = VVZ_POSMAP_INVALID; + svol->nr_mapped_slices--; - if (mutex_lock_interruptible(&sd->prmslices_lock)) - return -EINTR; - - /* PSI to return */ - if (unlikely(!sd->nr_free_slices)) { - err = -ENOSPC; - goto out; - } - *psi = sd->shuffled_psis[sd->first_free_psi_idx]; - if (unlikely(sd->psi_taken[*psi])) { - err = -EINVAL; // TODO make it more tragic - goto out; - } - - /* Update device state */ - int i; - for (i = sd->first_free_psi_idx + 1; - i < sd->tot_slices && sd->psi_taken[i]; i++); - sd->first_free_psi_idx = i; - sd->nr_free_slices -= 1; - sd->psi_taken[*psi] = true; - -out: - mutex_unlock(&sd->prmslices_lock); - return err; + /* Don't do anything in the device though, leave it there: we don't yet + * have an obvious way to release PSIs. + * This means a PSI will be incorrectly marked as occupied, but that's + * not too bad: the PSI shuffling and its occupation counter are + * ephemeral, so they reset if you close and reopen all the volumes. */ + return; } - -/******************************************************************************* - * On-disk operations on the position map - ******************************************************************************/ - - -/* Synchronously read/write the entire on-disk encrypted position map */ -static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw); - - -/* Read position map from disk and decrypt in place */ -int vvz_load_posmap(struct vvz_volume *sv) +/** + * Synchronously store (and flush) the posmap block containing the given LSI. + * + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + */ +static int store_posmap_block(struct vvz_volume *svol, u32 lsi) { + struct vvz_device *sdev = svol->sdev; + u32 posmap_block_num = lsi / VVZ_POSMAP_ENTRIES_PER_BLOCK; + u32 first_lsi = posmap_block_num * VVZ_POSMAP_ENTRIES_PER_BLOCK; + struct page *page; + struct bio *bio; int err; - /* No locking needed (we are in the constructor) */ - err = rw_posmap(sv, sv->posmap, READ); - if (err) - return err; - - /* Decrypt in place */ - err = vvz_crypt_blocks_vm(sv->tfm, sv->posmap, sv->posmap, - sv->sd->posmap_size_sectors >> VVZ_BLOCK_SHIFT, - VVZ_POSMAP_START_SECTOR(sv) >> VVZ_BLOCK_SHIFT, - READ); - if (err) - return err; - - return 0; -} - - -/* Encrypt position map out of place, onto a buffer, and write it on disk */ -int vvz_store_posmap(struct vvz_volume *sv) -{ - u8 *enc_posmap; - int err; - - /* Allocate it every time TODO evaluate alternatives */ - enc_posmap = vmalloc(sv->sd->posmap_size_sectors * SECTOR_SIZE); - if (!enc_posmap) + /* Sync + flush TODO GFP mask ok? */ + bio = bio_alloc_bioset(sdev->dm_dev->bdev, 1, + REQ_OP_WRITE | REQ_SYNC | REQ_FUA, GFP_NOIO, + &sdev->bioset); + if (!bio) { + DMERR("Could not allocate posmap block bio"); return -ENOMEM; + } + bio->bi_iter.bi_sector = VVZ_POSMAP_START_SECTOR(svol) + + (posmap_block_num << VVZ_BLOCK_SHIFT); - if (mutex_lock_interruptible&sv->posmap_lock) { - err = -EINTR; - goto out_vfree; + /* Alloc and add page TODO GFP mask */ + page = alloc_page(GFP_NOIO); + if (!page) { + DMERR("Could not allocate posmap block page"); + err = -ENOMEM; + goto bad_alloc_page; + } + // TODO remove this error check + if (unlikely(!bio_add_page(bio, page, VVZ_BLOCK_SIZE, 0))) { + DMCRIT("Could not add posmap block page to bio!"); + err = -ENOTRECOVERABLE; + goto bad_add_page; } + /* Serialise posmap block onto the page */ + void *page_ptr = kmap_local_page(page); + u32 lsi_iter; + for (lsi_iter = first_lsi; + lsi_iter < first_lsi + VVZ_POSMAP_ENTRIES_PER_BLOCK; + lsi_iter++) { + u32 psi = svol->posmap[lsi_iter]; + __be32 *be_psi = (__be32*) (page_ptr + (lsi_iter * sizeof(__be32))); + *be_psi = cpu_to_be32(psi); + } + kunmap_local(page_ptr); -out_vfree: - vfree(enc_posmap); + /* Encrypt the block in place */ + err = vvz_crypt_block_page(svol->tfm, page, page, + bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); + if (err) { + DMERR("Could not encrypt posmap block; error %d", err); + goto bad_encrypt; + } + + /* Submit */ + err = submit_bio_wait(bio); + DMERR("Could not complete posmap block bio; error %d", err); + +bad_encrypt: +bad_add_page: + __free_page(page); +bad_alloc_page: + bio_put(bio); return err; } -/* Synchronously read/write the entire on-disk encrypted position map */ -static int rw_posmap(struct vvz_volume *sv, u8 *buf, int rw) +/** + * Create a new mapping for the given LSI, and synchronise back to disk. + * + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + * MUTEX: takes @sdev->slices_lock. + * + * Syncing to disk means the posmap lock will be held (by the caller) for a long + * time thus blocking out all the other incoming bio's, even unrelated ones + * (falling in different slices). Several strategies are possible to avoid this + * problem, but for now we keep this simple implementation. + */ +int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *psi) +{ + struct vvz_device *sdev = svol->sdev; + int err; + + /* Bounds check TODO redundant? */ + if(unlikely(lsi >= svol->sdev->tot_slices)) + return -EINVAL; + /* Check mapping not existent TODO redundant? */ + if (unlikely(svol->posmap[lsi] != VVZ_POSMAP_INVALID)) + return -EINVAL; + + /* Create mapping */ + if (mutex_lock_interruptible(&sdev->slices_lock)) + return -ERESTARTSYS; + err = peek_next_free_psi(sdev, psi); + if (err) { + mutex_unlock(&sdev->slices_lock); + return err; + } + _create_local_slice_mapping(svol, lsi, *psi); + mutex_unlock(&sdev->slices_lock); + + /* Write posmap block to disk */ + err = store_posmap_block(svol, lsi); + if (err) { + DMERR("Could not store posmap block; error %d", err); + _delete_local_slice_mapping(svol, lsi); + return err; + } + + return 0; +} + + +/* + *---------------------------- + * Load position map + *---------------------------- + */ + +/** + * Synchronously read the entire on-disk encrypted position map + * + * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). + */ +static int read_encrypted_posmap(struct vvz_volume *svol) { struct dm_io_request io_req = { - .bi_opf = (rw == READ) ? REQ_OP_READ : REQ_OP_WRITE, + .bi_opf = REQ_OP_READ | REQ_SYNC, .mem.type = DM_IO_VMA, - .mem.ptr.vma = buf, + .mem.ptr.vma = svol->posmap, .notify.fn = NULL, - .client = sv->sd->io_client + .client = svol->sdev->io_client }; struct dm_io_region io_region = { - .bdev = sv->sd->dev->bdev, - .sector = VVZ_POSMAP_START_SECTOR(sv), - .count = sv->sd->posmap_size_sectors + .bdev = svol->sdev->dm_dev->bdev, + .sector = VVZ_POSMAP_START_SECTOR(svol), + .count = svol->sdev->posmap_size_sectors }; return dm_io(&io_req, 1, &io_region, NULL); } +/** + * De-serialise the position map entries. On the fly, if a conflict is detected, + * resolve it by sampling a new PSI, and sync to disk (block by block). + * + * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). + * MUTEX: @sdev->slices_lock must be held. + */ +static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) +{ + struct vvz_device *sdev = svol->sdev; + void *posmap_ptr = svol->posmap; + u32 lsi; + bool posmap_block_dirty; + int err; + + for (lsi = 0; lsi < sdev->tot_slices; lsi++) { + /* Reset dirty bit at the start of every posmap block */ + if (lsi % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) + posmap_block_dirty = false; + + /* De-serialise posmap entry */ + __be32 *be_psi = (__be32*) (posmap_ptr + (lsi * sizeof(__be32))); + u32 psi = be32_to_cpu(*be_psi); + + /* If LSI unmapped, just continue */ + if (psi == VVZ_POSMAP_INVALID) { + svol->posmap[lsi] = psi; + continue; + } + + /* If PSI already taken, sample a new one */ + if (sdev->slices_ofld[psi]) { + DMWARN("Corruption of volume %d: LSI %u was evicted from PSI %u", + svol->vol_idx, lsi, psi); + err = peek_next_free_psi(sdev, &psi); + if (err) + return err; + posmap_block_dirty = true; + } + /* Either way, create the mapping locally */ + _create_local_slice_mapping(svol, lsi, psi); + + /* Only check dirty bit at the end of the posmap block */ + if (posmap_block_dirty && + ( ((lsi + 1) % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) || + (lsi == sdev->tot_slices) )) { + err = store_posmap_block(svol, lsi); + if (err) + return err; + } + } + + return 0; +} + + +/** + * Load the volume's position map from the disk. If some conflicts are present + * (i.e. an LSI is mapped to a PSI that's already taken), then resolve them + * (i.e. re-sample a free PSI for the "unlucky" LSI) and sync back to disk. + * + * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). + * MUTEX: takes @sdev->slices_lock. + */ +int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) +{ + int err; + struct vvz_device *sdev = svol->sdev; + u32 lsi; + + /* Read raw posmap from disk */ + err = read_encrypted_posmap(svol); + if (err) + return err; + + /* Decrypt in place */ + err = vvz_crypt_blocks_vm(svol->tfm, svol->posmap, svol->posmap, + svol->sdev->posmap_size_sectors >> VVZ_BLOCK_SHIFT, + VVZ_POSMAP_START_SECTOR(svol) >> VVZ_BLOCK_SHIFT, + READ); + if (err) + return err; + + /* Deserialise and sanitise as you go */ + if (mutex_lock_interruptible(&sdev->slices_lock)) + return -ERESTARTSYS; + err = _deserialise_and_sanitise_posmap(svol); + mutex_unlock(&sdev->slices_lock); + if (err) + return err; + + return 0; +} + diff --git a/dm-vvz/posmap.h b/dm-vvz/posmap.h deleted file mode 100644 index df6c3a3..0000000 --- a/dm-vvz/posmap.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _VVZ_POSMAP_H_ -#define _VVZ_POSMAP_H_ - - -#include "volume.h" - - -#define VVZ_POSMAP_INVALID 0xFFFFFFFF -/* Starting sector of position map */ -#define VVZ_POSMAP_START_SECTOR(sv) \ - (VVZ_BLOCK_SCALE * (1 + VVZ_DEV_MAX_VOLUMES) + \ - (sv)->vol_idx * (sv)->sd->posmap_size_sectors) - - -/* At volume creation */ -int vvz_load_posmap(struct vvz_volume *sv); -/* On FLUSH request */ -int vvz_store_posmap(struct vvz_volume *sv); - -/* Returns INVALID (in *psi) if mapping does not exist */ -int vvz_get_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi); -/* Does not persist mapping on disk (only done on FLUSH requests) */ -int vvz_create_slice_mapping(struct vvz_volume *sv, u32 lsi, u32 *psi); - - -#endif /* _VVZ_POSMAP_H_ */ diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 9461493..2b8f844 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -238,7 +238,7 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) { - /* TODO: don't really know what to put here */ + // Currently, we only handle one block at a time limits->logical_block_size = VVZ_BLOCK_SIZE; limits->physical_block_size = VVZ_BLOCK_SIZE; limits->io_min = VVZ_BLOCK_SIZE; diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 6241b77..24048c0 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -24,7 +24,6 @@ #ifndef _VVZ_H #define _VVZ_H - #include #include #include @@ -77,7 +76,7 @@ struct vvz_device struct completion kobj_released; /* Resource sharing */ - struct bio_set bs; + struct bio_set bioset; struct dm_io_client *io_client; struct workqueue_struct *wq; }; @@ -114,6 +113,18 @@ struct vvz_io }; +/* + *---------------------------- + * Macros + *---------------------------- + */ + +/* Starting sector of position map */ +#define VVZ_POSMAP_START_SECTOR(svol) \ + (VVZ_BLOCK_SCALE * (1 + VVZ_DEV_MAX_VOLUMES) + \ + (svol)->vol_idx * (svol)->sdev->posmap_size_sectors) + + /* *---------------------------- * Global variables @@ -152,5 +163,12 @@ void vvz_sysfs_unregister_volume(struct vvz_volume *svol); void vvz_read_work_fn(struct work_struct *work); void vvz_write_work_fn(struct work_struct *work); +/* Position map */ +int vvz_load_and_sanitise_posmap(struct vvz_volume *svol); +int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *psi); + +/* Crypto */ +int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, + u64 num_blocks, u64 first_pblk_num, int rw); #endif /* _VVZ_H */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index b2bfe0c..24a9265 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -50,12 +50,17 @@ /* XTS requires doubling the key size */ #define VVZ_XTS_KEYLEN 64 /* bytes */ +/* The IV is the right-0-padded LE physical block number */ +#define VVZ_XTS_IVLEN 16 /* bytes */ #define VVZ_DEV_MAX_VOLUMES 15 #define VVZ_MAX_DEVS 1024 +#define VVZ_POSMAP_INVALID 0xFFFFFFFF + + /* Sysfs entries under /sys/module/dm_vvz/ */ #define VVZ_SYSFS_BDEVS "bdevs" #define VVZ_SYSFS_DEVID "next_dev_id" From 5cbdbbb614c4f8535efea9fb29def577b1646447 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 20 Jan 2024 12:43:35 +0100 Subject: [PATCH 36/75] fix posmap.c --- dm-vvz/posmap.c | 64 ++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index e5ca102..4fb2111 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -21,6 +21,8 @@ * If not, see . */ +#include + #include "vvz.h" @@ -31,30 +33,7 @@ */ /** - * Grab the specified PSI in the device: mark as occupied, decrease the number - * of free slices, advance the occupation counter. This specific algorithm, - * that never wraps @prmslices_octr around, only works because slices are never - * freed up. - * Sanity checks to be performed by the caller. - * - * MUTEX: @sdev->slices_lock must be held. - */ -static void _grab_psi(struct vvz_device *sdev, u32 psi) -{ - u32 i; - - sdev->slices_ofld[*psi] = true; - sdev->nr_free_slices--; - - /* Preserve the invariant: @prmslices_octr must point to a free slice */ - for (i = sdev->prmslices_octr; - i < sdev->tot_slices && sdev->slices_ofld[i]; - i++); - sdev->prmslices_octr = i; -} - -/** - * Return the next free PSI in the device's shuffled array, but don't modify + * Return the next free PSI in the device's shuffled array, without modifying * the device state. * * MUTEX: @sdev->slices_lock must be held. @@ -85,10 +64,20 @@ static int peek_next_free_psi(struct vvz_device *sdev, u32 *psi) */ static void _create_local_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 psi) { + struct vvz_device *sdev = svol->sdev; + u32 i; + /* Grab it from the device */ - _grab_psi(svol->sdev, psi); + sdev->slices_ofld[psi] = true; + sdev->nr_free_slices--; + // Preserve the invariant: @prmslices_octr must point to a free slice + for (i = sdev->prmslices_octr; + i < sdev->tot_slices && sdev->slices_ofld[i]; + i++); + sdev->prmslices_octr = i; + /* Insert in the volume */ - svol->posmap[lsi] = *psi; + svol->posmap[lsi] = psi; svol->nr_mapped_slices++; return; @@ -115,15 +104,13 @@ static void _delete_local_slice_mapping(struct vvz_volume *svol, u32 lsi) } /** - * Synchronously store (and flush) the posmap block containing the given LSI. + * Synchronously store (and flush) the given posmap block * * MUTEX: @svol->posmap_lock must be held, except under volume ctor. */ -static int store_posmap_block(struct vvz_volume *svol, u32 lsi) +static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) { struct vvz_device *sdev = svol->sdev; - u32 posmap_block_num = lsi / VVZ_POSMAP_ENTRIES_PER_BLOCK; - u32 first_lsi = posmap_block_num * VVZ_POSMAP_ENTRIES_PER_BLOCK; struct page *page; struct bio *bio; int err; @@ -155,12 +142,12 @@ static int store_posmap_block(struct vvz_volume *svol, u32 lsi) /* Serialise posmap block onto the page */ void *page_ptr = kmap_local_page(page); - u32 lsi_iter; - for (lsi_iter = first_lsi; - lsi_iter < first_lsi + VVZ_POSMAP_ENTRIES_PER_BLOCK; - lsi_iter++) { - u32 psi = svol->posmap[lsi_iter]; - __be32 *be_psi = (__be32*) (page_ptr + (lsi_iter * sizeof(__be32))); + u32 first_lsi = posmap_block_num * VVZ_POSMAP_ENTRIES_PER_BLOCK; + u32 last_lsi = min(first_lsi + VVZ_POSMAP_ENTRIES_PER_BLOCK, sdev->tot_slices); + u32 lsi; + for (lsi = first_lsi; lsi < last_lsi; lsi++) { + u32 psi = svol->posmap[lsi]; + __be32 *be_psi = (__be32*) (page_ptr + (lsi * sizeof(__be32))); *be_psi = cpu_to_be32(psi); } kunmap_local(page_ptr); @@ -175,6 +162,7 @@ static int store_posmap_block(struct vvz_volume *svol, u32 lsi) /* Submit */ err = submit_bio_wait(bio); + if (err) DMERR("Could not complete posmap block bio; error %d", err); bad_encrypt: @@ -305,8 +293,8 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) /* Only check dirty bit at the end of the posmap block */ if (posmap_block_dirty && - ( ((lsi + 1) % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) || - (lsi == sdev->tot_slices) )) { + (((lsi+1) % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) || + ((lsi+1) == sdev->tot_slices))) { err = store_posmap_block(svol, lsi); if (err) return err; From cc3fcf6a7b6ad5620b44f344cda4b7dd22dd1d98 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 20 Jan 2024 13:14:03 +0100 Subject: [PATCH 37/75] fix posmap.c and update volume.c --- dm-vvz/device.c | 12 +++++------- dm-vvz/posmap.c | 5 ++--- dm-vvz/volume.c | 8 +++++++- dm-vvz/vvz.c | 2 +- dm-vvz/vvz.h | 2 ++ 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 3681fff..46d68d2 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "vvz.h" @@ -34,15 +35,11 @@ /* Fisher-Yates shuffle */ static void fisheryates_u32(u32 *v, u32 len) { - u32 i, j, tmp; + u32 i, j; for (i = len-1; i >= 1; i--) { j = get_random_u32_below(i+1); - - /* Swap v[i] and v[j] */ - tmp = v[i]; - v[i] = v[j]; - v[j] = tmp; + swap(v[i], v[j]); } return; @@ -110,7 +107,8 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) } /* Workqueue */ - sdev->wq = alloc_workqueue("vvz_%s", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->dm_dev->name); + sdev->wq = alloc_workqueue("vvz_%s", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, + 0, sdev->dm_dev->name); if (!sdev->wq) { err = -ENOMEM; DMERR("Could not allocate workqueue"); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 4fb2111..62cd007 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -22,7 +22,6 @@ */ #include - #include "vvz.h" @@ -209,7 +208,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p mutex_unlock(&sdev->slices_lock); /* Write posmap block to disk */ - err = store_posmap_block(svol, lsi); + err = store_posmap_block(svol, lsi / VVZ_POSMAP_ENTRIES_PER_BLOCK); if (err) { DMERR("Could not store posmap block; error %d", err); _delete_local_slice_mapping(svol, lsi); @@ -295,7 +294,7 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) if (posmap_block_dirty && (((lsi+1) % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) || ((lsi+1) == sdev->tot_slices))) { - err = store_posmap_block(svol, lsi); + err = store_posmap_block(svol, lsi / VVZ_POSMAP_ENTRIES_PER_BLOCK); if (err) return err; } diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 110a7aa..51ad740 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -63,7 +63,12 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e goto bad_posmap_alloc; } svol->nr_mapped_slices = 0; - // TODO load posmap (must have crypto tfm initialised) + /* Load from disk */ + err = vvz_load_and_sanitise_posmap(svol); + if (err) { + DMERR("Could not load position map from disk; error %d", err); + goto bad_posmap_load; + } /* Register to sysfs, once initialised */ err = vvz_sysfs_register_volume(svol); @@ -76,6 +81,7 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e bad_sysfs: +bad_posmap_load: vfree(svol->posmap); bad_posmap_alloc: bad_tfm_setkey: diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 2b8f844..0fbdbaa 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -98,7 +98,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) * argv[1]: path to underlying physical device * argv[2]: volume index within the device * argv[3]: number of 1-MiB slices in the underlying device - * argv[4]: 64-byte encryption key (hex-encoded) + * argv[4]: 64-byte encryption key (hex-encoded, so 128 chars) */ if (argc != 5) { ti->error = "Invalid argument count"; diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 24048c0..0ccb72f 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -170,5 +170,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p /* Crypto */ int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, u64 num_blocks, u64 first_pblk_num, int rw); +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw); #endif /* _VVZ_H */ From 30a303a90f488d7983c6f2b66d1a556096cacf33 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 20 Jan 2024 13:22:54 +0100 Subject: [PATCH 38/75] fix compilation errors --- dm-vvz/Kbuild | 2 +- dm-vvz/crypto.c | 1 + dm-vvz/device.c | 4 ++-- dm-vvz/posmap.c | 23 ++++++++++------------- dm-vvz/vvz.h | 3 --- dm-vvz/vvz_constants.h | 4 +++- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/dm-vvz/Kbuild b/dm-vvz/Kbuild index d9ab37a..1ed4b30 100644 --- a/dm-vvz/Kbuild +++ b/dm-vvz/Kbuild @@ -25,7 +25,7 @@ MODULE_NAME := dm_vvz obj-m := $(MODULE_NAME).o -OBJ_LIST := vvz.o device.o volume.o sysfs.o +OBJ_LIST := vvz.o device.o volume.o sysfs.o crypto.o posmap.o read.o write.o $(MODULE_NAME)-y += $(OBJ_LIST) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index cdf0528..f318340 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -23,6 +23,7 @@ #include #include +#include #include "vvz_constants.h" diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 46d68d2..2320d93 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -65,7 +65,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) sdev->nr_free_slices = tot_slices; /* Enough posmap blocks to fit all the entries */ sdev->posmap_size_sectors = VVZ_BLOCK_SCALE * - DIV_ROUND_UP(tot_slices, VVZ_POSMAP_ENTRIES_PER_BLOCK); + DIV_ROUND_UP(tot_slices, VVZ_PSIS_PER_BLOCK); /* DMB + VMBs + PosMaps */ sdev->dev_header_size_sectors = VVZ_BLOCK_SCALE + (VVZ_DEV_MAX_VOLUMES * VVZ_BLOCK_SCALE) + @@ -130,7 +130,7 @@ bad_sysfs: bad_wq: dm_io_client_destroy(sdev->io_client); bad_dmio_client: - bioset_exit(sdev->bioset); + bioset_exit(&sdev->bioset); bad_bioset: vfree(sdev->prmslices); bad_prmslices: diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 62cd007..fe2785d 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -39,8 +39,6 @@ */ static int peek_next_free_psi(struct vvz_device *sdev, u32 *psi) { - int err; - if (unlikely(!sdev->nr_free_slices)) return -ENOSPC; if (unlikely(sdev->prmslices_octr >= sdev->tot_slices)) @@ -91,7 +89,7 @@ static void _create_local_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 ps static void _delete_local_slice_mapping(struct vvz_volume *svol, u32 lsi) { /* Delete mapping in the volume */ - svol->posmap[lsi] = VVZ_POSMAP_INVALID; + svol->posmap[lsi] = VVZ_PSI_INVALID; svol->nr_mapped_slices--; /* Don't do anything in the device though, leave it there: we don't yet @@ -141,8 +139,8 @@ static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) /* Serialise posmap block onto the page */ void *page_ptr = kmap_local_page(page); - u32 first_lsi = posmap_block_num * VVZ_POSMAP_ENTRIES_PER_BLOCK; - u32 last_lsi = min(first_lsi + VVZ_POSMAP_ENTRIES_PER_BLOCK, sdev->tot_slices); + u32 first_lsi = posmap_block_num * VVZ_PSIS_PER_BLOCK; + u32 last_lsi = min(first_lsi + VVZ_PSIS_PER_BLOCK, sdev->tot_slices); u32 lsi; for (lsi = first_lsi; lsi < last_lsi; lsi++) { u32 psi = svol->posmap[lsi]; @@ -193,7 +191,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p if(unlikely(lsi >= svol->sdev->tot_slices)) return -EINVAL; /* Check mapping not existent TODO redundant? */ - if (unlikely(svol->posmap[lsi] != VVZ_POSMAP_INVALID)) + if (unlikely(svol->posmap[lsi] != VVZ_PSI_INVALID)) return -EINVAL; /* Create mapping */ @@ -208,7 +206,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p mutex_unlock(&sdev->slices_lock); /* Write posmap block to disk */ - err = store_posmap_block(svol, lsi / VVZ_POSMAP_ENTRIES_PER_BLOCK); + err = store_posmap_block(svol, lsi / VVZ_PSIS_PER_BLOCK); if (err) { DMERR("Could not store posmap block; error %d", err); _delete_local_slice_mapping(svol, lsi); @@ -265,7 +263,7 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) for (lsi = 0; lsi < sdev->tot_slices; lsi++) { /* Reset dirty bit at the start of every posmap block */ - if (lsi % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) + if (lsi % VVZ_PSIS_PER_BLOCK == 0) posmap_block_dirty = false; /* De-serialise posmap entry */ @@ -273,14 +271,14 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) u32 psi = be32_to_cpu(*be_psi); /* If LSI unmapped, just continue */ - if (psi == VVZ_POSMAP_INVALID) { + if (psi == VVZ_PSI_INVALID) { svol->posmap[lsi] = psi; continue; } /* If PSI already taken, sample a new one */ if (sdev->slices_ofld[psi]) { - DMWARN("Corruption of volume %d: LSI %u was evicted from PSI %u", + DMWARN("Corruption of volume %lu: LSI %u was evicted from PSI %u", svol->vol_idx, lsi, psi); err = peek_next_free_psi(sdev, &psi); if (err) @@ -292,9 +290,9 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) /* Only check dirty bit at the end of the posmap block */ if (posmap_block_dirty && - (((lsi+1) % VVZ_POSMAP_ENTRIES_PER_BLOCK == 0) || + (((lsi+1) % VVZ_PSIS_PER_BLOCK == 0) || ((lsi+1) == sdev->tot_slices))) { - err = store_posmap_block(svol, lsi / VVZ_POSMAP_ENTRIES_PER_BLOCK); + err = store_posmap_block(svol, lsi / VVZ_PSIS_PER_BLOCK); if (err) return err; } @@ -316,7 +314,6 @@ int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) { int err; struct vvz_device *sdev = svol->sdev; - u32 lsi; /* Read raw posmap from disk */ err = read_encrypted_posmap(svol); diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 0ccb72f..f1799db 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -39,9 +39,6 @@ #define DM_MSG_PREFIX "vvz" -/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ -#define VVZ_POSMAP_ENTRIES_PER_BLOCK 1024 - /* *---------------------------- diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 24a9265..310bbd0 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -58,7 +58,9 @@ #define VVZ_MAX_DEVS 1024 -#define VVZ_POSMAP_INVALID 0xFFFFFFFF +#define VVZ_PSI_INVALID 0xFFFFFFFF +/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ +#define VVZ_PSIS_PER_BLOCK 1024 /* Sysfs entries under /sys/module/dm_vvz/ */ From 221d1337ee9162db3ee53b36b3977c769a38f291 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 20 Jan 2024 13:40:21 +0100 Subject: [PATCH 39/75] fix bug in posmap.c --- dm-vvz/posmap.c | 10 ++++++---- dm-vvz/vvz.h | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index fe2785d..03e194a 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -206,7 +206,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p mutex_unlock(&sdev->slices_lock); /* Write posmap block to disk */ - err = store_posmap_block(svol, lsi / VVZ_PSIS_PER_BLOCK); + err = store_posmap_block(svol, lsi/VVZ_PSIS_PER_BLOCK); if (err) { DMERR("Could not store posmap block; error %d", err); _delete_local_slice_mapping(svol, lsi); @@ -270,10 +270,10 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) __be32 *be_psi = (__be32*) (posmap_ptr + (lsi * sizeof(__be32))); u32 psi = be32_to_cpu(*be_psi); - /* If LSI unmapped, just continue */ + /* If LSI unmapped, skip mapping creation */ if (psi == VVZ_PSI_INVALID) { svol->posmap[lsi] = psi; - continue; + goto skip_create_mapping; } /* If PSI already taken, sample a new one */ @@ -288,11 +288,13 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) /* Either way, create the mapping locally */ _create_local_slice_mapping(svol, lsi, psi); +skip_create_mapping: + /* Only check dirty bit at the end of the posmap block */ if (posmap_block_dirty && (((lsi+1) % VVZ_PSIS_PER_BLOCK == 0) || ((lsi+1) == sdev->tot_slices))) { - err = store_posmap_block(svol, lsi / VVZ_PSIS_PER_BLOCK); + err = store_posmap_block(svol, lsi/VVZ_PSIS_PER_BLOCK); if (err) return err; } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index f1799db..dae2f87 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -46,8 +46,6 @@ *---------------------------- */ -struct vvz_volume; - struct vvz_device { /* Shufflecake-unique device ID */ From f2d3abd155dc792964aa022f308b3ec5e5d2f5bd Mon Sep 17 00:00:00 2001 From: = Date: Mon, 4 Mar 2024 22:11:21 +0100 Subject: [PATCH 40/75] Implement read --- dm-vvz/crypto.c | 8 +-- dm-vvz/device.c | 29 ++++++--- dm-vvz/posmap.c | 2 +- dm-vvz/read.c | 129 +++++++++++++++++++++++++++++++++++++++++ dm-vvz/vvz.c | 7 ++- dm-vvz/vvz.h | 18 +++++- dm-vvz/vvz_constants.h | 4 +- dm-vvz/write.c | 31 ++++++++++ 8 files changed, 209 insertions(+), 19 deletions(-) create mode 100644 dm-vvz/read.c create mode 100644 dm-vvz/write.c diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index f318340..909cb50 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -67,16 +67,16 @@ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, } /* Encrypt-decrypt a single block (memory buffer is a page) */ -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw) +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, unsigned src_off, + struct page *dst_page, unsigned dst_off, u64 pblk_num, int rw) { struct scatterlist dst, src; /* We assume PAGE_SIZE >= VVZ_BLOCK_SIZE TODO better document this */ sg_init_table(&src, 1); - sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); + sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, src_off); sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); + sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, dst_off); return crypt_sg(tfm, &src, &dst, pblk_num, rw); } diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 2320d93..cff41dc 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -106,13 +106,23 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) goto bad_dmio_client; } - /* Workqueue */ - sdev->wq = alloc_workqueue("vvz_%s", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, + /* I/O workqueue */ + sdev->io_queue = alloc_workqueue("vvz_%s_io", + WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->dm_dev->name); - if (!sdev->wq) { + if (!sdev->io_queue) { err = -ENOMEM; - DMERR("Could not allocate workqueue"); - goto bad_wq; + DMERR("Could not allocate I/O workqueue"); + goto bad_io_wq; + } + /* Decryption workqueue */ + sdev->crypt_queue = alloc_workqueue("vvz_%s_crypt", + WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, + 0, sdev->dm_dev->name); + if (!sdev->crypt_queue) { + err = -ENOMEM; + DMERR("Could not allocate decryption workqueue"); + goto bad_crypt_wq; } /* Register to sysfs, once initialised */ @@ -126,8 +136,10 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) bad_sysfs: - destroy_workqueue(sdev->wq); -bad_wq: + destroy_workqueue(sdev->crypt_queue); +bad_crypt_wq: + destroy_workqueue(sdev->io_queue); +bad_io_wq: dm_io_client_destroy(sdev->io_client); bad_dmio_client: bioset_exit(&sdev->bioset); @@ -144,7 +156,8 @@ bad_ofld: void vvz_dev_destroy(struct vvz_device *sdev) { vvz_sysfs_unregister_device(sdev); - destroy_workqueue(sdev->wq); + destroy_workqueue(sdev->crypt_queue); + destroy_workqueue(sdev->io_queue); dm_io_client_destroy(sdev->io_client); bioset_exit(&sdev->bioset); vfree(sdev->prmslices); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 03e194a..acb2c96 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -150,7 +150,7 @@ static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) kunmap_local(page_ptr); /* Encrypt the block in place */ - err = vvz_crypt_block_page(svol->tfm, page, page, + err = vvz_crypt_block_page(svol->tfm, page, 0, page, 0, bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); if (err) { DMERR("Could not encrypt posmap block; error %d", err); diff --git a/dm-vvz/read.c b/dm-vvz/read.c new file mode 100644 index 0000000..b86e452 --- /dev/null +++ b/dm-vvz/read.c @@ -0,0 +1,129 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "vvz.h" + + +static void vvz_read_endio(struct bio *phys_bio); +static void vvz_decrypt_work_fn(struct work_struct *work); + + +void vvz_read_work_fn(struct work_struct *work) +{ + struct vvz_io *sio = container_of(work, struct vvz_io, work); + struct vvz_volume *svol = sio->svol; + struct vvz_device *sdev = svol->sdev; + struct bio *orig_bio = sio->orig_bio; + struct bio *phys_bio; + u32 lsi = sio->lsi; + u32 block_offset = sio->block_offset; + u32 psi; + + /* Read position map */ + if (mutex_lock_interruptible(&svol->posmap_lock)) { + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + psi = svol->posmap[lsi]; + mutex_unlock(&svol->posmap_lock); + + /* If LSI is unmapped, short-circuit and return all zeros */ + if (psi == VVZ_PSI_INVALID) { + zero_fill_bio(orig_bio); + orig_bio->bi_status = BLK_STS_OK; + goto endio; + } + + /* Shallow-copy the bio and submit it (different bi_endio). + We can shallow-copy because we don't need to own the pages, + we can decrypt in place. */ + + /* Shallow copy */ + phys_bio = bio_alloc_clone(sdev->dm_dev->bdev, orig_bio, GFP_NOIO, &sdev->bioset); + if (!phys_bio) { + DMERR("Could not clone original bio"); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + /* Insert in the I/O struct */ + sio->phys_bio = phys_bio; + + /* Remap sector */ + phys_bio->bi_iter.bi_sector = VVZ_PHYS_BIO_SECTOR(sdev, psi, block_offset); + /* Set fields for the endio */ + phys_bio->bi_private = sio; + phys_bio->bi_end_io = vvz_read_endio; + /* Submit */ + dm_submit_bio_remap(orig_bio, phys_bio); + + return; + + +endio: + bio_endio(orig_bio); + return; +} + + +static void vvz_read_endio(struct bio *phys_bio) +{ + struct vvz_io *sio = phys_bio->bi_private; + + /* Can't decrypt here in ISR: submit to decryption workqueue. + * Can reuse the same work item, though, since it was popped out of the + * io_queue already */ + INIT_WORK(&sio->work, vvz_decrypt_work_fn); + queue_work(sio->svol->sdev->crypt_queue, &sio->work); +} + + +static void vvz_decrypt_work_fn(struct work_struct *work) +{ + struct vvz_io *sio = container_of(work, struct vvz_io, work); + struct vvz_volume *svol = sio->svol; + struct bio *orig_bio = sio->orig_bio; + struct bio *phys_bio = sio->phys_bio; + struct bio_vec bvl = bio_iovec(orig_bio); + blk_status_t status; + int err; + + /* Decrypt page in-place */ + err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_offset, bvl.bv_page, + bvl.bv_offset, phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, READ); + if (err) { + DMERR("Could not decrypt bio; error %d", err); + status = BLK_STS_IOERR; + goto endio; + } + + /* Advance original bio by one block */ + bio_advance(orig_bio, VVZ_BLOCK_SIZE); + +endio: + orig_bio->bi_status = status; + bio_endio(orig_bio); + /* Free the physical bio */ + bio_put(phys_bio); + + return; +} diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 0fbdbaa..9c0d00c 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -218,19 +218,22 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) { struct vvz_io *sio = dm_per_bio_data(bio, sizeof(struct vvz_io)); struct vvz_volume *svol = ti->private; + sector_t lblk_num = bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT; // TODO check flush /* Set fields */ - sio->orig_bio = bio; sio->svol = svol; + sio->orig_bio = bio; + sio->lsi = lblk_num >> VVZ_SLICE_SHIFT; + sio->block_offset = lblk_num & GENMASK(VVZ_SLICE_SHIFT - 1, 0); /* Enqueue */ if (bio_data_dir(bio) == READ) INIT_WORK(&sio->work, vvz_read_work_fn); else INIT_WORK(&sio->work, vvz_write_work_fn); - queue_work(svol->sdev->wq, &sio->work); + queue_work(svol->sdev->io_queue, &sio->work); return DM_MAPIO_SUBMITTED; } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index dae2f87..c8e3dc8 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -73,7 +73,8 @@ struct vvz_device /* Resource sharing */ struct bio_set bioset; struct dm_io_client *io_client; - struct workqueue_struct *wq; + struct workqueue_struct *io_queue; + struct workqueue_struct *crypt_queue; }; struct vvz_volume @@ -102,7 +103,11 @@ struct vvz_volume struct vvz_io { struct vvz_volume *svol; + struct bio *orig_bio; + struct bio *phys_bio; + u32 lsi; + u32 block_offset; struct work_struct work; }; @@ -120,6 +125,13 @@ struct vvz_io (svol)->vol_idx * (svol)->sdev->posmap_size_sectors) +/* Physical sector of a remapped bio */ +#define VVZ_PHYS_BIO_SECTOR(sdev, psi, off) ( \ + (sdev)->dev_header_size_sectors + ( \ + ((psi << VVZ_SLICE_SHIFT) + off) << VVZ_BLOCK_SHIFT \ + ) \ +) + /* *---------------------------- * Global variables @@ -165,7 +177,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p /* Crypto */ int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, u64 num_blocks, u64 first_pblk_num, int rw); -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw); +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, unsigned src_off, + struct page *dst_page, unsigned dst_off, u64 pblk_num, int rw); #endif /* _VVZ_H */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 310bbd0..16b1f73 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -45,7 +45,9 @@ #define VVZ_BLOCK_SIZE 4096 /* bytes */ #define VVZ_BLOCK_SHIFT 3 -#define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* sectors in a block */ +#define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* 8 sectors in a block */ +#define VVZ_SLICE_SHIFT 8 +#define VVZ_SLICE_SCALE (1 << VVZ_SLICE_SHIFT) /* 256 blocks in a slice */ /* XTS requires doubling the key size */ diff --git a/dm-vvz/write.c b/dm-vvz/write.c new file mode 100644 index 0000000..cefd0e6 --- /dev/null +++ b/dm-vvz/write.c @@ -0,0 +1,31 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "vvz.h" + + +void vvz_write_work_fn(struct work_struct *work) +{ + // TODO stub + return; +} From ad00a4b3fb50c0678b9c4fd5addd51fdc885eca0 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 5 Mar 2024 23:40:52 +0100 Subject: [PATCH 41/75] Implement write --- dm-vvz/read.c | 19 ++++++--- dm-vvz/write.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 6 deletions(-) diff --git a/dm-vvz/read.c b/dm-vvz/read.c index b86e452..8066f79 100644 --- a/dm-vvz/read.c +++ b/dm-vvz/read.c @@ -28,6 +28,7 @@ static void vvz_read_endio(struct bio *phys_bio); static void vvz_decrypt_work_fn(struct work_struct *work); +/* Landing here from ->map() through the io_queue */ void vvz_read_work_fn(struct work_struct *work) { struct vvz_io *sio = container_of(work, struct vvz_io, work); @@ -85,18 +86,20 @@ endio: } +/* ISR for the phys_bio */ static void vvz_read_endio(struct bio *phys_bio) { struct vvz_io *sio = phys_bio->bi_private; /* Can't decrypt here in ISR: submit to decryption workqueue. * Can reuse the same work item, though, since it was popped out of the - * io_queue already */ + * io_queue already */ INIT_WORK(&sio->work, vvz_decrypt_work_fn); queue_work(sio->svol->sdev->crypt_queue, &sio->work); } +/* Decrypt and endio */ static void vvz_decrypt_work_fn(struct work_struct *work) { struct vvz_io *sio = container_of(work, struct vvz_io, work); @@ -104,26 +107,32 @@ static void vvz_decrypt_work_fn(struct work_struct *work) struct bio *orig_bio = sio->orig_bio; struct bio *phys_bio = sio->phys_bio; struct bio_vec bvl = bio_iovec(orig_bio); - blk_status_t status; int err; + /* If physical bio failed, then fail-fast */ + if (phys_bio->bi_status != BLK_STS_OK) { + orig_bio->bi_status = phys_bio->bi_status; + goto endio; + } + /* Decrypt page in-place */ err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_offset, bvl.bv_page, bvl.bv_offset, phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, READ); if (err) { DMERR("Could not decrypt bio; error %d", err); - status = BLK_STS_IOERR; + orig_bio->bi_status = BLK_STS_IOERR; goto endio; } /* Advance original bio by one block */ bio_advance(orig_bio, VVZ_BLOCK_SIZE); + orig_bio->bi_status = BLK_STS_OK; endio: - orig_bio->bi_status = status; - bio_endio(orig_bio); /* Free the physical bio */ bio_put(phys_bio); + /* End original bio */ + bio_endio(orig_bio); return; } diff --git a/dm-vvz/write.c b/dm-vvz/write.c index cefd0e6..6bccc7c 100644 --- a/dm-vvz/write.c +++ b/dm-vvz/write.c @@ -24,8 +24,113 @@ #include "vvz.h" +static void vvz_write_endio(struct bio *phys_bio); + + void vvz_write_work_fn(struct work_struct *work) { - // TODO stub + struct vvz_io *sio = container_of(work, struct vvz_io, work); + struct vvz_volume *svol = sio->svol; + struct vvz_device *sdev = svol->sdev; + struct bio *orig_bio = sio->orig_bio; + struct bio_vec bvl = bio_iovec(orig_bio); + struct bio *phys_bio; + struct page *page; + u32 lsi = sio->lsi; + u32 block_offset = sio->block_offset; + u32 psi; + int err; + + /* Read existing mapping, or create new one */ + if (mutex_lock_interruptible(&svol->posmap_lock)) { + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + psi = svol->posmap[lsi]; + /* If LSI unmapped, create new mapping, while holding the lock */ + if (psi == VVZ_PSI_INVALID) { + err = vvz_create_persistent_slice_mapping(svol, lsi, &psi); + if (err){ + DMERR("Could not create slice mapping; error %d", err); + mutex_unlock(&svol->posmap_lock); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + } + mutex_unlock(&svol->posmap_lock); + + /* Allocate physical bio */ + phys_bio = bio_alloc_bioset(sdev->dm_dev->bdev, 1, orig_bio->bi_opf, + GFP_NOIO, &sdev->bioset); + if (!phys_bio) { + DMERR("Could not allocate physical bio"); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + /* Insert in the I/O struct */ + sio->phys_bio = phys_bio; + + /* Physical bio needs its own page */ + page = alloc_pages(GFP_NOIO, 0); + if (!page) { + DMERR("Could not allocate page for physical bio"); + orig_bio->bi_status = BLK_STS_IOERR; + goto bad_alloc_page; + } + + /* Remap sector */ + phys_bio->bi_iter.bi_sector = VVZ_PHYS_BIO_SECTOR(sdev, psi, block_offset); + /* Encrypt */ + err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_offset, page, 0, + phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); + if (err) { + DMERR("Could not encrypt bio; error %d", err); + orig_bio->bi_status = BLK_STS_IOERR; + goto bad_encrypt; + } + + /* Add page to bio */ + __bio_add_page(phys_bio, page, VVZ_BLOCK_SIZE, 0); + /* Set fields for the endio */ + phys_bio->bi_private = sio; + phys_bio->bi_end_io = vvz_write_endio; + /* Submit */ + dm_submit_bio_remap(orig_bio, phys_bio); + + return; + + +bad_encrypt: + __free_page(page); +bad_alloc_page: + bio_put(phys_bio); +endio: + bio_endio(orig_bio); return; } + +static void vvz_write_endio(struct bio *phys_bio) +{ + struct vvz_io *sio = phys_bio->bi_private; + struct bio *orig_bio = sio->orig_bio; + + /* If physical bio failed, then fail-fast */ + if (phys_bio->bi_status != BLK_STS_OK) { + orig_bio->bi_status = phys_bio->bi_status; + goto endio; + } + + /* Advance original bio by one block */ + bio_advance(orig_bio, VVZ_BLOCK_SIZE); + orig_bio->bi_status = BLK_STS_OK; + +endio: + /* Free the physical bio and its page */ + bio_free_pages(phys_bio); + bio_put(phys_bio); + /* End original bio */ + bio_endio(orig_bio); + + return; +} + From 8ac7b58e4017c174b389bd007880b6e0a3f33aa4 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 29 Mar 2024 23:32:09 +0100 Subject: [PATCH 42/75] Finish dm-vvz --- dm-vvz/crypto.c | 11 ++++++----- dm-vvz/posmap.c | 2 +- dm-vvz/read.c | 4 ++-- dm-vvz/vvz.c | 34 +++++++++++++++++++++++++++++++--- dm-vvz/vvz.h | 4 ++-- dm-vvz/write.c | 2 +- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index 909cb50..be1e687 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -67,16 +67,17 @@ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, } /* Encrypt-decrypt a single block (memory buffer is a page) */ -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, unsigned src_off, - struct page *dst_page, unsigned dst_off, u64 pblk_num, int rw) +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw) { struct scatterlist dst, src; - /* We assume PAGE_SIZE >= VVZ_BLOCK_SIZE TODO better document this */ + /* We assume PAGE_SIZE == VVZ_BLOCK_SIZE */ + /* And orig_bio to start at offset 0 within the page */ sg_init_table(&src, 1); - sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, src_off); + sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, dst_off); + sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); return crypt_sg(tfm, &src, &dst, pblk_num, rw); } diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index acb2c96..03e194a 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -150,7 +150,7 @@ static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) kunmap_local(page_ptr); /* Encrypt the block in place */ - err = vvz_crypt_block_page(svol->tfm, page, 0, page, 0, + err = vvz_crypt_block_page(svol->tfm, page, page, bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); if (err) { DMERR("Could not encrypt posmap block; error %d", err); diff --git a/dm-vvz/read.c b/dm-vvz/read.c index 8066f79..36f7761 100644 --- a/dm-vvz/read.c +++ b/dm-vvz/read.c @@ -116,8 +116,8 @@ static void vvz_decrypt_work_fn(struct work_struct *work) } /* Decrypt page in-place */ - err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_offset, bvl.bv_page, - bvl.bv_offset, phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, READ); + err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_page, + phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, READ); if (err) { DMERR("Could not decrypt bio; error %d", err); orig_bio->bi_status = BLK_STS_IOERR; diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 9c0d00c..4367d95 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -220,9 +220,29 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) struct vvz_volume *svol = ti->private; sector_t lblk_num = bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT; - // TODO check flush + /* Accept one block at a time TODO improve */ + if (unlikely(bio->bi_iter.bi_size > VVZ_BLOCK_SIZE)) + dm_accept_partial_bio(bio, VVZ_BLOCK_SCALE); + /* Only one segment, single page, starting at 0 TODO improve */ + if (unlikely(bio_segments(bio) > 1 || + bio_offset(bio) != 0)) { + DMWARN("Unaligned bio!"); + return DM_MAPIO_KILL; + } - /* Set fields */ + /* Flush requests are just passed down, since our position map is + * currently write-through, so we have no volatile cache */ + if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { + /* Has to be empty though */ + if (bio_sectors(bio)) { + DMWARN("Non-empty flush request!"); + return DM_MAPIO_KILL; + } + bio_set_dev(bio, svol->sdev->dm_dev->bdev); + return DM_MAPIO_REMAPPED; + } + + /* Init I/O struct */ sio->svol = svol; sio->orig_bio = bio; sio->lsi = lblk_num >> VVZ_SLICE_SHIFT; @@ -241,7 +261,7 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) { - // Currently, we only handle one block at a time + // Currently, we only handle one block at a time TODO improve limits->logical_block_size = VVZ_BLOCK_SIZE; limits->physical_block_size = VVZ_BLOCK_SIZE; limits->io_min = VVZ_BLOCK_SIZE; @@ -284,6 +304,13 @@ static int __init vvz_init(void) { int err; + /* For the moment, we assume PAGE_SIZE == VVZ_BLOCK_SIZE TODO improve */ + if (VVZ_BLOCK_SIZE != PAGE_SIZE) { + DMERR("Error, PAGE_SIZE != %d bytes not yet supported", VVZ_BLOCK_SIZE); + err = -ENOTRECOVERABLE; + goto bad_page_size; + } + vvz_alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*vvz_alldevs)); if (!vvz_alldevs) { DMERR("Could not allocate vvz_alldevs"); @@ -312,6 +339,7 @@ bad_register_target: bad_sysfs_init: vfree(vvz_alldevs); bad_alldevs_alloc: +bad_page_size: DMERR("not loaded"); return err; } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index c8e3dc8..a954761 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -177,7 +177,7 @@ int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *p /* Crypto */ int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, u64 num_blocks, u64 first_pblk_num, int rw); -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, unsigned src_off, - struct page *dst_page, unsigned dst_off, u64 pblk_num, int rw); +int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw); #endif /* _VVZ_H */ diff --git a/dm-vvz/write.c b/dm-vvz/write.c index 6bccc7c..79e5e7e 100644 --- a/dm-vvz/write.c +++ b/dm-vvz/write.c @@ -81,7 +81,7 @@ void vvz_write_work_fn(struct work_struct *work) /* Remap sector */ phys_bio->bi_iter.bi_sector = VVZ_PHYS_BIO_SECTOR(sdev, psi, block_offset); /* Encrypt */ - err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_offset, page, 0, + err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, page, phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); if (err) { DMERR("Could not encrypt bio; error %d", err); From ccc05bee51954e88a0fb380198ce5e073a4dc420 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 30 Mar 2024 00:08:41 +0100 Subject: [PATCH 43/75] Copy new version of userland tool from main --- vuvuzela-userland/.gitignore | 11 + vuvuzela-userland/Makefile | 131 ++++++ vuvuzela-userland/Makefile.sources | 49 ++ vuvuzela-userland/include/cli.h | 65 +++ vuvuzela-userland/include/commands.h | 113 +++++ vuvuzela-userland/include/header.h | 161 +++++++ vuvuzela-userland/include/operations.h | 84 ++++ vuvuzela-userland/include/sflc_constants.h | 1 + vuvuzela-userland/include/utils/crypto.h | 103 +++++ vuvuzela-userland/include/utils/disk.h | 107 +++++ vuvuzela-userland/include/utils/dm.h | 56 +++ vuvuzela-userland/include/utils/file.h | 36 ++ vuvuzela-userland/include/utils/input.h | 46 ++ vuvuzela-userland/include/utils/log.h | 136 ++++++ vuvuzela-userland/include/utils/math.h | 36 ++ vuvuzela-userland/include/utils/sflc.h | 89 ++++ vuvuzela-userland/include/utils/string.h | 39 ++ vuvuzela-userland/src/cli/changepwd.c | 112 +++++ vuvuzela-userland/src/cli/close.c | 74 +++ vuvuzela-userland/src/cli/dispatch.c | 245 ++++++++++ vuvuzela-userland/src/cli/init.c | 118 +++++ vuvuzela-userland/src/cli/open.c | 77 ++++ vuvuzela-userland/src/cli/testpwd.c | 87 ++++ vuvuzela-userland/src/commands/change_pwd.c | 58 +++ vuvuzela-userland/src/commands/close.c | 178 ++++++++ vuvuzela-userland/src/commands/init.c | 202 +++++++++ vuvuzela-userland/src/commands/open.c | 183 ++++++++ vuvuzela-userland/src/commands/test_pwd.c | 59 +++ .../src/header/device_master_block.c | 276 ++++++++++++ vuvuzela-userland/src/header/position_map.c | 134 ++++++ .../src/header/volume_master_block.c | 223 +++++++++ vuvuzela-userland/src/main.c | 44 ++ vuvuzela-userland/src/operations/devmapper.c | 111 +++++ vuvuzela-userland/src/operations/dmb.c | 167 +++++++ .../src/operations/volume_header.c | 165 +++++++ vuvuzela-userland/src/utils/crypto.c | 424 ++++++++++++++++++ vuvuzela-userland/src/utils/disk.c | 257 +++++++++++ vuvuzela-userland/src/utils/dm.c | 203 +++++++++ vuvuzela-userland/src/utils/file.c | 81 ++++ vuvuzela-userland/src/utils/input.c | 101 +++++ vuvuzela-userland/src/utils/string.c | 74 +++ .../test/crypto/test_aes256ctr.c | 178 ++++++++ .../test/crypto/test_aes256ctr.h | 85 ++++ .../test/crypto/test_aes256gcm.c | 160 +++++++ .../test/crypto/test_aes256gcm.h | 91 ++++ vuvuzela-userland/test/crypto/test_argon2id.c | 83 ++++ vuvuzela-userland/test/crypto/test_argon2id.h | 43 ++ vuvuzela-userland/test/main.c | 80 ++++ vuvuzela-userland/test/minunit.h | 10 + 49 files changed, 5646 insertions(+) create mode 100644 vuvuzela-userland/.gitignore create mode 100644 vuvuzela-userland/Makefile create mode 100644 vuvuzela-userland/Makefile.sources create mode 100644 vuvuzela-userland/include/cli.h create mode 100644 vuvuzela-userland/include/commands.h create mode 100644 vuvuzela-userland/include/header.h create mode 100644 vuvuzela-userland/include/operations.h create mode 120000 vuvuzela-userland/include/sflc_constants.h create mode 100644 vuvuzela-userland/include/utils/crypto.h create mode 100644 vuvuzela-userland/include/utils/disk.h create mode 100644 vuvuzela-userland/include/utils/dm.h create mode 100644 vuvuzela-userland/include/utils/file.h create mode 100644 vuvuzela-userland/include/utils/input.h create mode 100644 vuvuzela-userland/include/utils/log.h create mode 100644 vuvuzela-userland/include/utils/math.h create mode 100644 vuvuzela-userland/include/utils/sflc.h create mode 100644 vuvuzela-userland/include/utils/string.h create mode 100644 vuvuzela-userland/src/cli/changepwd.c create mode 100644 vuvuzela-userland/src/cli/close.c create mode 100644 vuvuzela-userland/src/cli/dispatch.c create mode 100644 vuvuzela-userland/src/cli/init.c create mode 100644 vuvuzela-userland/src/cli/open.c create mode 100644 vuvuzela-userland/src/cli/testpwd.c create mode 100644 vuvuzela-userland/src/commands/change_pwd.c create mode 100644 vuvuzela-userland/src/commands/close.c create mode 100644 vuvuzela-userland/src/commands/init.c create mode 100644 vuvuzela-userland/src/commands/open.c create mode 100644 vuvuzela-userland/src/commands/test_pwd.c create mode 100644 vuvuzela-userland/src/header/device_master_block.c create mode 100644 vuvuzela-userland/src/header/position_map.c create mode 100644 vuvuzela-userland/src/header/volume_master_block.c create mode 100644 vuvuzela-userland/src/main.c create mode 100644 vuvuzela-userland/src/operations/devmapper.c create mode 100644 vuvuzela-userland/src/operations/dmb.c create mode 100644 vuvuzela-userland/src/operations/volume_header.c create mode 100644 vuvuzela-userland/src/utils/crypto.c create mode 100644 vuvuzela-userland/src/utils/disk.c create mode 100644 vuvuzela-userland/src/utils/dm.c create mode 100644 vuvuzela-userland/src/utils/file.c create mode 100644 vuvuzela-userland/src/utils/input.c create mode 100644 vuvuzela-userland/src/utils/string.c create mode 100644 vuvuzela-userland/test/crypto/test_aes256ctr.c create mode 100644 vuvuzela-userland/test/crypto/test_aes256ctr.h create mode 100644 vuvuzela-userland/test/crypto/test_aes256gcm.c create mode 100644 vuvuzela-userland/test/crypto/test_aes256gcm.h create mode 100644 vuvuzela-userland/test/crypto/test_argon2id.c create mode 100644 vuvuzela-userland/test/crypto/test_argon2id.h create mode 100644 vuvuzela-userland/test/main.c create mode 100644 vuvuzela-userland/test/minunit.h diff --git a/vuvuzela-userland/.gitignore b/vuvuzela-userland/.gitignore new file mode 100644 index 0000000..ca8a718 --- /dev/null +++ b/vuvuzela-userland/.gitignore @@ -0,0 +1,11 @@ +proj_build/ +test_build/ +.proj_deps/ +.test_deps/ +build/ +.cproject +.project +.settings/ +tests +shufflecake +disks/ diff --git a/vuvuzela-userland/Makefile b/vuvuzela-userland/Makefile new file mode 100644 index 0000000..ee59323 --- /dev/null +++ b/vuvuzela-userland/Makefile @@ -0,0 +1,131 @@ +# Copyright The Shufflecake Project Authors (2022) +# Copyright The Shufflecake Project Contributors (2022) +# Copyright Contributors to the The Shufflecake Project. + +# See the AUTHORS file at the top-level directory of this distribution and at +# + +# This file is part of the program shufflecake-c, which is part of the Shufflecake +# Project. Shufflecake is a plausible deniability (hidden storage) layer for +# Linux. See . + +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2 of the License, or (at your option) +# any later version. 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, see . + +############################################################################# +# Makefile with dependency auto-generation, taken and adapted from +# https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ +############################################################################# + +# Output dirs for binaries +BIN_DIR := bin +PROJ_OUT_DIR := $(BIN_DIR)/proj_build +TEST_OUT_DIR := $(BIN_DIR)/test_build +# Output dirs for dependency files +PROJ_DEP_DIR := $(BIN_DIR)/.proj_deps +TEST_DEP_DIR := $(BIN_DIR)/.test_deps + +# Include directories for compilation +INCLUDE := include test + +# Use gcc +CC := gcc +# All warnings, add includes (other options may be supplied on command line) +override CFLAGS += -Wall $(addprefix -I,$(INCLUDE)) +# Flags for dependency file auto-generation (deferred evaluation) +PROJ_DEPFLAGS = -MT $@ -MMD -MP -MF $(PROJ_DEP_DIR)/$*.d +TEST_DEPFLAGS = -MT $@ -MMD -MP -MF $(TEST_DEP_DIR)/$*.d +# Linker flags +LDFLAGS := -lgcrypt -ldevmapper + +# The variables PROJ_SRCS (and PROJ_ROOT) and TEST_SRCS (and TEST_ROOT) are defined in this Makefile +include Makefile.sources +# Create the three lists of object files +PROJ_OBJS := $(PROJ_SRCS:$(PROJ_ROOT)/%.c=$(PROJ_OUT_DIR)/%.o) +TEST_OBJS := $(TEST_SRCS:$(TEST_ROOT)/%.c=$(TEST_OUT_DIR)/%.o) +PROJ_OBJS_NO_MAIN := $(filter-out $(PROJ_OUT_DIR)/main.o,$(PROJ_OBJS)) +# Create the two lists of dependency files +PROJ_DEPS := $(PROJ_SRCS:$(PROJ_ROOT)/%.c=$(PROJ_DEP_DIR)/%.d) +TEST_DEPS := $(TEST_SRCS:$(TEST_ROOT)/%.c=$(TEST_DEP_DIR)/%.d) +# Put them together +DEPS := $(PROJ_DEPS) $(TEST_DEPS) + +# All directories to be created if non-existing (sort to remove duplicates) +DIRS := $(sort $(dir $(BIN_DIR) $(PROJ_OBJS) $(TEST_OBJS) $(PROJ_DEPS) $(TEST_DEPS))) + +# The target binaries +MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake +TEST_BIN := $(TEST_OUT_DIR)/tests +# Their symlink +MAIN_LINK := shufflecake +TEST_LINK := tests + + + +#### +#### RULES +#### + + +.PHONY: main +main: $(MAIN_BIN) + +.PHONY: test +test: $(TEST_BIN) + +.PHONY: link_msg +link_msg: + @echo "Linking object files" + +.PHONY: compile_msg +compile_msg: + @echo "Compiling source files" + +# Link project object files +$(MAIN_BIN): $(PROJ_OBJS) | link_msg + @echo "\t---> $@" + @$(CC) $^ -o $@ $(LDFLAGS) + @rm -f $(MAIN_LINK) + @ln -s $@ $(MAIN_LINK) + +# Link test object files +$(TEST_BIN): $(PROJ_OBJS_NO_MAIN) $(TEST_OBJS) | link_msg + @echo "\t---> $@" + @$(CC) $^ -o $@ $(LDFLAGS) + @rm -f $(TEST_LINK) + @ln -s $@ $(TEST_LINK) + @echo "Done, launching tests" + @./$(TEST_LINK) + +# Cancel implicit rule +%.o : %.c + +# Build project object file +$(PROJ_OUT_DIR)/%.o : $(PROJ_ROOT)/%.c $(PROJ_DEP_DIR)/%.d | $(DIRS) compile_msg + @echo "\t---> $@" + @$(CC) $(PROJ_DEPFLAGS) $(CFLAGS) -c -o $@ $< + +# Build test object file +$(TEST_OUT_DIR)/%.o : $(TEST_ROOT)/%.c $(TEST_DEP_DIR)/%.d | $(DIRS) compile_msg + @echo "\t---> $@" + @$(CC) $(TEST_DEPFLAGS) $(CFLAGS) -c -o $@ $< + +# Create needed directories +$(DIRS): + @mkdir -p $@ + +.PHONY: clean +clean: + rm -rf $(PROJ_OUT_DIR) $(TEST_OUT_DIR) $(PROJ_DEP_DIR) $(TEST_DEP_DIR) + rm -rf $(BIN_DIR) + @rm -f $(MAIN_LINK) $(TEST_LINK) + +$(DEPS): +include $(wildcard $(DEPS)) diff --git a/vuvuzela-userland/Makefile.sources b/vuvuzela-userland/Makefile.sources new file mode 100644 index 0000000..0e2a80b --- /dev/null +++ b/vuvuzela-userland/Makefile.sources @@ -0,0 +1,49 @@ +# Copyright The Shufflecake Project Authors (2022) +# Copyright The Shufflecake Project Contributors (2022) +# Copyright Contributors to the The Shufflecake Project. + +# See the AUTHORS file at the top-level directory of this distribution and at +# + +# This file is part of the program shufflecake-c, which is part of the Shufflecake +# Project. Shufflecake is a plausible deniability (hidden storage) layer for +# Linux. See . + +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2 of the License, or (at your option) +# any later version. 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, see . + +######################################### +# Only define the sources to be compiled +######################################### + +#### +#### Main files +#### + +PROJ_SRCS := $(addprefix utils/,crypto.c disk.c dm.c file.c string.c input.c) +PROJ_SRCS += $(addprefix header/,position_map.c volume_master_block.c device_master_block.c) +PROJ_SRCS += $(addprefix operations/,volume_header.c devmapper.c dmb.c) +PROJ_SRCS += $(addprefix commands/,init.c open.c close.c test_pwd.c change_pwd.c) +PROJ_SRCS += $(addprefix cli/,dispatch.c init.c open.c close.c testpwd.c changepwd.c) +PROJ_SRCS += main.c + +PROJ_ROOT := src +PROJ_SRCS := $(addprefix $(PROJ_ROOT)/,$(PROJ_SRCS)) + + +#### +#### Test files +#### + +TEST_SRCS := $(addprefix crypto/,test_aes256ctr.c test_aes256gcm.c test_argon2id.c) +TEST_SRCS += main.c + +TEST_ROOT := test +TEST_SRCS := $(addprefix $(TEST_ROOT)/,$(TEST_SRCS)) diff --git a/vuvuzela-userland/include/cli.h b/vuvuzela-userland/include/cli.h new file mode 100644 index 0000000..838f618 --- /dev/null +++ b/vuvuzela-userland/include/cli.h @@ -0,0 +1,65 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _CLI_H_ +#define _CLI_H_ + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/* Action to create volumes */ +#define SFLC_CLI_INITACT "init" +/* Action to open volumes */ +#define SFLC_CLI_OPENACT "open" +/* Action to close volumes */ +#define SFLC_CLI_CLOSEACT "close" +/* Action to test password */ +#define SFLC_CLI_TESTPWDACT "testpwd" +/* Action to change password */ +#define SFLC_CLI_CHANGEPWDACT "changepwd" + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Called by the main to parse the arguments and dispatch to the right command */ +int sflc_cli_dispatch(int argc, char **argv); + +/* Initializes device and create empty volumes */ +int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill); +/* Open volumes */ +int sflc_cli_open(char *block_device); +/* Close volumes */ +int sflc_cli_close(char *block_device); +/* Test password */ +int sflc_cli_testPwd(char *block_device); +/* Change password */ +int sflc_cli_changePwd(char *block_device); + + +#endif /* _CLI_H_ */ + + diff --git a/vuvuzela-userland/include/commands.h b/vuvuzela-userland/include/commands.h new file mode 100644 index 0000000..68a14ac --- /dev/null +++ b/vuvuzela-userland/include/commands.h @@ -0,0 +1,113 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _COMMANDS_H_ +#define _COMMANDS_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "header.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + + +/***************************************************** + * STRUCTS * + *****************************************************/ + +/* Parameters for the init command */ +typedef struct +{ + /* Underlying block device */ + char *bdev_path; + + /* Number of volumes */ + size_t nr_vols; + /* Volumes' passwords */ + char **pwds; + size_t *pwd_lens; + + /* Option to skip random filling */ + bool no_randfill; + +} sflc_cmd_InitArgs; + + +/* Parameters for the open command */ +typedef struct +{ + /* Underlying block device */ + char *bdev_path; + + /* The only password provided */ + char *pwd; + size_t pwd_len; + +} sflc_cmd_OpenArgs; + +typedef struct +{ + /* Underlying block device */ + char *bdev_path; + + /* Content of the DMB cell */ + sflc_DmbCell *dmb_cell; + + /* The new password */ + char *new_pwd; + size_t new_pwd_len; + +} sflc_cmd_ChangePwdArgs; + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Create N volumes (only formats the device header, does not open the volumes) */ +int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args); + +/* Open M volumes, from the first down to the one whose pwd is provided */ +int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args); + +/* Close all volumes on the device (reads the list from sysfs) */ +int sflc_cmd_closeVolumes(char *bdev_path); + +/* Tests which volume is unlocked by the given password */ +int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell); + +/* Changes the specified volume's password */ +int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args); + + +#endif /* _COMMANDS_H_ */ diff --git a/vuvuzela-userland/include/header.h b/vuvuzela-userland/include/header.h new file mode 100644 index 0000000..869b868 --- /dev/null +++ b/vuvuzela-userland/include/header.h @@ -0,0 +1,161 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _HEADER_H_ +#define _HEADER_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +#include "utils/crypto.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/* The DMB contains one IV + one VMB key + one MAC for each volume */ +#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_CRYPTO_KEYLEN + SFLC_AESGCM_TAGLEN) + +/* Let us enforce that the one DMB can fit cells for all volumes */ +#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL) > SFLC_SECTOR_SIZE +#error "Invalid combination of parameters: probably SFLC_DEV_MAX_VOLUMES is too big" +#endif + + +// The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) +#define SFLC_CLEAR_VMB_LEN (SFLC_SECTOR_SIZE - \ + SFLC_AESGCM_PADDED_IVLEN - \ + SFLC_AESGCM_TAGLEN) + + + +/***************************************************** + * STRUCTS * + *****************************************************/ + +/** + * The on-disk master block of a device contains lots of crypto stuff + * (a KDF salt, IVs, MACs...) used to properly hide the VMB keys. + * This struct only contains such useful info, in the clear. + */ +typedef struct { + // Each volume's VMB key + char vmb_keys[SFLC_DEV_MAX_VOLUMES][SFLC_CRYPTO_KEYLEN]; + + // How many of these need actually be encrypted + size_t nr_vols; + +} sflc_Dmb; + + +/** + * When unsealing a DMB, only one VMB key can be unlocked with a password. + * An invalid value for vol_idx means no VMB key could be unlocked (wrong pwd) + */ +typedef struct { + // The unlocked VMB key + char vmb_key[SFLC_CRYPTO_KEYLEN]; + + // The index of the volume opened by this VMB key + size_t vol_idx; + +} sflc_DmbCell; + + +/** + * The on-disk master block of a volume contains crypto stuff + * (an IV) used to properly hide the useful info. This struct + * only contains the useful info, in the clear. + */ +typedef struct { + // The key that encrypts the volume's data section + char volume_key[SFLC_CRYPTO_KEYLEN]; + + // The key that encrypts the previous volume's master block + char prev_vmb_key[SFLC_CRYPTO_KEYLEN]; + + // The total number of logical slices virtually available to this volume + size_t nr_slices; + +} sflc_Vmb; + + +/** + * This struct represents an encrypted empty position map. + * On-disk, the layout interleaves one IV block with 256 PosMap blocks (each + * encrypted by an IV in the IV block). Many such "runs" can be concatenated, + * until the position map is big enough to index the desired number of slices. + * The last "run" might be incomplete, in that it could have less than 256 + * PosMap blocks, if not all of them are needed. + * In the struct, there are as many IV blocks as there are PosMapBlock arrays + * (equal to the number of "runs"). The m-th IV of the n-th IV block encrypts + * the m-th block of the n-th array. The PosMapBlocks in an array are stored + * contiguously in RAM, so a PosMapBlock array is just a char array of length + * multiple of 4096. All the arrays are full (256 PosMapBlocks, 1 MiB) except + * for the last one, which may hold fewer blocks. + */ +typedef struct { + // The number of PosMapBlock arrays (and of IV blocks) + size_t nr_arrays; + + // The sequence of IV blocks + char **iv_blocks; + // The sequence of (encrypted) PosMapBlock arrays + char **pmb_arrays; + + // The number of PosMapBlocks in the last array + size_t nr_last_pmbs; + +} sflc_EncPosMap; + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* "Encrypt" each VMB key with its pwd, so the DMB is ready to be written on-disk */ +int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); +/* "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF) */ +int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); +/* Re-encrypt the content of a single DMB cell */ +int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len); + + +/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ +int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block); +/* "Decrypt" a VMB coming from the disk, directly using its key */ +int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); + + +/* Create an encrypted empty position map for the given number of slices (allocates memory) */ +int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm); + + + +#endif /* _HEADER_H_ */ diff --git a/vuvuzela-userland/include/operations.h b/vuvuzela-userland/include/operations.h new file mode 100644 index 0000000..8de9ab6 --- /dev/null +++ b/vuvuzela-userland/include/operations.h @@ -0,0 +1,84 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _OPERATIONS_H_ +#define _OPERATIONS_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +#include "header.h" +#include "utils/crypto.h" +#include "utils/math.h" + + +/***************************************************** + * INLINE FUNCTIONS * + *****************************************************/ + +// Size, in 4096-byte blocks, of a whole volume header (VMB+PM) +static inline size_t sflc_volHeaderSize(size_t nr_slices) +{ + // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) + size_t nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + // Each array holds up to 256 PosMapBlocks + size_t nr_arrays = ceil(nr_pmbs, SFLC_BLOCKS_PER_LOG_SLICE); + + // 1 VMB, the PMBs, and the IV blocks + return 1 + nr_pmbs + nr_arrays; +} + +// Position of the VMB for the given volume +static inline uint64_t sflc_vmbPosition(size_t vol_idx, size_t nr_slices) +{ + return 1 + ((uint64_t) vol_idx) * ((uint64_t) sflc_volHeaderSize(nr_slices)); +} + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Encrypts and writes the DMB to disk */ +int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb); +/* Reads the DMB from disk and outputs the unlocked VMB key */ +int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); +/* Reads the DMB from disk, changes the relevant DMB cell, and writes it back */ +int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); + +/* Encrypts and writes a volume header (VMB+PM) on-disk */ +int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx); +/* Reads a VMB from disk and unlocks it */ +int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb); + +/* Build parameter list for ctor in dm_sflc, and send DM ioctl to create virtual block device */ +int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb); +/* Close the volume via the appropriate ioctl to DM */ +int sflc_ops_closeVolume(char *label); + +#endif /* _OPERATIONS_H_ */ diff --git a/vuvuzela-userland/include/sflc_constants.h b/vuvuzela-userland/include/sflc_constants.h new file mode 120000 index 0000000..fab9e42 --- /dev/null +++ b/vuvuzela-userland/include/sflc_constants.h @@ -0,0 +1 @@ +../../dm-sflc/sflc_constants.h \ No newline at end of file diff --git a/vuvuzela-userland/include/utils/crypto.h b/vuvuzela-userland/include/utils/crypto.h new file mode 100644 index 0000000..15ac111 --- /dev/null +++ b/vuvuzela-userland/include/utils/crypto.h @@ -0,0 +1,103 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _UTILS_CRYPTO_H_ +#define _UTILS_CRYPTO_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "utils/sflc.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +// Key length, for input into AES-CTR and AES-GCM, and for output from Argon +#define SFLC_CRYPTO_KEYLEN 32 /* bytes */ + +// IV length for AES-CTR +#define SFLC_AESCTR_IVLEN 16 /* bytes */ + +// IV length for AES-GCM +#define SFLC_AESGCM_IVLEN 12 /* bytes */ + +// IVs occupy 16 bytes on-disk, but only the *FIRST* 12 are used for AES-GCM +#define SFLC_AESGCM_PADDED_IVLEN 16 /* bytes */ + +// MAC length for AES-GCM +#define SFLC_AESGCM_TAGLEN 16 /* bytes */ + +// Content of output plaintext upon MAC verification failure +#define SFLC_AESGCM_POISON_PT 0xFF + + +/* Argon parameters */ + +// Argon salt length +#define SFLC_ARGON_SALTLEN 16 /* bytes */ + +// Argon memory parameter +// We assume machines with at least 128 MiB available RAM, so 2^17 kiB +#define SFLC_ARGON_M (1 << 17) /* kibibytes */ + +// Argon iterations count +// We aim for 1-2 seconds on a low-end laptop or mobile (it's a one-time operation) +#define SFLC_ARGON_T 3 + +// Argon parallelism parameter (recommended to be 2 * CPU cores) +// We assume use even on single core devices +#define SFLC_ARGON_P 2 + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Get slow, true random bytes (suited for keys) */ +int sflc_rand_getStrongBytes(char *buf, size_t buflen); +/* Get fast, pseudo random bytes (suited for IVs and padding) */ +int sflc_rand_getWeakBytes(char *buf, size_t buflen); + +/* AES256-CTR encryption, does not touch the IV. Set ct = NULL for in-place. */ +int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +/* AES256-CTR decryption, does not touch the IV. Set pt = NULL for in-place. */ +int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); + +/* AES256-GCM encryption, does not touch the IV */ +int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); +/* AES256-GCM decryption, does not touch the IV (only decrypts if MAC is valid) */ +int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); + +/* Compute Argon KDF */ +int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); + + +#endif /* _UTILS_CRYPTO_H_ */ diff --git a/vuvuzela-userland/include/utils/disk.h b/vuvuzela-userland/include/utils/disk.h new file mode 100644 index 0000000..7666609 --- /dev/null +++ b/vuvuzela-userland/include/utils/disk.h @@ -0,0 +1,107 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * Disk helper functions + */ + +#ifndef _UTILS_DISK_H_ +#define _UTILS_DISK_H_ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +#include "utils/sflc.h" + + +/***************************************************** + * MACROS * + *****************************************************/ + +/** + * Max slices for given disk size (in 4096-byte blocks). + * + * The bigger a disk is, the more slices it can host. However, the more slices we format it with, + * the bigger the position map needed to index them: the header size grows with the number of slices, + * taking up part of the space that's supposed to host those slices. + * To settle the matter, let us derive an upper bound on the header size, yielding a "safe" value + * for the number of slices (given a disk size). + * + * To index s slices, we need pm := ceil(s/1024) <= s/1024 + 1 PosMap blocks, since each PosMap + * block (4096 bytes) can host 1024 slice indices (4 bytes each). + * + * To encrypt those PosMap blocks, we need iv := ceil(pm/256) <= pm IV blocks, since each IV block + * (4096 bytes) can encrypt 256 data blocks (IVs are 16 bytes). + * + * Therefore, a position map indexing s slices occupies pm+iv <= 2*pm <= 2*s/1024 + 2 blocks. + * + * A single volume's header contains the Volume Master Block and the position map, therefore it + * occupies 1+pm+iv <= 2*s/1024 + 3 blocks. + * + * The entire device's header simply contains 15 volume headers of the same size, therefore it + * occupies h := 15 * (1+pm+iv) <= 15*2*s/1024 + 3*15 <= s + 3*15 blocks. + * The last inequality follows from 15*2/1024 <= 1 (we need to enforce this on the symbolic values). + * + * To actually host the s slices, the data section needs 257*s blocks (256 data blocks + 1 IV block + * per slice). + * + * Therefore, in order to format a disk with s slices, we need at most (s + 3*15) + 257*s = + * = (1 + 257)*s + 3*15 blocks. + * + * If we are given d blocks on the disk, a safe value for s is one that satisfies + * (1 + 257)*s + 3*15 <= d <==> s <= (d - 3*15) / (1 + 257) + */ +#define sflc_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFLC_BLOCKS_PER_PHYS_SLICE) + + +/* Let us enforce, on the symbolic values, the inequality used in the previous bound */ +#if SFLC_DEV_MAX_VOLUMES * 2 > SFLC_SLICE_IDX_PER_BLOCK +#error "Invalid combination of parameters, probably SFLC_DEV_MAX_VOLUMES is too big" +#endif + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Checks whether the given path points to a block device */ +bool sflc_disk_isBlockDevice(char *path); + +/* Returns the size in 4096-byte sectors (or < 0 if error) */ +int64_t sflc_disk_getSize(char * bdev_path); + +/* Reads a single 4096-byte sector from the disk */ +int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf); + +/* Writes a single 4096-byte sector to the disk */ +int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf); + +/* Writes many 4096-byte sectors to the disk */ +int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors); + + +#endif /* _UTILS_DISK_H_ */ diff --git a/vuvuzela-userland/include/utils/dm.h b/vuvuzela-userland/include/utils/dm.h new file mode 100644 index 0000000..3334852 --- /dev/null +++ b/vuvuzela-userland/include/utils/dm.h @@ -0,0 +1,56 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * Interface to the device mapper + */ + +#ifndef _UTILS_DM_H_ +#define _UTILS_DM_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include + +#include "utils/sflc.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Create a new Shufflecake virtual device (volume) under /dev/mapper */ +int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); +/* Destroy the virtual device under /dev/mapper */ +int sflc_dm_destroy(char * virt_dev_name); + + +#endif /* _UTILS_DM_H_ */ diff --git a/vuvuzela-userland/include/utils/file.h b/vuvuzela-userland/include/utils/file.h new file mode 100644 index 0000000..fb03078 --- /dev/null +++ b/vuvuzela-userland/include/utils/file.h @@ -0,0 +1,36 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _UTILS_FILE_H_ +#define _UTILS_FILE_H_ + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Malloc's the buffer for the file contents */ +char *sflc_readFile(char *path); + + +#endif /* _UTILS_FILE_H_ */ diff --git a/vuvuzela-userland/include/utils/input.h b/vuvuzela-userland/include/utils/input.h new file mode 100644 index 0000000..9463999 --- /dev/null +++ b/vuvuzela-userland/include/utils/input.h @@ -0,0 +1,46 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _UTILS_INPUT_H_ +#define _UTILS_INPUT_H_ + + +/***************************************************** + * MACROS * + *****************************************************/ + +/* Clear a line from stdin, to use after a failed scanf (it didn't actually read input) */ +#define sflc_ignoreLine() scanf("%*[^\n]") + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Reads a line (discarding the newline) from stdin. No buffer overflow */ +int sflc_safeReadLine(char *buf, size_t bufsize); + +/* Reads a password or passphrase (discarding the newline) from stdin in a secure way (no echo) */ +int sflc_safeReadPassphrase(char *buf, size_t bufsize); + +#endif /* _UTILS_FILE_H_ */ diff --git a/vuvuzela-userland/include/utils/log.h b/vuvuzela-userland/include/utils/log.h new file mode 100644 index 0000000..2088fbb --- /dev/null +++ b/vuvuzela-userland/include/utils/log.h @@ -0,0 +1,136 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _UTILS_LOG_H_ +#define _UTILS_LOG_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +// Printf colours (regular text) +#define SFLC_LOG_BLK "\033[0;30m" +#define SFLC_LOG_RED "\033[0;31m" +#define SFLC_LOG_GRN "\033[0;32m" +#define SFLC_LOG_YEL "\033[0;33m" +#define SFLC_LOG_BLU "\033[0;34m" +#define SFLC_LOG_MAG "\033[0;35m" +#define SFLC_LOG_CYN "\033[0;36m" +#define SFLC_LOG_WHT "\033[0;37m" +// Printf colours (bold text) +#define SFLC_LOG_BBLK "\033[1;30m" +#define SFLC_LOG_BRED "\033[1;31m" +#define SFLC_LOG_BGRN "\033[1;32m" +#define SFLC_LOG_BYEL "\033[1;33m" +#define SFLC_LOG_BBLU "\033[1;34m" +#define SFLC_LOG_BMAG "\033[1;35m" +#define SFLC_LOG_BCYN "\033[1;36m" +#define SFLC_LOG_BWHT "\033[1;37m" +// Reset colour +#define SFLC_LOG_RESET "\033[0m" + +// Log level: debug implies detailed logs +#ifdef CONFIG_SFLC_LOG_DEBUG +#define CONFIG_SFLC_LOG_DETAILED +#endif + + +/***************************************************** + * MACROS * + *****************************************************/ + +// Gives the point in the code where it was called +#define sflc_log_detailed(col, ...) do{ \ + printf(SFLC_LOG_GRN "FUNC " SFLC_LOG_RESET "%s() " \ + SFLC_LOG_GRN "FILE " SFLC_LOG_RESET "%s " \ + SFLC_LOG_GRN "LINE " SFLC_LOG_RESET "%d | ", \ + __func__, __FILE__, __LINE__); \ + sflc_log_concise(col, __VA_ARGS__); \ +}while(0) + +// Only writes using the given colour +#define sflc_log_concise(col, ...) do{ \ + printf(col); \ + printf(__VA_ARGS__); \ + printf(SFLC_LOG_RESET "\n"); \ +}while(0) + +// Maps to one or the other, based on a Makefile switch +#ifdef CONFIG_SFLC_LOG_DETAILED + #define sflc_log_colour(...) sflc_log_detailed(__VA_ARGS__) +#else + #define sflc_log_colour(...) sflc_log_concise(__VA_ARGS__) +#endif + +// Using specific colours +#define sflc_log_green(...) sflc_log_colour(SFLC_LOG_GRN, __VA_ARGS__) +#define sflc_log_red(...) sflc_log_colour(SFLC_LOG_RED, __VA_ARGS__) +#define sflc_log_yellow(...) sflc_log_colour(SFLC_LOG_YEL, __VA_ARGS__) +#define sflc_log_blue(...) sflc_log_colour(SFLC_LOG_BLU, __VA_ARGS__) +#define sflc_log_normal(...) sflc_log_colour(SFLC_LOG_RESET, __VA_ARGS__) + +// With log levels +#define sflc_log_error(...) sflc_log_colour(SFLC_LOG_RED, "[ERROR] " __VA_ARGS__) +#define sflc_log_warn(...) sflc_log_colour(SFLC_LOG_MAG, "[WARN] " __VA_ARGS__) +#ifdef CONFIG_SFLC_LOG_DEBUG + #define sflc_log_debug(...) sflc_log_colour(SFLC_LOG_CYN, "[DEBUG] " __VA_ARGS__) +#else + #define sflc_log_debug(...) +#endif + + +/***************************************************** + * INLINE FUNCTIONS * + *****************************************************/ + +// Log a hex string +static inline void sflc_log_hex(char *str, size_t len) +{ + int i; + unsigned char *s = (unsigned char *) str; + + for (i = 0; i < len; i++) { + printf("%02x ", s[i]); + // Nice aligned wrapping + if (i % 16 == 15) { + printf("\n"); + } + } + + // Always end with a newline + if (i % 16 != 0) { + printf("\n"); + } + + return; +} + +#endif /* _UTILS_LOG_H_ */ diff --git a/vuvuzela-userland/include/utils/math.h b/vuvuzela-userland/include/utils/math.h new file mode 100644 index 0000000..db5e397 --- /dev/null +++ b/vuvuzela-userland/include/utils/math.h @@ -0,0 +1,36 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _UTILS_MATH_H_ +#define _UTILS_MATH_H_ + + +/***************************************************** + * MACROS * + *****************************************************/ + +// Function ceil(a/b) = floor((a+b-1)/b) +#define ceil(a, b) ( ((a)+(b)-1) / (b) ) + + +#endif /* _UTILS_MATH_H_ */ diff --git a/vuvuzela-userland/include/utils/sflc.h b/vuvuzela-userland/include/utils/sflc.h new file mode 100644 index 0000000..e8135e4 --- /dev/null +++ b/vuvuzela-userland/include/utils/sflc.h @@ -0,0 +1,89 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflc_constans.h + */ + +#ifndef _UTILS_SFLC_H_ +#define _UTILS_SFLC_H_ + + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/* Name of the DM target in the kernel */ +#define SFLC_DM_TARGET_NAME "shufflecake" + +/* Disk constants */ +#define SFLC_SECTOR_SIZE 4096 /* bytes */ +#define KERNEL_SECTOR_SIZE 512 /* bytes */ +#define SFLC_SECTOR_SCALE (SFLC_SECTOR_SIZE / KERNEL_SECTOR_SIZE) + +/* Max number of volumes in a device */ +#define SFLC_DEV_MAX_VOLUMES 15 + +/* Max total number of open devices at any given time */ +#define SFLC_TOT_MAX_DEVICES 1024 +/* A volume name is sflc__ */ +#define SFLC_MAX_VOL_NAME_LEN 15 + +/* A slice index is represented over 32 bits */ +#define SFLC_SLICE_IDX_WIDTH 4 /* bytes */ +/* A position map block contains 1024 slice indices */ +#define SFLC_SLICE_IDX_PER_BLOCK (SFLC_SECTOR_SIZE / SFLC_SLICE_IDX_WIDTH) + +// IV length for AES-CTR +#define SFLC_AESCTR_IVLEN 16 /* bytes */ + +/* An IV block can encrypt 256 data blocks */ +#define SFLC_DATA_BLOCKS_PER_IV_BLOCK (SFLC_SECTOR_SIZE / SFLC_AESCTR_IVLEN) +/* A logical slice spans 256 blocks of data (1 MiB) */ +#define SFLC_BLOCKS_PER_LOG_SLICE SFLC_DATA_BLOCKS_PER_IV_BLOCK +/* A physical slice also includes the IV block */ +#define SFLC_BLOCKS_PER_PHYS_SLICE (1 + SFLC_BLOCKS_PER_LOG_SLICE) + +/* A PSI of 0xFFFFFFFF indicates an unassigned LSI */ +#define SFLC_EPM_FILLER 0xFF + +/* The sysfs file containing the next available device ID */ +#define SFLC_SYSFS_NEXTDEVID "/sys/devices/sflc/next_dev_id" +/* The sysfs directory containing a subdir for each (underlying) block device */ +#define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" +/* Within each bdev's subdir, this file lists its open volumes */ +#define SFLC_SYSFS_OPENVOLUMES_FILENAME "volumes" + +/* TODO: reasonable? */ +#define SFLC_BDEV_PATH_MAX_LEN 1024 + +/* For when you can't be bothered to upper-bound a buffer size */ +#define SFLC_BIGBUFSIZE 4096 + + +#endif /* _UTILS_SFLC_H_ */ diff --git a/vuvuzela-userland/include/utils/string.h b/vuvuzela-userland/include/utils/string.h new file mode 100644 index 0000000..ca42c0e --- /dev/null +++ b/vuvuzela-userland/include/utils/string.h @@ -0,0 +1,39 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _UTILS_STRING_H_ +#define _UTILS_STRING_H_ + + +/***************************************************** + * PUBLIC FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Malloc's the buffer for the hex string */ +char *sflc_toHex(char *buf, size_t len); + +/* Replaces all occurrences of character in-place */ +void sflc_str_replaceAll(char *str, char old, char new); + + +#endif /* _UTILS_STRING_H_ */ diff --git a/vuvuzela-userland/src/cli/changepwd.c b/vuvuzela-userland/src/cli/changepwd.c new file mode 100644 index 0000000..de37779 --- /dev/null +++ b/vuvuzela-userland/src/cli/changepwd.c @@ -0,0 +1,112 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * Change volume password + * + * @return Error code, 0 on success + */ +int sflc_cli_changePwd(char *block_device) +{ // Requires: block_device is a correct block device path + sflc_cmd_OpenArgs open_args; + sflc_cmd_ChangePwdArgs change_pwd_args; + sflc_DmbCell dmb_cell; + char old_pwd[SFLC_BIGBUFSIZE]; + size_t old_pwd_len; + char new_pwd[SFLC_BIGBUFSIZE]; + size_t new_pwd_len; + int err; + + open_args.bdev_path = block_device; + + /* Gather password */ + printf("Enter the password you want to change: "); + err = sflc_safeReadPassphrase(old_pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + old_pwd_len = strlen(old_pwd); + /* Assign fields */ + open_args.pwd = old_pwd; + open_args.pwd_len = old_pwd_len; + + /* Test the password */ + err = sflc_cmd_testPwd(&open_args, &dmb_cell); + if (err) { + sflc_log_error("Could not test password; error %d", err); + return err; + } + + /* Does this password open any volumes? */ + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + printf("This password does not unlock any volume.\n"); + return 0; + } + + /* Gather new password (no secure shell) */ + printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); + printf("Choose new password for volume %lu: ", dmb_cell.vol_idx); + err = sflc_safeReadLine(new_pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read new password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + new_pwd_len = strlen(new_pwd); + + /* Assign fields */ + change_pwd_args.bdev_path = block_device; + change_pwd_args.dmb_cell = &dmb_cell; + change_pwd_args.new_pwd = new_pwd; + change_pwd_args.new_pwd_len = new_pwd_len; + + /* Change password */ + err = sflc_cmd_changePwd(&change_pwd_args); + if (err) { + sflc_log_error("Could not change password; error %d", err); + return err; + } + printf("Password changed successfully.\n"); + return err; +} diff --git a/vuvuzela-userland/src/cli/close.c b/vuvuzela-userland/src/cli/close.c new file mode 100644 index 0000000..fdbaa28 --- /dev/null +++ b/vuvuzela-userland/src/cli/close.c @@ -0,0 +1,74 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * Close volumes + * + * @return Error code, 0 on success + */ +int sflc_cli_close(char *block_device) +{ // Requires: block_device is a correct block device path +// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; +// int err; + +// /* Gather (absolute) path to underlying block device */ +// printf("Enter the absolute path to the underlying block device containing the Shufflecake volumes to close: "); +// err = sflc_safeReadLine(bdev_path, SFLC_BDEV_PATH_MAX_LEN + 2); +// if (err) { +// sflc_log_error("Could not read path to underlying block device; error %d", err); +// return err; +// } +// /* Check that it is absolute */ +// if (bdev_path[0] != '/') { +// printf("The path to the block device must be absolute"); +// return EINVAL; +// } +// + + + /* Actually perform the command */ +// return sflc_cmd_closeVolumes(bdev_path); + + + return sflc_cmd_closeVolumes(block_device); + +} diff --git a/vuvuzela-userland/src/cli/dispatch.c b/vuvuzela-userland/src/cli/dispatch.c new file mode 100644 index 0000000..01da250 --- /dev/null +++ b/vuvuzela-userland/src/cli/dispatch.c @@ -0,0 +1,245 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include + +#include "cli.h" +#include "utils/sflc.h" +#include "utils/disk.h" +#include "utils/log.h" +#include "sflc_constants.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/* Used by argp to provide the automatic "-V" option */ +const char *argp_program_version = SFLC_VERSION; +/* Used by argp to provide the automatic "--help" option */ +const char *argp_program_bug_address = ""; + +/* Signed integer values representing a handle for each option */ +#define SFLC_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option +#define SFLC_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this + + +/***************************************************** + * TYPES * + *****************************************************/ + +enum sflc_cli_action { + SFLC_ACT_INIT, + SFLC_ACT_OPEN, + SFLC_ACT_CLOSE, + SFLC_ACT_TESTPWD, + SFLC_ACT_CHANGEPWD +}; + +struct sflc_cli_arguments { + enum sflc_cli_action act; + char *block_device; + int num_volumes; + bool skip_randfill; +}; + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +static error_t _parseArgpKey(int key, char *arg, struct argp_state *state); + + +/***************************************************** + * PRIVATE VARIABLES * + *****************************************************/ + +/* Doc strings */ +static char args_doc[] = "ACTION "; +static char doc[] = + "Shufflecake is a plausible deniability (hidden storage) layer for Linux.\n" + "See official website at for more info.\n" + "Possible values for mandatory ACTION are:\n\n" + + "\tinit:\t\tInitialise a block device for Shufflecake use, formatting\n" + "\t\t\theaders with provided passwords and overwriting with random\n" + "\t\t\tdata. WARNING: THIS WILL ERASE THE CONTENT OF THE DEVICE.\n\n" + + "\topen:\t\tOpen a hierarchy of Shufflecake volumes within a device by\n" + "\t\t\tasking a single user password. Virtual devices will appear\n" + "\t\t\tin /dev/mapper. Notice: freshly created device must be\n" + "\t\t\tuser-formatted and mounted in order to be used.\n\n" + + "\tclose:\t\tClose all open Shufflecake volumes supported by given\n" + "\t\t\tdevice.\n\n" + + "\ttestpwd:\tTest whether a given password unlocks any volume within\n" + "\t\t\tthe block device and, if so, show its index.\n\n" + + "\tchangepwd:\tChange the password unlocking a certain volume.\n\n" + + "Possible options are:"; + +/* Description of each option */ +static struct argp_option options[] = { + {"num-volumes", SFLC_OPT_NUMVOLS_KEY, "num", 0, + "Specify number of volumes to be created with `init'. Must be an integer between 1 and 15.", 0 }, // TODO: define MAX_VOLS instead of hardcoding 15 + {"skip-randfill", SFLC_OPT_SKIPRAND_KEY, 0, 0, + "Skip pre-overwriting block device with random data, only valid with `init'. Faster but less secure. Use only for debugging or testing."}, + {0} +}; + +/* Wrapper containing everything */ +static struct argp argp = {options, _parseArgpKey, args_doc, doc}; + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * The following is the main dispatch function called by the main to parse + * the arguments and dispatch to the right command. + * + * @param argc The number of command-line arguments supplied to the main + * @param argv The arguments + * + * @return Error code, 0 on success + */ + +int sflc_cli_dispatch(int argc, char **argv) { + struct sflc_cli_arguments arguments; + + arguments.act = -1; + arguments.block_device = NULL; + arguments.num_volumes = 0; + arguments.skip_randfill = false; + + /* Parse */ + argp_parse(&argp, argc, argv, 0, 0, &arguments); + + /* Check options consistency */ + if (arguments.num_volumes && arguments.act != SFLC_ACT_INIT) { + printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); + return EINVAL; + } + /* Check options consistency */ + if (arguments.skip_randfill && arguments.act != SFLC_ACT_INIT) { + printf("Error: --skip-randfill can only be combined with `init'.\n"); + return EINVAL; + } + /* Check that input is actually a block device */ + if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !sflc_disk_isBlockDevice(arguments.block_device)) { + printf("Error: '%s' is not a valid block device.\n", arguments.block_device); + return EINVAL; + } + + /* Dispatch to specific command */ + if (arguments.act == SFLC_ACT_INIT) { + return sflc_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); + } + if (arguments.act == SFLC_ACT_OPEN) { + return sflc_cli_open(arguments.block_device); + } + if (arguments.act == SFLC_ACT_CLOSE) { + return sflc_cli_close(arguments.block_device); + } + if (arguments.act == SFLC_ACT_TESTPWD) { + return sflc_cli_testPwd(arguments.block_device); + } + if (arguments.act == SFLC_ACT_CHANGEPWD) { + return sflc_cli_changePwd(arguments.block_device); + } + + printf("\n"); + + return EINVAL; +} + + +/***************************************************** + * PRIVATE FUNCTIONS DEFINITIONS * + *****************************************************/ + +static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { + struct sflc_cli_arguments *arguments = state->input; + + switch (key) { + /* We are parsing an argument (not an option) */ + case ARGP_KEY_ARG: + /* We are parsing the command */ + if (state->arg_num == 0) { + if (strcmp(arg, SFLC_CLI_INITACT) == 0) { + arguments->act = SFLC_ACT_INIT; + } else if (strcmp(arg, SFLC_CLI_OPENACT) == 0) { + arguments->act = SFLC_ACT_OPEN; + } else if (strcmp(arg, SFLC_CLI_CLOSEACT) == 0) { + arguments->act = SFLC_ACT_CLOSE; + } else if (strcmp(arg, SFLC_CLI_TESTPWDACT) == 0) { + arguments->act = SFLC_ACT_TESTPWD; + } else if (strcmp(arg, SFLC_CLI_CHANGEPWDACT) == 0) { + arguments->act = SFLC_ACT_CHANGEPWD; + } else { + argp_error(state, "Invalid action. Please enter one and only one of: `%s', `%s', `%s', '%s', or '%s'.", + SFLC_CLI_INITACT, SFLC_CLI_OPENACT, SFLC_CLI_CLOSEACT, SFLC_CLI_TESTPWDACT, SFLC_CLI_CHANGEPWDACT); + } + /* We are parsing the block device */ + } else if (state->arg_num == 1) { + arguments->block_device = arg; + /* Too many arguments */ + } else { + argp_usage(state); + } + break; + + /* We are parsing an option */ + case SFLC_OPT_NUMVOLS_KEY: + arguments->num_volumes = atoi(arg); + break; + case SFLC_OPT_SKIPRAND_KEY: + arguments->skip_randfill = true; + break; + + /* End of arg list */ + case ARGP_KEY_END: + if (state->arg_num < 2) { + argp_usage(state); + } + break; + + /* Unrecognised key */ + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} diff --git a/vuvuzela-userland/src/cli/init.c b/vuvuzela-userland/src/cli/init.c new file mode 100644 index 0000000..302a96d --- /dev/null +++ b/vuvuzela-userland/src/cli/init.c @@ -0,0 +1,118 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * Create volumes + * + * @return Error code, 0 on success + */ +int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) +{ // Requires: block_device is a correct block device path + sflc_cmd_InitArgs args; + char str_nrvols[SFLC_BIGBUFSIZE]; + char *pwds[SFLC_DEV_MAX_VOLUMES]; + size_t pwd_lens[SFLC_DEV_MAX_VOLUMES]; + int err; + + args.bdev_path = block_device; + + // Check if number of volumes was nonzero passed by command line already + if (num_volumes) { + args.nr_vols = num_volumes; + } else { + // If not, ask user for number of volumes + printf("\nHow many volumes do you want to create (maximum is %d)? ", SFLC_DEV_MAX_VOLUMES); + err = sflc_safeReadLine(str_nrvols, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Error: could not read number of volumes; error %d", err); + return err; + } + /* Parse string */ + if (sscanf(str_nrvols, "%lu\n", &args.nr_vols) != 1) { + sflc_log_error("Error: could not parse number of volumes"); + return EINVAL; + } + } + + /* Bounds check */ + if (args.nr_vols <= 0) { + printf("Error: number of volumes must be a positive integer"); + return EINVAL; + } + if (args.nr_vols > SFLC_DEV_MAX_VOLUMES) { + printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", SFLC_DEV_MAX_VOLUMES); + return EINVAL; + } + + /* Collects the passwords */ + printf("\nNow you will be asked to insert the passwords for all the volumes you want to create, \nfrom " + "volume 0 (the least secret) to volume %lu (the most secret).\n\n", args.nr_vols - 1); + size_t i; + for (i = 0; i < args.nr_vols; i++) { + // Allocate pwd + pwds[i] = malloc(SFLC_BIGBUFSIZE); + + /* Read it */ + printf("Choose password for volume %lu (must not be empty): ", i); + err = sflc_safeReadLine(pwds[i], SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read password for volume %lu; error %d", i, err); + return err; + } + + /* You can trust the length of strings input this way */ + pwd_lens[i] = strlen(pwds[i]); + /* Check non-empty */ + if (pwd_lens[i] == 0) { + sflc_log_error("Password cannot be empty!"); + return EINVAL; + } + } + /* Assign them */ + args.pwds = pwds; + args.pwd_lens = pwd_lens; + + args.no_randfill = skip_randfill; + + /* Actually perform the command */ + return sflc_cmd_initVolumes(&args); +} diff --git a/vuvuzela-userland/src/cli/open.c b/vuvuzela-userland/src/cli/open.c new file mode 100644 index 0000000..45464c9 --- /dev/null +++ b/vuvuzela-userland/src/cli/open.c @@ -0,0 +1,77 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * Open volumes + * + * @return Error code, 0 on success + */ +int sflc_cli_open(char *block_device) +{ // Requires: block_device is a correct block device path + sflc_cmd_OpenArgs args; + char pwd[SFLC_BIGBUFSIZE]; + size_t pwd_len; + int err; + + args.bdev_path = block_device; + + /* Gather password */ + printf("Enter the password for the most secret volume you want to open: "); + err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + pwd_len = strlen(pwd); + /* Check non-empty */ + if (pwd_len == 0) { + sflc_log_error("Password cannot be empty!"); + return EINVAL; + } + /* Assign them */ + args.pwd = pwd; + args.pwd_len = pwd_len; + + /* Actually perform the command */ + return sflc_cmd_openVolumes(&args); +} diff --git a/vuvuzela-userland/src/cli/testpwd.c b/vuvuzela-userland/src/cli/testpwd.c new file mode 100644 index 0000000..550df25 --- /dev/null +++ b/vuvuzela-userland/src/cli/testpwd.c @@ -0,0 +1,87 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * Test volume password + * + * @return Error code, 0 on success + */ +int sflc_cli_testPwd(char *block_device) +{ // Requires: block_device is a correct block device path + sflc_cmd_OpenArgs args; + sflc_DmbCell dmb_cell; +// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; + char pwd[SFLC_BIGBUFSIZE]; + size_t pwd_len; + int err; + + args.bdev_path = block_device; + + /* Gather password */ + printf("Enter the password you want to test: "); + err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + pwd_len = strlen(pwd); + /* Assign them */ + args.pwd = pwd; + args.pwd_len = pwd_len; + + /* Actually perform the command */ + err = sflc_cmd_testPwd(&args, &dmb_cell); + if (err) { + sflc_log_error("Could not test password; error %d", err); + return err; + } + + /* Does this password open any volumes? */ + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + printf("This password does not unlock any volume.\n"); + } else { + printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); + } + + return 0; +} diff --git a/vuvuzela-userland/src/commands/change_pwd.c b/vuvuzela-userland/src/commands/change_pwd.c new file mode 100644 index 0000000..2ef64e0 --- /dev/null +++ b/vuvuzela-userland/src/commands/change_pwd.c @@ -0,0 +1,58 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/file.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Changes the specified volume's password. + * + * @param args->bdev_path The underlying block device + * @param args->dmb_cell The DMB cell to re-encrypt + * @param args->new_pwd The new password + * @param args->new_pwd_len Its length + * + * @return Error code, 0 on success + */ +int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args) +{ + /* Delegate entirely to the function reading the DMB */ + return sflc_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); +} diff --git a/vuvuzela-userland/src/commands/close.c b/vuvuzela-userland/src/commands/close.c new file mode 100644 index 0000000..4c180f6 --- /dev/null +++ b/vuvuzela-userland/src/commands/close.c @@ -0,0 +1,178 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/string.h" +#include "utils/file.h" +#include "utils/log.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Reads the list of volumes from sysfs */ +static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols); + +/* Close them all (in reverse order of opening) */ +static int _closeVolumes(char **labels, size_t nr_vols); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Close all volumes on the device (reads the list from sysfs) + * + * @param bdev_path The path to the underlying block device + * + * @return Error code, 0 on success + */ +int sflc_cmd_closeVolumes(char *bdev_path) +{ + char *labels[SFLC_DEV_MAX_VOLUMES]; + size_t nr_vols; + int err; + + /* Allocate labels */ + size_t i; + for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { + labels[i] = malloc(SFLC_MAX_VOL_NAME_LEN + 1); + if (!labels[1]) { + sflc_log_error("Could not allocate volume label %lu", i); + return ENOMEM; // Do not free the ones already allocated + } + } + + /* Read them */ + err = _readVolumesList(bdev_path, labels, &nr_vols); + if (err) { + sflc_log_error("Could not read volume list from sysfs; error %d", err); + goto out; + } + + /* Close the volumes (in reverse order of opening) */ + err = _closeVolumes(labels, nr_vols); + if (err) { + sflc_log_error("Could not close volumes; error %d", err); + goto out; + } + + /* No prob */ + err = 0; + + +out: + for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { + free(labels[i]); + } + return err; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Reads the list of volumes from sysfs */ +static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) +{ + char bdev_path_noslash[SFLC_BDEV_PATH_MAX_LEN + 1]; + char openvolumes_path[SFLC_BIGBUFSIZE]; + char *str_openvolumes; + + /* Remove the slashes from the bdev_path (replace with underscores) */ + strcpy(bdev_path_noslash, bdev_path); + sflc_str_replaceAll(bdev_path_noslash, '/', '_'); + /* Build path to sysfsy file containing open volumes list */ + sprintf(openvolumes_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_path_noslash, SFLC_SYSFS_OPENVOLUMES_FILENAME); + + /* Read the sysfs file */ + str_openvolumes = sflc_readFile(openvolumes_path); + if (!str_openvolumes) { + sflc_log_error("Could not read file %s", openvolumes_path); + return EBADF; + } + + /* Parse the number of volumes */ + char *endptr; + *nr_vols = strtoul(str_openvolumes, &endptr, 10); + /* Skip past the number of volumes (lands on a whitespace before the first label) */ + str_openvolumes = endptr; + + /* Just to be sure */ + if (*nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); + return EBADF; + } + + /* Read labels */ + size_t i; + for (i = 0; i < *nr_vols; i++) { + /* Trust the content of the sysfs file */ + if (sscanf(str_openvolumes, " %s", labels[i]) != 1) { + sflc_log_error("Could not read volume label %lu. Sysfs content:\n%s", i, str_openvolumes); + return EBADF; + } + sflc_log_debug("Label %lu to close: %s", i, labels[i]); + + /* Skip past the whitespace and the label */ + str_openvolumes += 1 + strlen(labels[i]); + } + + return 0; +} + + +/* Close them all (in reverse order of opening) */ +static int _closeVolumes(char **labels, size_t nr_vols) +{ + int err; + + /* Eazy peazy */ + int i; + for (i = nr_vols-1; i >= 0; i--) { + err = sflc_ops_closeVolume(labels[i]); + if (err) { + sflc_log_error("Could not close volume %s; error %d", labels[i], err); + return err; + } + sflc_log_debug("Closed volume %s", labels[i]); + printf("Closed volume /dev/mapper/%s\n", labels[i]); + } + + return 0; +} + diff --git a/vuvuzela-userland/src/commands/init.c b/vuvuzela-userland/src/commands/init.c new file mode 100644 index 0000000..cd21b03 --- /dev/null +++ b/vuvuzela-userland/src/commands/init.c @@ -0,0 +1,202 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/disk.h" +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/* The device is randomised in chunks of 1024 blocks (arbitrary number) */ +#define SFLC_BLOCKS_IN_RAND_CHUNK 1024 +/* That's 4 MiB */ +#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_SECTOR_SIZE) + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Fill the device with random data */ +static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Create N volumes (only formats the device header, does not open the volumes). + * Creates them in order from 0 to N-1, so as to induce a back-linked list on the device. + * + * @param args->bdev_path The path to the underlying block device + * @param args->nr_vols The number of volumes to create + * @param args->pwds The array of passwords for the various volumes + * @param args->pwd_lens The length of each password + * @param args->no_randfill A boolean switch indicating that the volume should not + * be filled entirely with random data prior to formatting. + * + * @return Error code, 0 on success + */ +int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) +{ + sflc_Dmb dmb; + sflc_Vmb vmb; + int64_t dev_size; + size_t nr_slices; + int err; + + /* Sanity check */ + if (args->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create %lu volumes on a single device", args->nr_vols); + return EINVAL; + } + + /* Get device size */ + dev_size = sflc_disk_getSize(args->bdev_path); + if (dev_size < 0) { + err = -dev_size; + sflc_log_error("Could not get device size for %s; error %d", args->bdev_path, err); + return err; + } + /* Convert to number of slices */ + nr_slices = sflc_disk_maxSlices(dev_size); + sflc_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); + + /* Fill disk with random bytes, if requested */ + if (!args->no_randfill) { + err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); + if (err) { + sflc_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); + return err; + } + } + + /* Fill the DMB */ + dmb.nr_vols = args->nr_vols; + /* Sample the VMB keys */ + size_t i; + for (i = 0; i < dmb.nr_vols; i++) { + err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_CRYPTO_KEYLEN); + if (err) { + sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); + return err; + } + } + /* And write (encrypted) to disk */ + err = sflc_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); + if (err) { + sflc_log_error("Could not create DMB and write it to disk; error %d", err); + return err; + } + + /* Write the volume headers */ + vmb.nr_slices = nr_slices; + for (i = 0; i < args->nr_vols; i++) { + /* This volume's prev_vmb_key */ + if (i > 0) { + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_CRYPTO_KEYLEN); + } + /* Sample this volume's VEK */ + sflc_rand_getStrongBytes(vmb.volume_key, SFLC_CRYPTO_KEYLEN); + + /* Write complete volume header (VMB + PM) */ + err = sflc_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); + if (err) { + sflc_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); + return err; + } + } + printf("Created %lu volumes on device %s\n", args->nr_vols, args->bdev_path); + + return 0; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Fill the device with random data */ +static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) +{ + char *rand_chunk; + int err; + + /* Allocate chunk */ + rand_chunk = malloc(SFLC_RAND_CHUNK_SIZE); + if (!rand_chunk) { + sflc_log_error("Could not allocate %d bytes for chunk of random data", SFLC_RAND_CHUNK_SIZE); + return ENOMEM; + } + + /* Loop to write random data in chunks */ + uint64_t blocks_remaining = dev_size; + uint64_t sector = 0; + while (blocks_remaining > 0) { + uint64_t blocks_to_write = + (blocks_remaining > SFLC_BLOCKS_IN_RAND_CHUNK) ? SFLC_BLOCKS_IN_RAND_CHUNK : blocks_remaining; + uint64_t bytes_to_write = blocks_to_write * SFLC_SECTOR_SIZE; + + /* Sample random bytes */ + err = sflc_rand_getWeakBytes(rand_chunk, bytes_to_write); + if (err) { + sflc_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); + goto out; + } + + /* Write on disk */ + err = sflc_disk_writeManySectors(bdev_path, sector, rand_chunk, blocks_to_write); + if (err) { + sflc_log_error("Could not write random bytes on disk; error %d", err); + goto out; + } + + /* Advance loop */ + sector += blocks_to_write; + blocks_remaining -= blocks_to_write; + } + + /* No prob */ + err = 0; + + +out: + free(rand_chunk); + return err; +} + diff --git a/vuvuzela-userland/src/commands/open.c b/vuvuzela-userland/src/commands/open.c new file mode 100644 index 0000000..6c58225 --- /dev/null +++ b/vuvuzela-userland/src/commands/open.c @@ -0,0 +1,183 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/disk.h" +#include "utils/file.h" +#include "utils/log.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Read the next device ID in sysfs */ +static int _getNextDevId(size_t *next_dev_id); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Open M volumes, from the first one down to the one whose pwd is provided. + * Scans the DMB cells to find which one is unlocked by the provided pwd; then, + * using the decrypted VMB key, unlocks the M-th VMB; then, iteratively using + * the prev_vmb_key field, unlocks all the previous VMBs; then, using the + * decrypted VMB keys, opens the volumes "in order" from 1 to M. + * + * @param args->bdev_path The underlying block device + * @param args->pwd The password + * @param args->pwd_len The password length + * + * @return Error code (also if no volume could be opened), 0 on success + */ +int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) +{ + int64_t dev_size; + size_t nr_slices; + sflc_DmbCell dmb_cell; + sflc_Vmb vmbs[SFLC_DEV_MAX_VOLUMES]; + size_t dev_id; + int err; + + /* Get number of slices */ + dev_size = sflc_disk_getSize(args->bdev_path); + if (dev_size < 0) { + err = -dev_size; + sflc_log_error("Could not read device size for %s; error %d", args->bdev_path, err); + return err; + } + nr_slices = sflc_disk_maxSlices(dev_size); + + /* Find volume opened by the pwd */ + err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); + if (err) { + sflc_log_error("Could not read DMB; error %d", err); + return err; + } + /* Was there one? */ + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("The provided password opens no volume on the device"); + return EINVAL; + } + printf("Password is correct! Opening volumes...\n"); + + /* Unlock VMBs "backwards" */ + int i; // Needs sign, because loop ends on i>=0 + for (i = dmb_cell.vol_idx; i >= 0; i--) { + /* Which VMB key to use? */ + char *vmb_key; + if (i == dmb_cell.vol_idx) { + // The one unlocked by pwd + vmb_key = dmb_cell.vmb_key; + } else { + // Or the prev_vmb_key from last iteration + vmb_key = vmbs[i+1].prev_vmb_key; + } + + /* Read and unlock VMB */ + err = sflc_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); + if (err) { + sflc_log_error("Could not read VMB %d on device %s; error %d", + i, args->bdev_path, err); + return err; + } + } + + /* Get the ID that will be assigned to the block device */ + err = _getNextDevId(&dev_id); + if (err) { + sflc_log_error("Could not get next device ID; error %d", err); + return err; + } + sflc_log_debug("Next device ID is %lu", dev_id); + + /* Open volumes "in order" */ + for (i = 0; i <= dmb_cell.vol_idx; i++) { + err = sflc_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); + if (err) { + sflc_log_error("Could not open volume %d; error %d. " + "Previous volumes on the device might have already " + "been opened, it's recommended you close them", + i, err); + return err; + } + sflc_log_debug("Successfully opened volume %d with VMB key", i); + printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); + } + + return 0; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Read the next device ID in sysfs */ +static int _getNextDevId(size_t *next_dev_id) +{ + char *str_nextdevid; + int err; + + /* Read sysfs entry */ + str_nextdevid = sflc_readFile(SFLC_SYSFS_NEXTDEVID); + if (!str_nextdevid) { + sflc_log_error("Could not read sysfs entry %s", SFLC_SYSFS_NEXTDEVID); + return EINVAL; + } + + /* Parse integer */ + if (sscanf(str_nextdevid, "%lu", next_dev_id) != 1) { + sflc_log_error("Error parsing content of file %s", SFLC_SYSFS_NEXTDEVID); + err = EINVAL; + goto err_devid; + } + /* Sanity check */ + if (*next_dev_id >= SFLC_TOT_MAX_DEVICES) { + sflc_log_error("There are already %d open devices, this is the maximum allowed", SFLC_TOT_MAX_DEVICES); + err = E2BIG; + goto err_devid; + } + + /* All good */ + err = 0; + + +err_devid: + free(str_nextdevid); + return err; +} + diff --git a/vuvuzela-userland/src/commands/test_pwd.c b/vuvuzela-userland/src/commands/test_pwd.c new file mode 100644 index 0000000..f794347 --- /dev/null +++ b/vuvuzela-userland/src/commands/test_pwd.c @@ -0,0 +1,59 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/file.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Tests which volume is unlocked by the given password + * + * @param args->bdev_path The underlying block device + * @param pwd The password + * @param pwd_len The password length + * + * @output dmb_cell The unlocked DMB cell + * + * @return Error code, 0 on success + */ +int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell) +{ + /* Delegate entirely to the function reading the DMB */ + return sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); +} diff --git a/vuvuzela-userland/src/header/device_master_block.c b/vuvuzela-userland/src/header/device_master_block.c new file mode 100644 index 0000000..cdd1f8c --- /dev/null +++ b/vuvuzela-userland/src/header/device_master_block.c @@ -0,0 +1,276 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "header.h" +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* AES-GCM-encrypt a VMB key with the KDF-generated key */ +static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vmb_key, char *dmb_cell); + +/* AES-GCM-decrypt a VMB key with the KDF-generated key */ +static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool *match); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Builds the on-disk device master block (indistinguishable from random). + * + * @param dmb The list of VMB keys + * @param pwds The passwords of the volumes + * @param pwd_lens Their lengths + * @param disk_block The 4096-byte buffer that will contain the random-looking + * bytes to be written on-disk + * + * @return The error code, 0 on success + */ +int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) +{ + char *salt; + int err; + + /* Sanity check */ + if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); + return EINVAL; + } + + /* Randomise whole block */ + err = sflc_rand_getWeakBytes(disk_block, SFLC_SECTOR_SIZE); + if (err) { + sflc_log_error("Could not randomise DMB; error %d", err); + return err; + } + + /* Assign salt */ + salt = disk_block; + + /* Loop over all VMB keys to encrypt them */ + size_t i; + for (i = 0; i < dmb->nr_vols; i++) { + char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); + + /* Encrypt it */ + err = _encryptVmbKeyWithPwd(salt, pwds[i], pwd_lens[i], dmb->vmb_keys[i], dmb_cell); + if (err) { + sflc_log_error("Could not encrypt VMB key number %lu; error %d", i, err); + return err; + } + } + + return 0; +} + + +/** + * "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF). + * + * @param disk_block The on-disk sealed DMB + * @param pwd The password locking the VMB key + * @param pwd_len Its length + * + * @output dmb_cell->vmb_key The unlocked VMB key + * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) + * + * @return Error code, 0 on success + */ +int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell) +{ + // KDF salt + char *salt; + // The KDF-derived key + char kek[SFLC_CRYPTO_KEYLEN]; + // The unlocked VMB key + char vmb_key[SFLC_CRYPTO_KEYLEN]; + // Error code + int err; + + /* Derive KEK once and for all */ + salt = disk_block; + err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); + if (err) { + sflc_log_error("Could not perform KDF: error %d", err); + goto bad_kdf; + } + sflc_log_debug("Successfully derived key-encryption-key with KDF"); + + /* Init dmb->vol_idx to invalid */ + dmb_cell->vol_idx = SFLC_DEV_MAX_VOLUMES; + /* Try all DMB cells */ + size_t i; + for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { + char *enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); + bool match; + + /* Try to decrypt this one */ + err = _decryptVmbKeyWithPwd(enc_dmb_cell, kek, vmb_key, &match); + if (err) { + sflc_log_error("Error decrypting DMB cell number %lu; error %d", i, err); + goto bad_decrypt; + } + + /* If MAC matched, mark it, but don't break from the loop (timing attacks) */ + if (match) { + sflc_log_debug("The provided password unlocks volume %lu", i); + dmb_cell->vol_idx = i; + memcpy(dmb_cell->vmb_key, vmb_key, SFLC_CRYPTO_KEYLEN); + } + } + + // No prob + err = 0; + + +bad_decrypt: +bad_kdf: + /* Always wipe the key from memory, even on success */ + memset(kek, 0, SFLC_CRYPTO_KEYLEN); + return err; +} + +/** + * Re-encrypt the content of the specified DMB cell. + * + * @param disk_block The on-disk sealed DMB + * @param dmb_cell The DMB cell to re-encrypt + * @param pwd The new password + * @param pwd_len The password's length + * + * @return Error code, 0 on success + */ +int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len) +{ + char *salt; + char *enc_dmb_cell; + int err; + + /* Sanity check */ + if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + return EINVAL; + } + + /* Pointers inside DMB */ + salt = disk_block; + enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLC_DMB_CELL_SIZE); + /* Encrypt with KDF-derived key */ + err = _encryptVmbKeyWithPwd(salt, pwd, pwd_len, dmb_cell->vmb_key, enc_dmb_cell); + if (err) { + sflc_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); + return err; + } + sflc_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); + + return 0; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* AES-GCM-encrypt a VMB key with the KDF-generated key */ +static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vmb_key, char *dmb_cell) +{ + // Pointers inside the block + char *iv = dmb_cell; + char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + SFLC_CRYPTO_KEYLEN; + // Key-encryption-key derived from KDF + char kek[SFLC_CRYPTO_KEYLEN]; + // Error code + int err; + + /* Derive KEK */ + err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); + if (err) { + sflc_log_error("Could not perform KDF: error %d", err); + goto bad_kdf; + } + sflc_log_debug("Successfully derived key-encryption-key with KDF"); + + /* Sample VMB_IV */ + err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); + if (err) { + sflc_log_error("Could not sample prologue IV: error %d", err); + goto bad_sample_iv; + } + sflc_log_debug("Successfully sampled prologue IV"); + + /* Encrypt the VMB key */ + err = sflc_aes256gcm_encrypt(kek, vmb_key, SFLC_CRYPTO_KEYLEN, iv, enc_vmb_key, mac); + if (err) { + sflc_log_error("Could not encrypt the VMB key: error %d", err); + goto bad_encrypt; + } + sflc_log_debug("Successfully encrypted VMB key with key-encryption-key"); + + // No prob + err = 0; + + +bad_encrypt: +bad_sample_iv: +bad_kdf: + /* Always wipe the key from memory, even on success */ + memset(kek, 0, SFLC_CRYPTO_KEYLEN); + return err; +} + +/* AES-GCM-decrypt a VMB key with the KDF-generated key */ +static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool *match) +{ + // Pointers inside the block + char *iv = dmb_cell; + char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + SFLC_CRYPTO_KEYLEN; + // Error code + int err; + + /* Decrypt the VMB key */ + err = sflc_aes256gcm_decrypt(kek, enc_vmb_key, SFLC_CRYPTO_KEYLEN, mac, iv, vmb_key, match); + if (err) { + sflc_log_error("Error while decrypting VMB key: error %d", err); + return err; + } + sflc_log_debug("Decrypted VMB key: MAC match = %d", *match); + + return 0; +} + diff --git a/vuvuzela-userland/src/header/position_map.c b/vuvuzela-userland/src/header/position_map.c new file mode 100644 index 0000000..f2b8144 --- /dev/null +++ b/vuvuzela-userland/src/header/position_map.c @@ -0,0 +1,134 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "header.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/math.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* Create an encrypted empty position map for the given number of slices. + * Allocates the internal pointers of the EPM structure. + * On failure, does not free the allocated memory. + * + * @param nr_slices The number of slices the device will be composed of. + * @param volume_key The volume's data section encryption key, used to encrypt the + * position map as well. + * @param epm The EncPosMap struct to be initialised. + * + * @return Error code, 0 on success */ +int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm) +{ + size_t nr_pmbs; + size_t nr_arrays; + int err; + + // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) + nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + // Each array holds up to 256 PosMapBlocks + nr_arrays = ceil(nr_pmbs, SFLC_BLOCKS_PER_LOG_SLICE); + + // Fill the EPM numeric fields + epm->nr_arrays = nr_arrays; + // All arrays are full except the last one + epm->nr_last_pmbs = nr_pmbs - (SFLC_BLOCKS_PER_LOG_SLICE * (nr_arrays - 1)); + + // Allocate array of IV blocks + epm->iv_blocks = malloc(nr_arrays * sizeof(char *)); + if (!epm->iv_blocks) { + sflc_log_error("Could not malloc array of IV blocks"); + err = ENOMEM; + goto out; + } + // Allocate array of PosMapBlock arrays + epm->pmb_arrays = malloc(nr_arrays * sizeof(char *)); + if (!epm->pmb_arrays) { + sflc_log_error("Could not malloc array of PosMapBlock arrays"); + err = ENOMEM; + goto out; + } + + // Loop to allocate and encrypt each array + int i; + for (i = 0; i < nr_arrays; i++) { + // The last PMB array might be smaller + size_t nr_pmbs_here = ((i == nr_arrays - 1) ? epm->nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); + size_t pmb_array_size = SFLC_SECTOR_SIZE * nr_pmbs_here; + char *iv_block; + char *pmb_array; + + // Allocate IV block + epm->iv_blocks[i] = malloc(SFLC_SECTOR_SIZE); + if (!epm->iv_blocks[i]) { + sflc_log_error("Could not allocate IV block number %d", i); + err = ENOMEM; + goto out; + } + // Allocate PosMapBlock array + epm->pmb_arrays[i] = malloc(pmb_array_size); + if (!epm->pmb_arrays[i]) { + sflc_log_error("Could not allocate PMB array number %d", i); + err = ENOMEM; + goto out; + } + // Shorthand + iv_block = epm->iv_blocks[i]; + pmb_array = epm->pmb_arrays[i]; + + // Fill the IV block with random data (can ignore return value) + sflc_rand_getWeakBytes(iv_block, SFLC_SECTOR_SIZE); + // Fill the PMB array with 0xFF + memset(pmb_array, SFLC_EPM_FILLER, pmb_array_size); + + // Loop to encrypt each PMB separately with its IV + int j; + for (j = 0; j < nr_pmbs_here; j++) { + char *iv = iv_block + (j * SFLC_AESCTR_IVLEN); + char *pmb = pmb_array + (j * SFLC_SECTOR_SIZE); + + // Encrypt in-place + err = sflc_aes256ctr_encrypt(volume_key, pmb, SFLC_SECTOR_SIZE, iv, NULL); + if (err) { + sflc_log_error("Could not encrypt PMB %d of array %d", j, i); + goto out; + } + } + } + + +out: + return err; +} diff --git a/vuvuzela-userland/src/header/volume_master_block.c b/vuvuzela-userland/src/header/volume_master_block.c new file mode 100644 index 0000000..9347582 --- /dev/null +++ b/vuvuzela-userland/src/header/volume_master_block.c @@ -0,0 +1,223 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include // Network byte order + +#include "header.h" +#include "utils/crypto.h" +#include "utils/string.h" +#include "utils/log.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Serialise the VMB before encrypting it */ +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb); + +/* Deserialise the VMB after decrypting it */ +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Builds the on-disk master block (indistinguishable from random). + * + * @param vmb The useful information stored in this volume master block + * @param vmb_key The key encrypting the VMB + * @param disk_block The 4096-byte buffer that will contain the random-looking + * bytes to be written on-disk + * + * @return The error code, 0 on success + */ +int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) +{ + // Pointers inside the block + char *iv = disk_block; + char *enc_vmb = iv + SFLC_AESCTR_IVLEN; + // Serialised VMB (dynamically allocated), to be encrypted + char *clear_vmb; + // Error code + int err; + + /* Allocate large buffer on the heap */ + clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); + if (!clear_vmb) { + sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + err = ENOMEM; + goto bad_clear_alloc; + } + sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + + /* Serialise the struct */ + _serialiseVmb(vmb, clear_vmb); + sflc_log_debug("Serialised VMB struct"); + + /* Sample VMB IV */ + err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); + if (err) { + sflc_log_error("Could not sample VMB IV: error %d", err); + goto bad_sample_iv; + } + sflc_log_debug("Successfully sampled VMB IV"); + + /* Encrypt the VMB */ + err = sflc_aes256ctr_encrypt(vmb_key, clear_vmb, SFLC_CLEAR_VMB_LEN, iv, enc_vmb); + if (err) { + sflc_log_error("Could not encrypt VMB: error %d", err); + goto bad_encrypt; + } + sflc_log_debug("Successfully encrypted VMB"); + + // No prob + err = 0; + + +bad_encrypt: +bad_sample_iv: + /* Always wipe and free the cleartext VMB, even on success */ + memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); + free(clear_vmb); +bad_clear_alloc: + return err; +} + + +/** + * Decrypt the VMB payload using the VMB key. + * + * @param disk_block The content of the on-disk encrypted VMB + * @param vmb_key The proposed VMB key to unseal its payload + * @param vmb A pointer to the output struct that will contain all the VMB fields + * + * @return An error code, 0 on success + */ +int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) +{ + // Pointers inside the block + char *iv = disk_block; + char *enc_vmb = iv + SFLC_AESCTR_IVLEN; + // Decrypted VMB (dynamically allocated), to be deserialised + char *clear_vmb; + // Error code + int err; + + /* Allocate large buffer on the heap */ + clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); + if (!clear_vmb) { + sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + err = ENOMEM; + goto bad_clear_alloc; + } + sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + + /* Decrypt the VMB */ + err = sflc_aes256ctr_decrypt(vmb_key, enc_vmb, SFLC_CLEAR_VMB_LEN, iv, clear_vmb); + if (err) { + sflc_log_error("Error while decrypting VMB: error %d", err); + goto bad_decrypt; + } + sflc_log_debug("Successfully decrypted VMB"); + + /* Deserialise the struct */ + err = _deserialiseVmb(clear_vmb, vmb); + if (err) { + sflc_log_error("Error while deserialising VMB: error %d", err); + goto bad_deserialise; + } + sflc_log_debug("Deserialised VMB struct"); + + // No prob + err = 0; + + +bad_deserialise: +bad_decrypt: + /* Always wipe and free the VMB cleartext, even on success */ + memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); + free(clear_vmb); +bad_clear_alloc: + return err; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Serialise the payload before encrypting it */ +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) +{ + // Pointers inside the VMB + char *p_vol_key = clear_vmb; + char *p_prev_vmb_key = p_vol_key + SFLC_CRYPTO_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_CRYPTO_KEYLEN; + + /* Copy the volume key */ + memcpy(p_vol_key, vmb->volume_key, SFLC_CRYPTO_KEYLEN); + + /* Copy the previous volume's VMB key */ + memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_CRYPTO_KEYLEN); + + /* Write the number of slices (network byte order) */ + *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); + + // Leave the rest uninitialised + + return; +} + + +/* Deserialise the VMB after decrypting it */ +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) +{ + // Pointers inside the VMB + char *p_vol_key = clear_vmb; + char *p_prev_vmb_key = p_vol_key + SFLC_CRYPTO_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_CRYPTO_KEYLEN; + + /* Copy the volume key */ + memcpy(vmb->volume_key, p_vol_key, SFLC_CRYPTO_KEYLEN); + + /* Copy the previous volume's VMB key */ + memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_CRYPTO_KEYLEN); + + /* Read number of slices (network byte order) */ + vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); + + // Ignore the rest + + return 0; +} + diff --git a/vuvuzela-userland/src/main.c b/vuvuzela-userland/src/main.c new file mode 100644 index 0000000..737b57e --- /dev/null +++ b/vuvuzela-userland/src/main.c @@ -0,0 +1,44 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + + +/* + * Shufflecake userland tool + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include "cli.h" + + +/***************************************************** + * MAIN * + *****************************************************/ + +int main(int argc, char **argv) +{ + return sflc_cli_dispatch(argc, argv); +} + diff --git a/vuvuzela-userland/src/operations/devmapper.c b/vuvuzela-userland/src/operations/devmapper.c new file mode 100644 index 0000000..99a66a2 --- /dev/null +++ b/vuvuzela-userland/src/operations/devmapper.c @@ -0,0 +1,111 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include + +#include "header.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/file.h" +#include "utils/string.h" +#include "utils/dm.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Build parameter list for ctor in dm_sflc, and send DM ioctl to create + * virtual block device. + * + * @param bdev_path The path to the underlying device + * @param dev_id The ID of the underlying block device + * @param vol_idx The index of the volume within the device + * @param vmb Volume metadata + * + * @return Error code, 0 on success + */ +int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb) +{ + char label[SFLC_BIGBUFSIZE]; + char *hex_key; + char params[SFLC_BIGBUFSIZE]; + uint64_t num_sectors; + int err; + + /* Build volume label */ + sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); + + /* Get the hex version of the volume's data section key */ + hex_key = sflc_toHex(vmb->volume_key, SFLC_CRYPTO_KEYLEN); + if (!hex_key) { + sflc_log_error("Could not encode volume key to hexadecimal"); + err = ENOMEM; + goto err_hexkey; + } + + /* Get the number of logical 512-byte sectors composing the volume */ + num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; + + /* Build param list */ + sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); + + /* Issue ioctl */ + err = sflc_dm_create(label, num_sectors, params); + if (err) { + sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); + goto err_dmcreate; + } + err = 0; + + +err_dmcreate: + free(hex_key); +err_hexkey: + return err; +} + + +/** + * Close the volume by issuing the appropriate ioctl to the DM. + * + * @param label The only needed parameter: the ID of the volume. + * + * @return Error code, 0 on success + */ +int sflc_ops_closeVolume(char *label) +{ + /* Issue ioctl */ + return sflc_dm_destroy(label); +} diff --git a/vuvuzela-userland/src/operations/dmb.c b/vuvuzela-userland/src/operations/dmb.c new file mode 100644 index 0000000..d529966 --- /dev/null +++ b/vuvuzela-userland/src/operations/dmb.c @@ -0,0 +1,167 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include + +#include "header.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/disk.h" +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Encrypts and writes the DMB to disk. + * + * @param bdev_path The path to the underlying block device + * @param pwds The array of passwords + * @param pwd_lens Their lengths + * @param dmb->nr_vols + * + * + * @return Error code, 0 on success + */ +int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb) +{ + /* On-disk DMB */ + char enc_dmb[SFLC_SECTOR_SIZE]; + /* Error code */ + int err; + + /* Sanity check */ + if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); + return EINVAL; + } + + /* Seal DMB */ + err = sflc_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); + if (err) { + sflc_log_error("Coul dnot seal DMB; error %d", err); + return err; + } + + /* Write it to disk (at sector 0) */ + err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); + if (err) { + sflc_log_error("Could not write DMB to disk; error %d", err); + return err; + } + + return 0; +} + + +/** + * Reads the DMB from disk and outputs the unlocked VMB key. + * + * @param bdev_path The path to the underlying block device + * @param pwd The user-provided password + * @param pwd_len Its length + * + * @output dmb_cell->vmb_key The unlocked VMB key + * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) + * + * @return Error code, 0 on success + */ +int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb) +{ + char enc_dmb[SFLC_SECTOR_SIZE]; + int err; + + /* Read DMB from disk (at sector 0) */ + err = sflc_disk_readSector(bdev_path, 0, enc_dmb); + if (err) { + sflc_log_error("Could not read DMB from disk; error %d", err); + return err; + } + + /* Unseal it */ + err = sflc_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); + if (err) { + sflc_log_error("Could not unseal DMB; error %d", err); + return err; + } + + return 0; +} + +/** + * Reads the DMB from disk, changes the relevant DMB cell, and writes it back. + * + * @param bdev_path The path to the underlying block device + * @param dmb_cell The index and vmb_key of the DMB cell to re-encrypt + * @param new_pwd The new password of the DMB cell to re-encrypt + * @param new_pwd_len Its length + * + * @return Error code, 0 on success + */ +int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) +{ + char enc_dmb[SFLC_SECTOR_SIZE]; + int err; + + /* Sanity check */ + if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + return EINVAL; + } + + /* Read DMB from disk (at sector 0) */ + err = sflc_disk_readSector(bdev_path, 0, enc_dmb); + if (err) { + sflc_log_error("Could not read DMB from disk; error %d", err); + return err; + } + + /* Update the relevant cell */ + err = sflc_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); + if (err) { + sflc_log_error("Could not update DMB cell; error %d", err); + return err; + } + + /* Write it to disk (at sector 0) */ + err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); + if (err) { + sflc_log_error("Could not write DMB to disk; error %d", err); + return err; + } + + return 0; +} + + diff --git a/vuvuzela-userland/src/operations/volume_header.c b/vuvuzela-userland/src/operations/volume_header.c new file mode 100644 index 0000000..1088290 --- /dev/null +++ b/vuvuzela-userland/src/operations/volume_header.c @@ -0,0 +1,165 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include + +#include "header.h" +#include "header.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/disk.h" +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Writes a volume header (VMB+PM) on-disk. + * + * @param bdev_path The underlying block device to write the volume header + * @param vmb_key The key to encrypt the VMB + * @param vmb The VMB to encrypt + * @param vol_idx The index of the volume within the device + * + * @return Error code, 0 on success + */ +int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) +{ + char enc_vmb[SFLC_SECTOR_SIZE]; + sflc_EncPosMap epm; + uint64_t sector; + int err; + + // Encrypt VMB + err = sflc_vmb_seal(vmb, vmb_key, enc_vmb); + if (err) { + sflc_log_error("Could not seal VMB; error %d", err); + goto out; + } + + // Write it to disk + sector = sflc_vmbPosition(vol_idx, vmb->nr_slices); + err = sflc_disk_writeSector(bdev_path, sector, enc_vmb); + if (err) { + sflc_log_error("Could not write VMB to disk; error %d", err); + goto out; + } + sector += 1; + + // Create encrypted empty position map + err = sflc_epm_create(vmb->nr_slices, vmb->volume_key, &epm); + if (err) { + sflc_log_error("Could not create encrypted empty position map; error %d", err); + goto out; + } + + // Loop over PMB arrays to write them to disk + int i; + for (i = 0; i < epm.nr_arrays; i++) { + char *iv_block = epm.iv_blocks[i]; + char *pmb_array = epm.pmb_arrays[i]; + size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); + + // First write the IV block + err = sflc_disk_writeSector(bdev_path, sector, iv_block); + if (err) { + sflc_log_error("Could not write IV block to disk; error %d", err); + goto out; + } + sector += 1; + + // Then the whole PMB array + err = sflc_disk_writeManySectors(bdev_path, sector, pmb_array, nr_pmbs); + if (err) { + sflc_log_error("Could not write PMB array to disk; error %d", err); + goto out; + } + sector += nr_pmbs; + + // Free them both + free(iv_block); + free(pmb_array); + } + + // Free containers + free(epm.iv_blocks); + free(epm.pmb_arrays); + + +out: + return err; +} + + +/** + * Reads a VMB from disk and unlocks it + * + * @param bdev_path The underlying block device + * @param vmb_key The key to decrypt the VMB + * @param nr_slices The number of slices in the device + * @param vol_idx The index of the volume within the device + * + * @output vmb The decrypted VMB + * + * @return Error code, 0 on success + */ +int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) +{ + char enc_vmb[SFLC_SECTOR_SIZE]; + uint64_t sector; + int err; + + /* Read encrypted VMB from disk */ + sector = sflc_vmbPosition(vol_idx, nr_slices); + err = sflc_disk_readSector(bdev_path, sector, enc_vmb); + if (err) { + sflc_log_error("Could not read VMB from disk; error %d", err); + return err; + } + + /* Unseal it */ + err = sflc_vmb_unseal(enc_vmb, vmb_key, vmb); + if (err) { + sflc_log_error("Could not unseal VMB; error %d", err); + return err; + } + + /* Compare the number of slices */ + if (nr_slices != vmb->nr_slices) { + sflc_log_error("Incompatible header size: the device size was different when the volumes" + "were created. Did you resize the device %s since last time?", bdev_path); + return EINVAL; + } + + return 0; +} diff --git a/vuvuzela-userland/src/utils/crypto.c b/vuvuzela-userland/src/utils/crypto.c new file mode 100644 index 0000000..b42f50f --- /dev/null +++ b/vuvuzela-userland/src/utils/crypto.c @@ -0,0 +1,424 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include + +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + *Fills the given buffer with strong random bytes, suitable for long-term + *cryptographic keys (uses the entropy pool). Always succeeds. + * + *@param buf The buffer to fill + *@param buflen The number of desired random bytes + * + *@return The error code (0 on success) + */ +int sflc_rand_getStrongBytes(char *buf, size_t buflen) +{ + gcry_randomize(buf, buflen, GCRY_VERY_STRONG_RANDOM); + return 0; +} + + +/** + *Faster than the previous one, fills the given buffer with weak random bytes, + *suitable for IVs or block filling (does not use the entropy pool). + *Always succeeds. + * + *@param buf The buffer to fill + *@param buflen The number of desired random bytes + * + *@return The error code (0 on success) + */ +int sflc_rand_getWeakBytes(char *buf, size_t buflen) +{ + gcry_create_nonce(buf, buflen); + return 0; +} + + +/** + *AES-CTR encryption, does not touch the IV. Set ct = NULL for in-place. + * + *@param key The 32-byte AES key + *@param pt The plaintext + *@param pt_len The length of the plaintext, must be a multiple of the AES + * block size (16 bytes) + *@param iv The 16-byte AES-CTR IV + *@param ct A caller-allocated buffer that will contain the output ciphertext, + * cannot overlap with pt. If NULL, in-place encryption. + * + *@return The error code (0 on success) + */ +int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +{ + gcry_cipher_hd_t hd; + gcry_error_t err; + + // Instantiate the handle + err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); + if (err) { + sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + goto bad_open; + } + sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); + + // Set the key + err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + if (err) { + sflc_log_error("Could not set AES key: error %d", err); + goto bad_setkey; + } + sflc_log_debug("Successfully set the AES key"); + + // Set the counter (not an IV, as per Gcrypt docs) + err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); + if (err) { + sflc_log_error("Could not set AES-CTR IV: error %d", err); + goto bad_setctr; + } + sflc_log_debug("Successfully set the IV"); + + // Encrypt + if (ct == NULL) { // In-place + err = gcry_cipher_encrypt(hd, pt, pt_len, NULL, 0); + } + else { // Out-of-place + err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); + } + // Error check + if (err) { + sflc_log_error("Could not encrypt: error %d", err); + goto bad_encrypt; + } + sflc_log_debug("Successfully encrypted"); + + // No prob? + err = 0; + + +bad_encrypt: +bad_setctr: +bad_setkey: + gcry_cipher_close(hd); +bad_open: + return err; +} + +/** + *AES-CTR decryption, does not touch the IV. Set pt = NULL for in-place. + * + *@param key The 32-byte AES key + *@param ct The ciphertext + *@param ct_len The length of the ciphertext, must be a multiple of the AES + * block size (16 bytes) + *@param iv The 16-byte AES-CTR IV + *@param pt A caller-allocated buffer that will contain the output plaintext, + * cannot overlap with ct. If NULL, in-place decryption. + * + *@return The error code (0 on success) + */ +int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) +{ + gcry_cipher_hd_t hd; + gcry_error_t err; + + // Instantiate the handle + err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); + if (err) { + sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + goto bad_open; + } + sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); + + // Set the key + err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + if (err) { + sflc_log_error("Could not set AES key: error %d", err); + goto bad_setkey; + } + sflc_log_debug("Successfully set AES key"); + + // Set the counter (not an IV, as per Gcrypt docs) + err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); + if (err) { + sflc_log_error("Could not set AES-CTR IV: error %d", err); + goto bad_setctr; + } + sflc_log_debug("Successfully set IV"); + + // Decrypt + if (pt == NULL) { // In-place + err = gcry_cipher_decrypt(hd, ct, ct_len, NULL, 0); + } + else { // Out-of-place + err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); + } + // Error check + if (err) { + sflc_log_error("Could not decrypt: error %d", err); + goto bad_decrypt; + } + sflc_log_debug("Successfully decrypted"); + + // No prob + err = 0; + + +bad_decrypt: +bad_setctr: +bad_setkey: + gcry_cipher_close(hd); +bad_open: + return err; +} + + +/** + *AES-GCM encryption, does not touch the IV. + * + *@param key The 32-byte AES key + *@param pt The plaintext + *@param pt_len The length of the plaintext, must be a multiple of the AES + * block size (16 bytes) + *@param iv The 12-byte AES-GCM IV + *@param ct A caller-allocated buffer that will contain the output ciphertext, + * cannot overlap with pt + *@param tag A caller-allocated buffer that will contain the 16-byte output MAC + * + *@return The error code (0 on success) + */ +int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) +{ + gcry_cipher_hd_t hd; + gcry_error_t err; + + // Instantiate the handle + err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); + if (err) { + sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + goto bad_open; + } + sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); + + // Set the key + err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + if (err) { + sflc_log_error("Could not set AES key: error %d", err); + goto bad_setkey; + } + sflc_log_debug("Successfully set the AES key"); + + // Set the IV + err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); + if (err) { + sflc_log_error("Could not set AES-GCM IV: error %d", err); + goto bad_setiv; + } + sflc_log_debug("Successfully set the IV"); + + // Encrypt + err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); + if (err) { + sflc_log_error("Could not encrypt: error %d", err); + goto bad_encrypt; + } + sflc_log_debug("Successfully encrypted"); + + // Get MAC + err = gcry_cipher_gettag(hd, tag, SFLC_AESGCM_TAGLEN); + if (err) { + sflc_log_error("Could not get MAC: error %d", err); + goto bad_gettag; + } + sflc_log_debug("Successfully gotten MAC"); + + // No prob? + err = 0; + + +bad_gettag: +bad_encrypt: +bad_setiv: +bad_setkey: + gcry_cipher_close(hd); +bad_open: + return err; +} + + +/** + *AES-GCM decryption, does not touch the IV. + * + *@param key The 32-byte AES key + *@param ct The ciphertext + *@param ct_len The length of the ciphertext, must be a multiple of the AES + * block size (16 bytes) + *@param tag The 16-byte MAC + *@param iv The 12-byte AES-GCM IV + *@param pt A caller-allocated buffer that will contain the output plaintext, + * cannot overlap with ct + *@param match A pointer to a single output boolean, indicating MAC verification + * success or failure. On failure, pt is filled with poison bytes. + * + *@return The error code (0 on success) + */ +int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) +{ + gcry_cipher_hd_t hd; + gcry_error_t err; + + // Instantiate the handle + err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); + if (err) { + sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + goto bad_open; + } + sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); + + // Set the key + err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + if (err) { + sflc_log_error("Could not set AES key: error %d", err); + goto bad_setkey; + } + sflc_log_debug("Successfully set AES key"); + + // Set the IV + err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); + if (err) { + sflc_log_error("Could not set AES-GCM IV: error %d", err); + goto bad_setiv; + } + sflc_log_debug("Successfully set IV"); + + // Decrypt + err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); + if (err) { + sflc_log_error("Could not decrypt: error %d", err); + goto bad_decrypt; + } + sflc_log_debug("Successfully decrypted"); + + // Check MAC + err = gcry_cipher_checktag(hd, tag, SFLC_AESGCM_TAGLEN); + if (gcry_err_code(err) == GPG_ERR_CHECKSUM) { + // Undo decryption + memset(pt, SFLC_AESGCM_POISON_PT, ct_len); + // Flag it + *match = false; + } + else if (err) { + sflc_log_error("Could not check MAC: error %d", err); + goto bad_checktag; + } + else { + // Flag MAC verification success + *match = true; + } + sflc_log_debug("Successfully checked MAC: match = %d", *match); + + // No prob, whether MAC verified or not + err = 0; + + +bad_checktag: +bad_decrypt: +bad_setiv: +bad_setkey: + gcry_cipher_close(hd); +bad_open: + return err; +} + + +/** + * Argon2id KDF. + * + * @param pwd The password + * @param pwd_len The length of the password + * @param salt The 16-byte KDF salt + * @param hash A caller-allocated 32-byte output buffer that will contain the + * password hash + * + * @return The error code (0 on success) + */ +int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) +{ + gcry_kdf_hd_t hd; + const unsigned long argon_params[4] = + {SFLC_CRYPTO_KEYLEN, SFLC_ARGON_T, SFLC_ARGON_M, SFLC_ARGON_P}; + gcry_error_t err; + + // Instantiate Argon2id handle + err = gcry_kdf_open( + &hd, GCRY_KDF_ARGON2, GCRY_KDF_ARGON2ID, + argon_params, 4, + pwd, pwd_len, + salt, SFLC_ARGON_SALTLEN, + NULL, 0, /* Optional secret value K */ + NULL, 0 /* Optional associated data X */ + ); + if (err) { + sflc_log_error("Could not open Argon2id handle: error %d", err); + goto bad_open; + } + sflc_log_debug("Successfully opened Argon2id handle"); + + // Run the computation + err = gcry_kdf_compute(hd, NULL); + if (err) { + sflc_log_error("Could not run Argon2id computation: error %d", err); + goto bad_compute; + } + sflc_log_debug("Successfully run Argon2id computation"); + + // Finalise hash + err = gcry_kdf_final(hd, SFLC_CRYPTO_KEYLEN, hash); + if (err) { + sflc_log_error("Could not finalise Argon2id hash: error %d", err); + goto bad_final; + } + sflc_log_debug("Successfully finalised Argon2id hash"); + + // All in order + err = 0; + + +bad_final: +bad_compute: + gcry_kdf_close(hd); +bad_open: + return err; +} diff --git a/vuvuzela-userland/src/utils/disk.c b/vuvuzela-userland/src/utils/disk.c new file mode 100644 index 0000000..2f78598 --- /dev/null +++ b/vuvuzela-userland/src/utils/disk.c @@ -0,0 +1,257 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * Disk helper functions + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/disk.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + + +/** + * Checks whether the given path points to a block device. + * + * @param path The path to check + * + * @return true iff it's a block device + */ +bool sflc_disk_isBlockDevice(char *path) +{ + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return false; + } + return S_ISBLK(path_stat.st_mode); +} + +/** + * Returns the size in 4096-byte sectors (or < 0 if error). + * + * @param bdev_path The path of the block device + * + * @return The size (in 4096-byte sectors) of the disk, or -errno if error + */ +int64_t sflc_disk_getSize(char * bdev_path) +{ + int fd; + uint64_t size_bytes; + int64_t ret; + + /* Open file */ + fd = open(bdev_path, O_RDONLY); + if (fd < 0) { + sflc_log_error("Could not open file %s", bdev_path); + perror("Cause: "); + ret = -errno; + goto bad_open; + } + sflc_log_debug("Opened file %s", bdev_path); + + /* Get size in bytes */ + if (ioctl(fd, BLKGETSIZE64, &size_bytes) < 0) { + sflc_log_error("Could not ioctl file %s", bdev_path); + perror("Cause: "); + ret = -errno; + goto bad_ioctl; + } + sflc_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); + + /* Compute size in SFLC sectors */ + ret = (size_bytes / SFLC_SECTOR_SIZE); + +bad_ioctl: + close(fd); +bad_open: + return ret; +} + +/** + * Reads a single 4096-byte sector from the disk. + * + * @param bdev_path The path of the block device + * @param sector The index of the desired sector + * @param The caller-allocated buffer (must hold 4096 bytes) where the data + * from the disk will go + * + * @return The error code (0 on success) + */ +int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf) +{ + int fd; + int err; + + /* Open file */ + fd = open(bdev_path, O_RDONLY); + if (fd < 0) { + sflc_log_error("Could not open file %s", bdev_path); + perror("Cause: "); + err = errno; + goto bad_open; + } + sflc_log_debug("Opened file %s", bdev_path); + + /* Set offset in bytes */ + if (lseek(fd, sector * SFLC_SECTOR_SIZE, SEEK_SET) < 0) { + sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + perror("Cause: "); + err = errno; + goto bad_lseek; + } + sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + + /* Read in a loop */ + size_t bytes_to_read = SFLC_SECTOR_SIZE; + while (bytes_to_read > 0) { + /* Read syscall */ + ssize_t bytes_read = read(fd, buf, bytes_to_read); + if (bytes_read < 0) { + sflc_log_error("Could not read file %s at sector %lu", bdev_path, sector); + perror("Cause: "); + err = errno; + goto bad_read; + } + + /* Partial read? No problem just log */ + if (bytes_read < bytes_to_read) { + sflc_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", + bdev_path, sector, bytes_read, bytes_to_read); + } + + /* Advance loop */ + bytes_to_read -= bytes_read; + buf += bytes_read; + } + + // No prob + err = 0; + +bad_read: +bad_lseek: + close(fd); +bad_open: + return err; +} + + +/** + * Writes a single 4096-byte sector to the disk. + * + * @param bdev_path The path of the block device + * @param sector The index of the desired sector + * @param The caller-allocated buffer (must hold 4096 bytes) where the data + * comes from + * + * @return The error code (0 on success) + */ +int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf) +{ + return sflc_disk_writeManySectors(bdev_path, sector, buf, 1); +} + + +/** + * Writes many 4096-byte sectors to the disk. + * + * @param bdev_path The path of the block device + * @param sector The index of the starting sector + * @param The caller-allocated buffer where the data + * comes from + * @param num_sectors The number of sectors to write + * + * @return The error code (0 on success) + */ +int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) +{ + int fd; + int err; + + /* Open file */ + fd = open(bdev_path, O_WRONLY); + if (fd < 0) { + sflc_log_error("Could not open file %s", bdev_path); + perror("Cause: "); + err = errno; + goto bad_open; + } + sflc_log_debug("Opened file %s", bdev_path); + + /* Set offset in bytes */ + if (lseek(fd, sector * SFLC_SECTOR_SIZE, SEEK_SET) < 0) { + sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + perror("Cause: "); + err = errno; + goto bad_lseek; + } + sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + + /* Write in a loop */ + size_t bytes_to_write = SFLC_SECTOR_SIZE * num_sectors; + while (bytes_to_write > 0) { + /* Write syscall */ + ssize_t bytes_written = write(fd, buf, bytes_to_write); + if (bytes_written < 0) { + sflc_log_red("Could not write file %s at sector %lu", bdev_path, sector); + perror("Cause: "); + err = errno; + goto bad_write; + } + + /* Partial write? No problem just log */ + if (bytes_written < bytes_to_write) { + sflc_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", + bdev_path, sector, bytes_written, bytes_to_write); + } + + /* Advance loop */ + bytes_to_write -= bytes_written; + buf += bytes_written; + } + + // No prob + err = 0; + +bad_write: +bad_lseek: + close(fd); +bad_open: + return err; +} diff --git a/vuvuzela-userland/src/utils/dm.c b/vuvuzela-userland/src/utils/dm.c new file mode 100644 index 0000000..6c2d054 --- /dev/null +++ b/vuvuzela-userland/src/utils/dm.c @@ -0,0 +1,203 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + + +/** + * Interface to the device mapper. The only example I could find is the + * cryptsetup source, at + * https://kernel.googlesource.com/pub/scm/utils/cryptsetup/cryptsetup/+/v1_6_3/lib/libdevmapper.c + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include + +#include "utils/dm.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Create a new Shufflecake virtual device (volume) under /dev/mapper. + * + * @param virt_dev_name The name of the new virtual device, as it will appear + * under /dev/mapper + * @param num_sectors The size of the virtual device, in 512-byte sectors + * @param params The string containing the space-separated paramters that will + * be passed to the Shufflecake constructor in the kernel module + * + * @return The error code (0 on success) + */ +int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) +{ + struct dm_task *dmt; + uint32_t cookie = 0; + uint16_t udev_flags = 0; + int err; + + /* Just to be sure, let's get them on the heap */ + char * dup_virt_dev_name = strdup(virt_dev_name); + char * dup_params = strdup(params); + + sflc_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); + + /* Instantiate the DM task (with the CREATE ioctl command) */ + if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) { + sflc_log_error("Cannot create dm_task"); + err = 1; + goto dup_free; + } + sflc_log_debug("Successfully created dm_task"); + + /* Set the name of the target device (to be created) */ + if (!dm_task_set_name(dmt, dup_virt_dev_name)) { + sflc_log_error("Cannot set device name"); + err = 2; + goto out; + } + sflc_log_debug("Successfully set device name"); + + /* State that it is a Shufflecake device, pass the start and size, and the + * constructor parameters */ + if (!dm_task_add_target(dmt, 0, num_sectors, SFLC_DM_TARGET_NAME, dup_params)) { + sflc_log_error("Cannot add DM target and parameters"); + err = 3; + goto out; + } + sflc_log_debug("Successfully added DM target and parameters"); + + /* Say that we want a new node under /dev/mapper */ + if (!dm_task_set_add_node(dmt, DM_ADD_NODE_ON_CREATE)) { + sflc_log_error("Cannot add /dev/mapper node"); + err = 4; + goto out; + } + sflc_log_debug("Successfully set the ADD_NODE flag"); + + /* Get a cookie (request ID, basically) to wait for task completion */ + if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { + sflc_log_error("Cannot get cookie"); + err = 5; + goto out; + } + sflc_log_debug("Successfully got a cookie"); + + /* Run the task */ + if (!dm_task_run(dmt)) { + sflc_log_error("Cannot issue ioctl"); + err = 6; + goto out; + } + sflc_log_debug("Successfully run DM task"); + + /* Wait for completion */ + dm_udev_wait(cookie); + sflc_log_debug("Task completed"); + + // No prob + err = 0; + +out: + dm_task_destroy(dmt); +dup_free: + free(dup_virt_dev_name); + free(dup_params); + + return err; +} + +/** + * Close a Shufflecake virtual device (volume) under /dev/mapper. + * + * @param virt_dev_name the name of the virtual device, as it appears under + * /dev/mapper + * + * @return error code (0 on success) + */ +int sflc_dm_destroy(char * virt_dev_name) +{ + struct dm_task *dmt; + uint32_t cookie = 0; + uint16_t udev_flags = 0; + int err = 0; + + /* Just to be sure, let's get it on the heap */ + char * dup_virt_dev_name = strdup(virt_dev_name); + + sflc_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); + + /* Instantiate the DM task (with the REMOVE ioctl command) */ + if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) { + sflc_log_error("Cannot create dm_task"); + err = 1; + goto dup_free; + } + sflc_log_debug("Successfully created dm_task"); + + /* Set the name of the target device (to be closed) */ + if (!dm_task_set_name(dmt, dup_virt_dev_name)) { + sflc_log_error("Cannot set device name"); + err = 2; + goto out; + } + sflc_log_debug("Successfully set device name"); + + /* Get a cookie (request ID, basically) to wait for task completion */ + if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { + sflc_log_error("Cannot set cookie"); + err = 3; + goto out; + } + sflc_log_debug("Successfully got a cookie"); + + /* Needed for some reason */ + dm_task_retry_remove(dmt); + sflc_log_debug("Successful retry_remove"); + + /* Run the task */ + if (!dm_task_run(dmt)) { + sflc_log_error("Cannot issue ioctl"); + err = 4; + goto out; + } + sflc_log_debug("Successfully run task"); + + /* Wait for completion */ + dm_udev_wait(cookie); + sflc_log_debug("Task completed"); + + // No prob + err = 0; + +out: + dm_task_destroy(dmt); +dup_free: + free(dup_virt_dev_name); + + return err; +} diff --git a/vuvuzela-userland/src/utils/file.c b/vuvuzela-userland/src/utils/file.c new file mode 100644 index 0000000..a8e70e2 --- /dev/null +++ b/vuvuzela-userland/src/utils/file.c @@ -0,0 +1,81 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "utils/file.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* Reads the entire content of a file in a malloc-ed string */ +char *sflc_readFile(char *path) +{ + int filesize; + FILE *fp; + char *content; + + /* Open file */ + fp = fopen(path, "r"); + if (fp == NULL) { + sflc_log_error("Could not open file %s", path); + perror("Reason: "); + goto bad_fopen; + } + + /* Get size (overestimated) */ + fseek(fp, 0L, SEEK_END); + filesize = ftell(fp); + rewind(fp); + + /* Allocate */ + content = malloc(filesize + 1); + if (content == NULL) { + sflc_log_error("Could not malloc %d bytes for file content", filesize); + goto bad_malloc; + } + + /* Read (adjust filesize) */ + filesize = fread(content, 1, filesize, fp); + content[filesize] = '\0'; + + /* Close */ + fclose(fp); + + return content; + + +bad_malloc: + fclose(fp); +bad_fopen: + return NULL; +} diff --git a/vuvuzela-userland/src/utils/input.c b/vuvuzela-userland/src/utils/input.c new file mode 100644 index 0000000..ffc0b02 --- /dev/null +++ b/vuvuzela-userland/src/utils/input.c @@ -0,0 +1,101 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* Reads a line (discarding the newline) from stdin. No buffer overflow */ +int sflc_safeReadLine(char *buf, size_t bufsize) +{ + size_t len; + + /* Read from stdin */ + if (fgets(buf, bufsize, stdin) == NULL) { + sflc_log_error("Could not read from stdin"); + return EBADFD; + } + + /* Discard newline */ + len = strlen(buf); + if (buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } + + return 0; +} + + +/* Reads a password/passphrase in a secure way (no echo) */ +int sflc_safeReadPassphrase(char *buf, size_t bufsize) +{ + size_t len; + struct termios old, new; + + fflush(stdout); // Ensure stdout is flushed is printed immediately + + // Turn off echoing + tcgetattr(STDIN_FILENO, &old); + new = old; + new.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &new); + + /* Read from stdin */ + if (fgets(buf, bufsize, stdin) == NULL) { + // If reading the password failed, ensure echoing is turned back on + tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); + sflc_log_error("Could not read from stdin"); + return EBADFD; + } + + // Turn echoing back on + tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); + + /* Discard newline */ + len = strlen(buf); + if (buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } + + /* Newline on screen */ + printf("\n"); + + return 0; +} + + diff --git a/vuvuzela-userland/src/utils/string.c b/vuvuzela-userland/src/utils/string.c new file mode 100644 index 0000000..c6cf998 --- /dev/null +++ b/vuvuzela-userland/src/utils/string.c @@ -0,0 +1,74 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "utils/string.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* Malloc's the buffer for the hex string */ +char *sflc_toHex(char *buf, size_t len) +{ + unsigned char *u = (unsigned char *) buf; + char *hex; + + /* Allocate buffer */ + hex = malloc((len * 2) + 1); + if (!hex) { + sflc_log_error("Could not allocate buffer for hex string"); + return NULL; + } + + /* To hex */ + int i; + for(i = 0; i < len; i++) { + sprintf(hex + (i * 2), "%02x", u[i]); + } + hex[len*2] = '\0'; + + return hex; +} + + +void sflc_str_replaceAll(char * str, char old, char new) +{ + int i; + for (i = 0; str[i] != '\0'; i++) { + if (str[i] == old) { + str[i] = new; + } + } + + return; +} diff --git a/vuvuzela-userland/test/crypto/test_aes256ctr.c b/vuvuzela-userland/test/crypto/test_aes256ctr.c new file mode 100644 index 0000000..700a910 --- /dev/null +++ b/vuvuzela-userland/test/crypto/test_aes256ctr.c @@ -0,0 +1,178 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +#include "utils/crypto.h" +#include "test_aes256ctr.h" +#include "minunit.h" +#include "utils/log.h" + + +/***************************************************** + * CONSTANT VARIABLES * + *****************************************************/ + +static const char KEY[] = AES256CTR_TEST_KEY; +static const char IV[] = AES256CTR_TEST_IV; +static const char PT[] = AES256CTR_TEST_PT; +static const char CT[] = AES256CTR_TEST_CT; + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +char *test_aes256ctr_encrypt_inplace() +{ + char msg[] = AES256CTR_TEST_PT; + size_t msg_len = sizeof(msg); + char key[] = AES256CTR_TEST_KEY; + char iv[] = AES256CTR_TEST_IV; + int err; + + sflc_log_blue("Testing AES256-CTR encryption in-place"); + + // Encrypt in-place + err = sflc_aes256ctr_encrypt(key, msg, msg_len, iv, NULL); + + // Check error + mu_assert("Error while encrypting", !err); + + // Check outcome + mu_assert("Ciphertext mismatch", memcmp(msg, CT, msg_len) == 0); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + sflc_log_green("OK"); + + return NULL; +} + +char *test_aes256ctr_encrypt_outofplace() +{ + char msg[] = AES256CTR_TEST_PT; + char ct[sizeof(msg)]; + size_t msg_len = sizeof(msg); + char key[] = AES256CTR_TEST_KEY; + char iv[] = AES256CTR_TEST_IV; + int err; + + sflc_log_blue("Testing AES256-CTR encryption out-of-place"); + + // Encrypt out-of-place + err = sflc_aes256ctr_encrypt(key, msg, msg_len, iv, ct); + + // Check error + mu_assert("Error while encrypting", !err); + + // Check outcome + mu_assert("Ciphertext mismatch", memcmp(ct, CT, msg_len) == 0); + + // Check msg untouched + mu_assert("Plaintext changed", memcmp(msg, PT, sizeof(key)) == 0); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + sflc_log_green("OK"); + + return NULL; +} + +char *test_aes256ctr_decrypt_inplace() +{ + char msg[] = AES256CTR_TEST_CT; + size_t msg_len = sizeof(msg); + char key[] = AES256CTR_TEST_KEY; + char iv[] = AES256CTR_TEST_IV; + int err; + + sflc_log_blue("Testing AES256-CTR decryption in-place"); + + // Decrypt in-place + err = sflc_aes256ctr_decrypt(key, msg, msg_len, iv, NULL); + + // Check error + mu_assert("Error while decrypting", !err); + + // Check outcome + mu_assert("Plaintext mismatch", memcmp(msg, PT, msg_len) == 0); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + sflc_log_green("OK"); + + return NULL; +} + +char *test_aes256ctr_decrypt_outofplace() +{ + char msg[] = AES256CTR_TEST_CT; + char pt[sizeof(msg)]; + size_t msg_len = sizeof(msg); + char key[] = AES256CTR_TEST_KEY; + char iv[] = AES256CTR_TEST_IV; + int err; + + sflc_log_blue("Testing AES256-CTR decryption out-of-place"); + + // Decrypt out-of-place + err = sflc_aes256ctr_decrypt(key, msg, msg_len, iv, pt); + + // Check error + mu_assert("Error while decrypting", !err); + + // Check outcome + mu_assert("Plaintext mismatch", memcmp(pt, PT, msg_len) == 0); + + // Check msg untouched + mu_assert("Ciphertext changed", memcmp(msg, CT, sizeof(key)) == 0); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + sflc_log_green("OK"); + + return NULL; +} + diff --git a/vuvuzela-userland/test/crypto/test_aes256ctr.h b/vuvuzela-userland/test/crypto/test_aes256ctr.h new file mode 100644 index 0000000..c1070f8 --- /dev/null +++ b/vuvuzela-userland/test/crypto/test_aes256ctr.h @@ -0,0 +1,85 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +// Test vectors taken from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf + +#ifndef _TEST_CRYPTO_AES256CTR_H_ +#define _TEST_CRYPTO_AES256CTR_H_ + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +#define AES256CTR_TEST_KEY \ +{ \ + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, \ + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, \ + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, \ + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 \ +} + +#define AES256CTR_TEST_IV \ +{ \ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, \ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff \ +} + +#define AES256CTR_TEST_PT \ +{ \ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, \ + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, \ + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, \ + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, \ + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, \ + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, \ + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, \ + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 \ +} + +#define AES256CTR_TEST_CT \ +{ \ + 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, \ + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, \ + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, \ + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, \ + 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, \ + 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, \ + 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, \ + 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6 \ +} + + +/***************************************************** + * PUBLIC FUNCTIONS DECLARATIONS * + *****************************************************/ + +// Exported test cases + +char *test_aes256ctr_encrypt_inplace(); +char *test_aes256ctr_encrypt_outofplace(); +char *test_aes256ctr_decrypt_inplace(); +char *test_aes256ctr_decrypt_outofplace(); + + +#endif /* _TEST_CRYPTO_AES256CTR_H_ */ diff --git a/vuvuzela-userland/test/crypto/test_aes256gcm.c b/vuvuzela-userland/test/crypto/test_aes256gcm.c new file mode 100644 index 0000000..b332c51 --- /dev/null +++ b/vuvuzela-userland/test/crypto/test_aes256gcm.c @@ -0,0 +1,160 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +#include "utils/crypto.h" +#include "test_aes256gcm.h" +#include "minunit.h" +#include "utils/log.h" + + +/***************************************************** + * CONSTANT VARIABLES * + *****************************************************/ + +static const char KEY[] = AES256GCM_TEST_KEY; +static const char IV[] = AES256GCM_TEST_IV; +static const char PT[] = AES256GCM_TEST_PT; +static const char CT[] = AES256GCM_TEST_CT; +static const char TAG[] = AES256GCM_TEST_TAG; + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +char *test_aes256gcm_encrypt() +{ + char pt[] = AES256GCM_TEST_PT; + size_t pt_len = sizeof(pt); + char key[] = AES256GCM_TEST_KEY; + char iv[] = AES256GCM_TEST_IV; + char ct[sizeof(pt)]; + char tag[SFLC_AESGCM_TAGLEN]; + int err; + + sflc_log_blue("Testing AES256-GCM encryption"); + + // Encrypt + err = sflc_aes256gcm_encrypt(key, pt, pt_len, iv, ct, tag); + + // Check error + mu_assert("Error while encrypting", !err); + + // Check outcome + mu_assert("Ciphertext mismatch", memcmp(ct, CT, pt_len) == 0); + mu_assert("MAC mismatch", memcmp(tag, TAG, SFLC_AESGCM_TAGLEN) == 0); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + sflc_log_green("OK"); + + return NULL; +} + +char *test_aes256gcm_decrypt_good() +{ + char ct[] = AES256GCM_TEST_CT; + size_t ct_len = sizeof(ct); + char tag[] = AES256GCM_TEST_TAG; + char key[] = AES256GCM_TEST_KEY; + char iv[] = AES256GCM_TEST_IV; + bool match; + char pt[sizeof(ct)]; + int err; + + sflc_log_blue("Testing AES256-GCM decryption with the proper MAC"); + + // Decrypt + err = sflc_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); + + // Check error + mu_assert("Error while decrypting", !err); + + // Check outcome + mu_assert("MAC verification failed", match); + mu_assert("Plaintext mismatch", memcmp(pt, PT, ct_len) == 0); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + // Check MAC untouched + mu_assert("MAC changed", memcmp(tag, TAG, sizeof(tag)) == 0); + + sflc_log_green("OK"); + + return NULL; +} + +char *test_aes256gcm_decrypt_fail() +{ + char ct[] = AES256GCM_TEST_CT; + size_t ct_len = sizeof(ct); + char tag[] = AES256GCM_TEST_TAG; + char key[] = AES256GCM_TEST_KEY; + char iv[] = AES256GCM_TEST_IV; + bool match; + char pt[sizeof(ct)]; + int err; + + sflc_log_blue("Testing AES256-GCM decryption without the proper MAC"); + + // Corrupt the MAC + tag[0] += 1; + + // Decrypt + err = sflc_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); + + // Check error + mu_assert("Error while decrypting", !err); + + // Check outcome + mu_assert("MAC verification succeeded", !match); + + // Check key untouched + mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); + + // Check IV untouched + mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); + + // Check MAC untouched + mu_assert("Tail of MAC changed", memcmp(tag+1, TAG+1, sizeof(tag)-1) == 0); + mu_assert("Head of MAC changed", tag[0] == TAG[0]+1); + + sflc_log_green("OK"); + + return NULL; +} diff --git a/vuvuzela-userland/test/crypto/test_aes256gcm.h b/vuvuzela-userland/test/crypto/test_aes256gcm.h new file mode 100644 index 0000000..9ad445b --- /dev/null +++ b/vuvuzela-userland/test/crypto/test_aes256gcm.h @@ -0,0 +1,91 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +// Test vectors taken from test case 15 at +// https://luca-giuzzi.unibs.it/corsi/Support/papers-cryptography/gcm-spec.pdf + +#ifndef _TEST_CRYPTO_AES256GCM_H_ +#define _TEST_CRYPTO_AES256GCM_H_ + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +#define AES256GCM_TEST_KEY \ +{ \ + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, \ + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, \ + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, \ + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 \ +} + +#define AES256GCM_TEST_IV \ +{ \ + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, \ + 0xde, 0xca, 0xf8, 0x88 \ +} + +#define AES256GCM_TEST_PT \ +{ \ + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, \ + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, \ + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, \ + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, \ + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, \ + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, \ + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, \ + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 \ +} + +#define AES256GCM_TEST_CT \ +{ \ + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, \ + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, \ + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, \ + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, \ + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, \ + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, \ + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, \ + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad, \ +} + +#define AES256GCM_TEST_TAG \ +{ \ + 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, \ + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c, \ +} + + +/***************************************************** + * PUBLIC FUNCTIONS DECLARATIONS * + *****************************************************/ + +// Exported test cases + +char *test_aes256gcm_encrypt(); +char *test_aes256gcm_decrypt_good(); +char *test_aes256gcm_decrypt_fail(); + + +#endif /* _TEST_CRYPTO_AES256GCM_H_ */ diff --git a/vuvuzela-userland/test/crypto/test_argon2id.c b/vuvuzela-userland/test/crypto/test_argon2id.c new file mode 100644 index 0000000..0ded58b --- /dev/null +++ b/vuvuzela-userland/test/crypto/test_argon2id.c @@ -0,0 +1,83 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include + +#include "utils/crypto.h" +#include "test_argon2id.h" +#include "minunit.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * CONSTANT VARIABLES * + *****************************************************/ + +char SALT[SFLC_ARGON_SALTLEN+1] = "Poor Petrol Pump"; + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +char *test_argon2id() +{ + char pwd[SFLC_BIGBUFSIZE]; + char key[SFLC_CRYPTO_KEYLEN]; + int err; + + sflc_log_blue("Testing Argon2id interactively with a fixed salt"); + + // Loop until user breaks out + while (true) { + /* Collect password */ + printf("Choose password to hash (empty to skip): "); + err = sflc_safeReadLine(pwd, SFLC_BIGBUFSIZE); + mu_assert("Could not read password", !err); + + /* Check if empty */ + if (strlen(pwd) == 0) { + break; + } + + /* Hash it */ + err = sflc_argon2id_derive(pwd, strlen(pwd), SALT, key); + mu_assert("Could not hash password", !err); + + /* Print it */ + printf("Salt used ASCII: \"%s\". Hex:\n", SALT); + sflc_log_hex(SALT, SFLC_ARGON_SALTLEN); + printf("Argon2id hash (m = %d, t = %d, p = %d):\n", + SFLC_ARGON_M, SFLC_ARGON_T, SFLC_ARGON_P); + sflc_log_hex(key, SFLC_CRYPTO_KEYLEN); + printf("Go check the result online\n\n"); + } + + return NULL; +} diff --git a/vuvuzela-userland/test/crypto/test_argon2id.h b/vuvuzela-userland/test/crypto/test_argon2id.h new file mode 100644 index 0000000..12bd2c0 --- /dev/null +++ b/vuvuzela-userland/test/crypto/test_argon2id.h @@ -0,0 +1,43 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + + +#ifndef _TEST_CRYPTO_ARGON2ID_H_ +#define _TEST_CRYPTO_ARGON2ID_H_ + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + + +/***************************************************** + * PUBLIC FUNCTIONS DECLARATIONS * + *****************************************************/ + +// Exported test cases + +char *test_argon2id(); + + +#endif /* _TEST_CRYPTO_ARGON2ID_H_ */ diff --git a/vuvuzela-userland/test/main.c b/vuvuzela-userland/test/main.c new file mode 100644 index 0000000..565aa2c --- /dev/null +++ b/vuvuzela-userland/test/main.c @@ -0,0 +1,80 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + + +#include "crypto/test_aes256ctr.h" +#include "crypto/test_aes256gcm.h" +#include "crypto/test_argon2id.h" +#include "minunit.h" +#include "utils/log.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +static char *all_tests(); + + +/***************************************************** + * MAIN * + *****************************************************/ + +int main() +{ + char *result = all_tests(); + + if (result != NULL) { + sflc_log_red("\nTEST FAILED: %s", result); + } + else { + sflc_log_green("\nALL TESTS PASSED"); + } + + return result != NULL; +} + + +/***************************************************** + * PRIVATE FUNCTIONS DEFINITIONS * + *****************************************************/ + +static char *all_tests() +{ + sflc_log_yellow("Running crypto tests"); + mu_run_test(test_aes256ctr_encrypt_inplace); + mu_run_test(test_aes256ctr_encrypt_outofplace); + mu_run_test(test_aes256ctr_decrypt_inplace); + mu_run_test(test_aes256ctr_decrypt_outofplace); + mu_run_test(test_aes256gcm_encrypt); + mu_run_test(test_aes256gcm_decrypt_good); + mu_run_test(test_aes256gcm_decrypt_fail); + mu_run_test(test_argon2id); + + return 0; +} + diff --git a/vuvuzela-userland/test/minunit.h b/vuvuzela-userland/test/minunit.h new file mode 100644 index 0000000..4181aa1 --- /dev/null +++ b/vuvuzela-userland/test/minunit.h @@ -0,0 +1,10 @@ +// MinUnit -- a minimal unit testing framework for C. Slightly modified. +// https://jera.com/techinfo/jtns/jtn002 + +#ifndef _MINUNIT_H_ +#define _MINUNIT_H_ + +#define mu_assert(message, test) do { if (!(test)) return message; } while (0) +#define mu_run_test(test) do { char *message = test(); if (message) return message; } while (0) + +#endif // _MINUNIT_H_ From 2eefd23e189ea74f4271fbc6f31be6840706a525 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 7 Apr 2024 23:54:42 +0200 Subject: [PATCH 44/75] Fix EPM --- vuvuzela-userland/include/header.h | 51 ++++----- vuvuzela-userland/include/operations.h | 23 ---- vuvuzela-userland/include/utils/crypto.h | 17 +-- vuvuzela-userland/include/utils/disk.h | 68 +++++------- vuvuzela-userland/include/utils/input.h | 2 +- vuvuzela-userland/include/utils/sflc.h | 27 ++--- vuvuzela-userland/src/commands/init.c | 12 +-- .../src/header/device_master_block.c | 22 ++-- vuvuzela-userland/src/header/position_map.c | 100 +++++------------- .../src/header/volume_master_block.c | 16 +-- vuvuzela-userland/src/operations/devmapper.c | 4 +- vuvuzela-userland/src/operations/dmb.c | 14 +-- .../src/operations/volume_header.c | 12 +-- vuvuzela-userland/src/utils/crypto.c | 82 ++++++++++++-- vuvuzela-userland/src/utils/disk.c | 30 ++---- vuvuzela-userland/test/crypto/test_argon2id.c | 4 +- 16 files changed, 219 insertions(+), 265 deletions(-) diff --git a/vuvuzela-userland/include/header.h b/vuvuzela-userland/include/header.h index 869b868..32d5596 100644 --- a/vuvuzela-userland/include/header.h +++ b/vuvuzela-userland/include/header.h @@ -40,16 +40,16 @@ *****************************************************/ /* The DMB contains one IV + one VMB key + one MAC for each volume */ -#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_CRYPTO_KEYLEN + SFLC_AESGCM_TAGLEN) +#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_STANDARD_KEYLEN + SFLC_AESGCM_TAGLEN) /* Let us enforce that the one DMB can fit cells for all volumes */ -#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL) > SFLC_SECTOR_SIZE +#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL_SIZE) > SFLC_BLOCK_SIZE #error "Invalid combination of parameters: probably SFLC_DEV_MAX_VOLUMES is too big" #endif // The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) -#define SFLC_CLEAR_VMB_LEN (SFLC_SECTOR_SIZE - \ +#define SFLC_CLEAR_VMB_LEN (SFLC_BLOCK_SIZE - \ SFLC_AESGCM_PADDED_IVLEN - \ SFLC_AESGCM_TAGLEN) @@ -66,7 +66,7 @@ */ typedef struct { // Each volume's VMB key - char vmb_keys[SFLC_DEV_MAX_VOLUMES][SFLC_CRYPTO_KEYLEN]; + char vmb_keys[SFLC_DEV_MAX_VOLUMES][SFLC_STANDARD_KEYLEN]; // How many of these need actually be encrypted size_t nr_vols; @@ -80,7 +80,7 @@ typedef struct { */ typedef struct { // The unlocked VMB key - char vmb_key[SFLC_CRYPTO_KEYLEN]; + char vmb_key[SFLC_STANDARD_KEYLEN]; // The index of the volume opened by this VMB key size_t vol_idx; @@ -95,10 +95,10 @@ typedef struct { */ typedef struct { // The key that encrypts the volume's data section - char volume_key[SFLC_CRYPTO_KEYLEN]; + char volume_key[SFLC_STANDARD_KEYLEN]; // The key that encrypts the previous volume's master block - char prev_vmb_key[SFLC_CRYPTO_KEYLEN]; + char prev_vmb_key[SFLC_STANDARD_KEYLEN]; // The total number of logical slices virtually available to this volume size_t nr_slices; @@ -106,33 +106,18 @@ typedef struct { } sflc_Vmb; -/** - * This struct represents an encrypted empty position map. - * On-disk, the layout interleaves one IV block with 256 PosMap blocks (each - * encrypted by an IV in the IV block). Many such "runs" can be concatenated, - * until the position map is big enough to index the desired number of slices. - * The last "run" might be incomplete, in that it could have less than 256 - * PosMap blocks, if not all of them are needed. - * In the struct, there are as many IV blocks as there are PosMapBlock arrays - * (equal to the number of "runs"). The m-th IV of the n-th IV block encrypts - * the m-th block of the n-th array. The PosMapBlocks in an array are stored - * contiguously in RAM, so a PosMapBlock array is just a char array of length - * multiple of 4096. All the arrays are full (256 PosMapBlocks, 1 MiB) except - * for the last one, which may hold fewer blocks. - */ -typedef struct { - // The number of PosMapBlock arrays (and of IV blocks) - size_t nr_arrays; +/***************************************************** + * INLINE FUNCTIONS * + *****************************************************/ - // The sequence of IV blocks - char **iv_blocks; - // The sequence of (encrypted) PosMapBlock arrays - char **pmb_arrays; - // The number of PosMapBlocks in the last array - size_t nr_last_pmbs; - -} sflc_EncPosMap; +// Starting block of a volume's position map +static inline uint64_t sflc_pmStartBlock(size_t vol_idx, size_t nr_slices) +{ + return 1 + + SFLC_DEV_MAX_VOLUMES + + vol_idx*ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); +} /***************************************************** @@ -154,7 +139,7 @@ int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); /* Create an encrypted empty position map for the given number of slices (allocates memory) */ -int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm); +void *sflc_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key); diff --git a/vuvuzela-userland/include/operations.h b/vuvuzela-userland/include/operations.h index 8de9ab6..13bebde 100644 --- a/vuvuzela-userland/include/operations.h +++ b/vuvuzela-userland/include/operations.h @@ -37,29 +37,6 @@ #include "utils/math.h" -/***************************************************** - * INLINE FUNCTIONS * - *****************************************************/ - -// Size, in 4096-byte blocks, of a whole volume header (VMB+PM) -static inline size_t sflc_volHeaderSize(size_t nr_slices) -{ - // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) - size_t nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); - // Each array holds up to 256 PosMapBlocks - size_t nr_arrays = ceil(nr_pmbs, SFLC_BLOCKS_PER_LOG_SLICE); - - // 1 VMB, the PMBs, and the IV blocks - return 1 + nr_pmbs + nr_arrays; -} - -// Position of the VMB for the given volume -static inline uint64_t sflc_vmbPosition(size_t vol_idx, size_t nr_slices) -{ - return 1 + ((uint64_t) vol_idx) * ((uint64_t) sflc_volHeaderSize(nr_slices)); -} - - /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ diff --git a/vuvuzela-userland/include/utils/crypto.h b/vuvuzela-userland/include/utils/crypto.h index 15ac111..8e5f4d8 100644 --- a/vuvuzela-userland/include/utils/crypto.h +++ b/vuvuzela-userland/include/utils/crypto.h @@ -41,20 +41,21 @@ *****************************************************/ // Key length, for input into AES-CTR and AES-GCM, and for output from Argon -#define SFLC_CRYPTO_KEYLEN 32 /* bytes */ +#define SFLC_STANDARD_KEYLEN 32 /* bytes */ +// Key length for AES-XTS +#define SFLC_AESXTS_KEYLEN 64 /* bytes */ // IV length for AES-CTR #define SFLC_AESCTR_IVLEN 16 /* bytes */ +// IV length for AES-XTS +#define SFLC_AESXTS_IVLEN 16 /* bytes */ // IV length for AES-GCM #define SFLC_AESGCM_IVLEN 12 /* bytes */ - // IVs occupy 16 bytes on-disk, but only the *FIRST* 12 are used for AES-GCM #define SFLC_AESGCM_PADDED_IVLEN 16 /* bytes */ - // MAC length for AES-GCM #define SFLC_AESGCM_TAGLEN 16 /* bytes */ - // Content of output plaintext upon MAC verification failure #define SFLC_AESGCM_POISON_PT 0xFF @@ -81,9 +82,9 @@ * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* Get slow, true random bytes (suited for keys) */ +/* Get slow, strong random bytes (suited for keys) */ int sflc_rand_getStrongBytes(char *buf, size_t buflen); -/* Get fast, pseudo random bytes (suited for IVs and padding) */ +/* Get fast, weak(er) random bytes (suited for IVs and padding) */ int sflc_rand_getWeakBytes(char *buf, size_t buflen); /* AES256-CTR encryption, does not touch the IV. Set ct = NULL for in-place. */ @@ -91,6 +92,10 @@ int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c /* AES256-CTR decryption, does not touch the IV. Set pt = NULL for in-place. */ int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); +/* AES256-XTS encryption. Set ct = NULL for in-place. + * The IV is intepreted as a little-endian "sector number", and incremented by 1 */ +int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); + /* AES256-GCM encryption, does not touch the IV */ int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); /* AES256-GCM decryption, does not touch the IV (only decrypts if MAC is valid) */ diff --git a/vuvuzela-userland/include/utils/disk.h b/vuvuzela-userland/include/utils/disk.h index 7666609..00dd91c 100644 --- a/vuvuzela-userland/include/utils/disk.h +++ b/vuvuzela-userland/include/utils/disk.h @@ -35,6 +35,7 @@ #include #include +#include "utils/math.h" #include "utils/sflc.h" @@ -44,44 +45,27 @@ /** * Max slices for given disk size (in 4096-byte blocks). - * - * The bigger a disk is, the more slices it can host. However, the more slices we format it with, - * the bigger the position map needed to index them: the header size grows with the number of slices, - * taking up part of the space that's supposed to host those slices. - * To settle the matter, let us derive an upper bound on the header size, yielding a "safe" value - * for the number of slices (given a disk size). - * - * To index s slices, we need pm := ceil(s/1024) <= s/1024 + 1 PosMap blocks, since each PosMap - * block (4096 bytes) can host 1024 slice indices (4 bytes each). - * - * To encrypt those PosMap blocks, we need iv := ceil(pm/256) <= pm IV blocks, since each IV block - * (4096 bytes) can encrypt 256 data blocks (IVs are 16 bytes). - * - * Therefore, a position map indexing s slices occupies pm+iv <= 2*pm <= 2*s/1024 + 2 blocks. - * - * A single volume's header contains the Volume Master Block and the position map, therefore it - * occupies 1+pm+iv <= 2*s/1024 + 3 blocks. - * - * The entire device's header simply contains 15 volume headers of the same size, therefore it - * occupies h := 15 * (1+pm+iv) <= 15*2*s/1024 + 3*15 <= s + 3*15 blocks. - * The last inequality follows from 15*2/1024 <= 1 (we need to enforce this on the symbolic values). - * - * To actually host the s slices, the data section needs 257*s blocks (256 data blocks + 1 IV block - * per slice). - * - * Therefore, in order to format a disk with s slices, we need at most (s + 3*15) + 257*s = - * = (1 + 257)*s + 3*15 blocks. - * - * If we are given d blocks on the disk, a safe value for s is one that satisfies - * (1 + 257)*s + 3*15 <= d <==> s <= (d - 3*15) / (1 + 257) */ -#define sflc_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFLC_BLOCKS_PER_PHYS_SLICE) +static inline uint32_t sflc_disk_maxSlices(uint64_t size) { + uint64_t nr_slices; + // Start from upper bound + nr_slices = size / SFLC_SLICE_SCALE; + while(true) { + if (nr_slices == 0) + break; -/* Let us enforce, on the symbolic values, the inequality used in the previous bound */ -#if SFLC_DEV_MAX_VOLUMES * 2 > SFLC_SLICE_IDX_PER_BLOCK -#error "Invalid combination of parameters, probably SFLC_DEV_MAX_VOLUMES is too big" -#endif + // Stop when this nr_slices can fit in size, including the header + uint64_t posmap_blocks = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + uint64_t header_size = 1 + SFLC_DEV_MAX_VOLUMES * (1 + posmap_blocks); + if (header_size + nr_slices*SFLC_SLICE_SCALE <= size) + break; + + nr_slices--; + } + + return nr_slices > SFLC_MAX_SLICES ? SFLC_MAX_SLICES : (uint32_t) nr_slices; +} /***************************************************** @@ -92,16 +76,16 @@ bool sflc_disk_isBlockDevice(char *path); /* Returns the size in 4096-byte sectors (or < 0 if error) */ -int64_t sflc_disk_getSize(char * bdev_path); +int64_t sflc_disk_getSize(char *bdev_path); -/* Reads a single 4096-byte sector from the disk */ -int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf); +/* Reads a single 4096-byte block from the disk */ +int sflc_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); -/* Writes a single 4096-byte sector to the disk */ -int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf); +/* Writes many 4096-byte blocks to the disk */ +int sflc_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); -/* Writes many 4096-byte sectors to the disk */ -int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors); +/* Writes a single 4096-byte block to the disk */ +#define sflc_disk_writeBlock(bdev_path, bnum, buf) sflc_disk_writeManyBlocks(bdev_path, bnum, buf, 1) #endif /* _UTILS_DISK_H_ */ diff --git a/vuvuzela-userland/include/utils/input.h b/vuvuzela-userland/include/utils/input.h index 9463999..52e07fb 100644 --- a/vuvuzela-userland/include/utils/input.h +++ b/vuvuzela-userland/include/utils/input.h @@ -43,4 +43,4 @@ int sflc_safeReadLine(char *buf, size_t bufsize); /* Reads a password or passphrase (discarding the newline) from stdin in a secure way (no echo) */ int sflc_safeReadPassphrase(char *buf, size_t bufsize); -#endif /* _UTILS_FILE_H_ */ +#endif /* _UTILS_INPUT_H_ */ diff --git a/vuvuzela-userland/include/utils/sflc.h b/vuvuzela-userland/include/utils/sflc.h index e8135e4..99d0243 100644 --- a/vuvuzela-userland/include/utils/sflc.h +++ b/vuvuzela-userland/include/utils/sflc.h @@ -39,12 +39,14 @@ *****************************************************/ /* Name of the DM target in the kernel */ -#define SFLC_DM_TARGET_NAME "shufflecake" +#define SFLC_DM_TARGET_NAME "vvz" -/* Disk constants */ -#define SFLC_SECTOR_SIZE 4096 /* bytes */ -#define KERNEL_SECTOR_SIZE 512 /* bytes */ -#define SFLC_SECTOR_SCALE (SFLC_SECTOR_SIZE / KERNEL_SECTOR_SIZE) +/* Sizes */ +#define KERNEL_SECTOR_SIZE 512 /* bytes */ +#define SFLC_BLOCK_SIZE 4096 /* bytes */ +#define SFLC_BLOCK_SCALE (SFLC_BLOCK_SIZE / KERNEL_SECTOR_SIZE) +#define SFLC_SLICE_SCALE 256 /* blocks in a slice */ +#define SFLC_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ /* Max number of volumes in a device */ #define SFLC_DEV_MAX_VOLUMES 15 @@ -57,25 +59,16 @@ /* A slice index is represented over 32 bits */ #define SFLC_SLICE_IDX_WIDTH 4 /* bytes */ /* A position map block contains 1024 slice indices */ -#define SFLC_SLICE_IDX_PER_BLOCK (SFLC_SECTOR_SIZE / SFLC_SLICE_IDX_WIDTH) +#define SFLC_SLICE_IDX_PER_BLOCK (SFLC_BLOCK_SIZE / SFLC_SLICE_IDX_WIDTH) -// IV length for AES-CTR -#define SFLC_AESCTR_IVLEN 16 /* bytes */ - -/* An IV block can encrypt 256 data blocks */ -#define SFLC_DATA_BLOCKS_PER_IV_BLOCK (SFLC_SECTOR_SIZE / SFLC_AESCTR_IVLEN) -/* A logical slice spans 256 blocks of data (1 MiB) */ -#define SFLC_BLOCKS_PER_LOG_SLICE SFLC_DATA_BLOCKS_PER_IV_BLOCK -/* A physical slice also includes the IV block */ -#define SFLC_BLOCKS_PER_PHYS_SLICE (1 + SFLC_BLOCKS_PER_LOG_SLICE) /* A PSI of 0xFFFFFFFF indicates an unassigned LSI */ #define SFLC_EPM_FILLER 0xFF /* The sysfs file containing the next available device ID */ -#define SFLC_SYSFS_NEXTDEVID "/sys/devices/sflc/next_dev_id" +#define SFLC_SYSFS_NEXTDEVID "/sys/module/dm_vvz/next_dev_id" /* The sysfs directory containing a subdir for each (underlying) block device */ -#define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" +#define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_vvz/bdevs" /* Within each bdev's subdir, this file lists its open volumes */ #define SFLC_SYSFS_OPENVOLUMES_FILENAME "volumes" diff --git a/vuvuzela-userland/src/commands/init.c b/vuvuzela-userland/src/commands/init.c index cd21b03..e27e840 100644 --- a/vuvuzela-userland/src/commands/init.c +++ b/vuvuzela-userland/src/commands/init.c @@ -44,7 +44,7 @@ /* The device is randomised in chunks of 1024 blocks (arbitrary number) */ #define SFLC_BLOCKS_IN_RAND_CHUNK 1024 /* That's 4 MiB */ -#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_SECTOR_SIZE) +#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_BLOCK_SIZE) /***************************************************** @@ -111,7 +111,7 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) /* Sample the VMB keys */ size_t i; for (i = 0; i < dmb.nr_vols; i++) { - err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_CRYPTO_KEYLEN); + err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_STANDARD_KEYLEN); if (err) { sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); return err; @@ -129,10 +129,10 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) for (i = 0; i < args->nr_vols; i++) { /* This volume's prev_vmb_key */ if (i > 0) { - memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_CRYPTO_KEYLEN); + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_STANDARD_KEYLEN); } /* Sample this volume's VEK */ - sflc_rand_getStrongBytes(vmb.volume_key, SFLC_CRYPTO_KEYLEN); + sflc_rand_getStrongBytes(vmb.volume_key, SFLC_STANDARD_KEYLEN); /* Write complete volume header (VMB + PM) */ err = sflc_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); @@ -170,7 +170,7 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) while (blocks_remaining > 0) { uint64_t blocks_to_write = (blocks_remaining > SFLC_BLOCKS_IN_RAND_CHUNK) ? SFLC_BLOCKS_IN_RAND_CHUNK : blocks_remaining; - uint64_t bytes_to_write = blocks_to_write * SFLC_SECTOR_SIZE; + uint64_t bytes_to_write = blocks_to_write * SFLC_BLOCK_SIZE; /* Sample random bytes */ err = sflc_rand_getWeakBytes(rand_chunk, bytes_to_write); @@ -180,7 +180,7 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) } /* Write on disk */ - err = sflc_disk_writeManySectors(bdev_path, sector, rand_chunk, blocks_to_write); + err = sflc_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); if (err) { sflc_log_error("Could not write random bytes on disk; error %d", err); goto out; diff --git a/vuvuzela-userland/src/header/device_master_block.c b/vuvuzela-userland/src/header/device_master_block.c index cdd1f8c..1cfcd9b 100644 --- a/vuvuzela-userland/src/header/device_master_block.c +++ b/vuvuzela-userland/src/header/device_master_block.c @@ -72,7 +72,7 @@ int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block } /* Randomise whole block */ - err = sflc_rand_getWeakBytes(disk_block, SFLC_SECTOR_SIZE); + err = sflc_rand_getWeakBytes(disk_block, SFLC_BLOCK_SIZE); if (err) { sflc_log_error("Could not randomise DMB; error %d", err); return err; @@ -115,9 +115,9 @@ int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *d // KDF salt char *salt; // The KDF-derived key - char kek[SFLC_CRYPTO_KEYLEN]; + char kek[SFLC_STANDARD_KEYLEN]; // The unlocked VMB key - char vmb_key[SFLC_CRYPTO_KEYLEN]; + char vmb_key[SFLC_STANDARD_KEYLEN]; // Error code int err; @@ -149,7 +149,7 @@ int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *d if (match) { sflc_log_debug("The provided password unlocks volume %lu", i); dmb_cell->vol_idx = i; - memcpy(dmb_cell->vmb_key, vmb_key, SFLC_CRYPTO_KEYLEN); + memcpy(dmb_cell->vmb_key, vmb_key, SFLC_STANDARD_KEYLEN); } } @@ -160,7 +160,7 @@ int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *d bad_decrypt: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLC_CRYPTO_KEYLEN); + memset(kek, 0, SFLC_STANDARD_KEYLEN); return err; } @@ -211,9 +211,9 @@ static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vm // Pointers inside the block char *iv = dmb_cell; char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLC_CRYPTO_KEYLEN; + char *mac = enc_vmb_key + SFLC_STANDARD_KEYLEN; // Key-encryption-key derived from KDF - char kek[SFLC_CRYPTO_KEYLEN]; + char kek[SFLC_STANDARD_KEYLEN]; // Error code int err; @@ -234,7 +234,7 @@ static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vm sflc_log_debug("Successfully sampled prologue IV"); /* Encrypt the VMB key */ - err = sflc_aes256gcm_encrypt(kek, vmb_key, SFLC_CRYPTO_KEYLEN, iv, enc_vmb_key, mac); + err = sflc_aes256gcm_encrypt(kek, vmb_key, SFLC_STANDARD_KEYLEN, iv, enc_vmb_key, mac); if (err) { sflc_log_error("Could not encrypt the VMB key: error %d", err); goto bad_encrypt; @@ -249,7 +249,7 @@ bad_encrypt: bad_sample_iv: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLC_CRYPTO_KEYLEN); + memset(kek, 0, SFLC_STANDARD_KEYLEN); return err; } @@ -259,12 +259,12 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool // Pointers inside the block char *iv = dmb_cell; char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLC_CRYPTO_KEYLEN; + char *mac = enc_vmb_key + SFLC_STANDARD_KEYLEN; // Error code int err; /* Decrypt the VMB key */ - err = sflc_aes256gcm_decrypt(kek, enc_vmb_key, SFLC_CRYPTO_KEYLEN, mac, iv, vmb_key, match); + err = sflc_aes256gcm_decrypt(kek, enc_vmb_key, SFLC_STANDARD_KEYLEN, mac, iv, vmb_key, match); if (err) { sflc_log_error("Error while decrypting VMB key: error %d", err); return err; diff --git a/vuvuzela-userland/src/header/position_map.c b/vuvuzela-userland/src/header/position_map.c index f2b8144..051161f 100644 --- a/vuvuzela-userland/src/header/position_map.c +++ b/vuvuzela-userland/src/header/position_map.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "header.h" #include "utils/sflc.h" @@ -41,94 +42,49 @@ *****************************************************/ /* Create an encrypted empty position map for the given number of slices. - * Allocates the internal pointers of the EPM structure. - * On failure, does not free the allocated memory. + * Allocates the memory (whole number of blocks) needed to host it. * * @param nr_slices The number of slices the device will be composed of. * @param volume_key The volume's data section encryption key, used to encrypt the * position map as well. - * @param epm The EncPosMap struct to be initialised. * - * @return Error code, 0 on success */ -int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm) + * @return The memory buffer containing the position map */ +void *sflc_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) { + char pmb[SFLC_BLOCK_SIZE]; + char iv[SFLC_AESXTS_IVLEN]; + void *epm; size_t nr_pmbs; - size_t nr_arrays; int err; // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); - // Each array holds up to 256 PosMapBlocks - nr_arrays = ceil(nr_pmbs, SFLC_BLOCKS_PER_LOG_SLICE); - // Fill the EPM numeric fields - epm->nr_arrays = nr_arrays; - // All arrays are full except the last one - epm->nr_last_pmbs = nr_pmbs - (SFLC_BLOCKS_PER_LOG_SLICE * (nr_arrays - 1)); - - // Allocate array of IV blocks - epm->iv_blocks = malloc(nr_arrays * sizeof(char *)); - if (!epm->iv_blocks) { - sflc_log_error("Could not malloc array of IV blocks"); - err = ENOMEM; - goto out; - } - // Allocate array of PosMapBlock arrays - epm->pmb_arrays = malloc(nr_arrays * sizeof(char *)); - if (!epm->pmb_arrays) { - sflc_log_error("Could not malloc array of PosMapBlock arrays"); - err = ENOMEM; - goto out; + // Allocate EPM + epm = malloc(nr_pmbs * SFLC_BLOCK_SIZE); + if (!epm) { + sflc_log_error("Could not malloc EPM array"); + return NULL; } - // Loop to allocate and encrypt each array + // Fill cleartext PMB with 0xFF + memset(pmb, SFLC_EPM_FILLER, SFLC_BLOCK_SIZE); + // Set the IV for the first encryption + memset(iv, 0, SFLC_AESXTS_IVLEN); + *((uint64_t)iv) = htole64(sflc_pmStartBlock(vol_idx, nr_slices)); + + // Loop to encrypt each PMB int i; - for (i = 0; i < nr_arrays; i++) { - // The last PMB array might be smaller - size_t nr_pmbs_here = ((i == nr_arrays - 1) ? epm->nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); - size_t pmb_array_size = SFLC_SECTOR_SIZE * nr_pmbs_here; - char *iv_block; - char *pmb_array; - - // Allocate IV block - epm->iv_blocks[i] = malloc(SFLC_SECTOR_SIZE); - if (!epm->iv_blocks[i]) { - sflc_log_error("Could not allocate IV block number %d", i); - err = ENOMEM; - goto out; - } - // Allocate PosMapBlock array - epm->pmb_arrays[i] = malloc(pmb_array_size); - if (!epm->pmb_arrays[i]) { - sflc_log_error("Could not allocate PMB array number %d", i); - err = ENOMEM; - goto out; - } - // Shorthand - iv_block = epm->iv_blocks[i]; - pmb_array = epm->pmb_arrays[i]; - - // Fill the IV block with random data (can ignore return value) - sflc_rand_getWeakBytes(iv_block, SFLC_SECTOR_SIZE); - // Fill the PMB array with 0xFF - memset(pmb_array, SFLC_EPM_FILLER, pmb_array_size); - - // Loop to encrypt each PMB separately with its IV - int j; - for (j = 0; j < nr_pmbs_here; j++) { - char *iv = iv_block + (j * SFLC_AESCTR_IVLEN); - char *pmb = pmb_array + (j * SFLC_SECTOR_SIZE); - - // Encrypt in-place - err = sflc_aes256ctr_encrypt(volume_key, pmb, SFLC_SECTOR_SIZE, iv, NULL); - if (err) { - sflc_log_error("Could not encrypt PMB %d of array %d", j, i); - goto out; - } + for (i = 0; i < nr_pmbs; i++) { + // Encrypt. Auto-increment IV for next encryption + err = sflc_aes256xts_encrypt(volume_key, pmb, SFLC_BLOCK_SIZE, iv, + epm + i*SFLC_BLOCK_SIZE); + if (err) { + sflc_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); + free(epm); + return NULL; } } - -out: - return err; + return epm; } diff --git a/vuvuzela-userland/src/header/volume_master_block.c b/vuvuzela-userland/src/header/volume_master_block.c index 9347582..d73d98d 100644 --- a/vuvuzela-userland/src/header/volume_master_block.c +++ b/vuvuzela-userland/src/header/volume_master_block.c @@ -181,14 +181,14 @@ static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLC_CRYPTO_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLC_CRYPTO_KEYLEN; + char *p_prev_vmb_key = p_vol_key + SFLC_STANDARD_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(p_vol_key, vmb->volume_key, SFLC_CRYPTO_KEYLEN); + memcpy(p_vol_key, vmb->volume_key, SFLC_STANDARD_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_CRYPTO_KEYLEN); + memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_STANDARD_KEYLEN); /* Write the number of slices (network byte order) */ *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); @@ -204,14 +204,14 @@ static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLC_CRYPTO_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLC_CRYPTO_KEYLEN; + char *p_prev_vmb_key = p_vol_key + SFLC_STANDARD_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(vmb->volume_key, p_vol_key, SFLC_CRYPTO_KEYLEN); + memcpy(vmb->volume_key, p_vol_key, SFLC_STANDARD_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_CRYPTO_KEYLEN); + memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_STANDARD_KEYLEN); /* Read number of slices (network byte order) */ vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); diff --git a/vuvuzela-userland/src/operations/devmapper.c b/vuvuzela-userland/src/operations/devmapper.c index 99a66a2..91b3b51 100644 --- a/vuvuzela-userland/src/operations/devmapper.c +++ b/vuvuzela-userland/src/operations/devmapper.c @@ -68,7 +68,7 @@ int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); /* Get the hex version of the volume's data section key */ - hex_key = sflc_toHex(vmb->volume_key, SFLC_CRYPTO_KEYLEN); + hex_key = sflc_toHex(vmb->volume_key, SFLC_STANDARD_KEYLEN); if (!hex_key) { sflc_log_error("Could not encode volume key to hexadecimal"); err = ENOMEM; @@ -76,7 +76,7 @@ int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb } /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; + num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_BLOCK_SCALE; /* Build param list */ sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); diff --git a/vuvuzela-userland/src/operations/dmb.c b/vuvuzela-userland/src/operations/dmb.c index d529966..662742e 100644 --- a/vuvuzela-userland/src/operations/dmb.c +++ b/vuvuzela-userland/src/operations/dmb.c @@ -57,7 +57,7 @@ int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb) { /* On-disk DMB */ - char enc_dmb[SFLC_SECTOR_SIZE]; + char enc_dmb[SFLC_BLOCK_SIZE]; /* Error code */ int err; @@ -75,7 +75,7 @@ int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb * } /* Write it to disk (at sector 0) */ - err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); + err = sflc_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { sflc_log_error("Could not write DMB to disk; error %d", err); return err; @@ -99,11 +99,11 @@ int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb * */ int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb) { - char enc_dmb[SFLC_SECTOR_SIZE]; + char enc_dmb[SFLC_BLOCK_SIZE]; int err; /* Read DMB from disk (at sector 0) */ - err = sflc_disk_readSector(bdev_path, 0, enc_dmb); + err = sflc_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { sflc_log_error("Could not read DMB from disk; error %d", err); return err; @@ -131,7 +131,7 @@ int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *d */ int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) { - char enc_dmb[SFLC_SECTOR_SIZE]; + char enc_dmb[SFLC_BLOCK_SIZE]; int err; /* Sanity check */ @@ -141,7 +141,7 @@ int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_p } /* Read DMB from disk (at sector 0) */ - err = sflc_disk_readSector(bdev_path, 0, enc_dmb); + err = sflc_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { sflc_log_error("Could not read DMB from disk; error %d", err); return err; @@ -155,7 +155,7 @@ int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_p } /* Write it to disk (at sector 0) */ - err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); + err = sflc_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { sflc_log_error("Could not write DMB to disk; error %d", err); return err; diff --git a/vuvuzela-userland/src/operations/volume_header.c b/vuvuzela-userland/src/operations/volume_header.c index 1088290..d35acdd 100644 --- a/vuvuzela-userland/src/operations/volume_header.c +++ b/vuvuzela-userland/src/operations/volume_header.c @@ -55,7 +55,7 @@ */ int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) { - char enc_vmb[SFLC_SECTOR_SIZE]; + char enc_vmb[SFLC_BLOCK_SIZE]; sflc_EncPosMap epm; uint64_t sector; int err; @@ -69,7 +69,7 @@ int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, si // Write it to disk sector = sflc_vmbPosition(vol_idx, vmb->nr_slices); - err = sflc_disk_writeSector(bdev_path, sector, enc_vmb); + err = sflc_disk_writeBlock(bdev_path, sector, enc_vmb); if (err) { sflc_log_error("Could not write VMB to disk; error %d", err); goto out; @@ -91,7 +91,7 @@ int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, si size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); // First write the IV block - err = sflc_disk_writeSector(bdev_path, sector, iv_block); + err = sflc_disk_writeBlock(bdev_path, sector, iv_block); if (err) { sflc_log_error("Could not write IV block to disk; error %d", err); goto out; @@ -99,7 +99,7 @@ int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, si sector += 1; // Then the whole PMB array - err = sflc_disk_writeManySectors(bdev_path, sector, pmb_array, nr_pmbs); + err = sflc_disk_writeManyBlocks(bdev_path, sector, pmb_array, nr_pmbs); if (err) { sflc_log_error("Could not write PMB array to disk; error %d", err); goto out; @@ -135,13 +135,13 @@ out: */ int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) { - char enc_vmb[SFLC_SECTOR_SIZE]; + char enc_vmb[SFLC_BLOCK_SIZE]; uint64_t sector; int err; /* Read encrypted VMB from disk */ sector = sflc_vmbPosition(vol_idx, nr_slices); - err = sflc_disk_readSector(bdev_path, sector, enc_vmb); + err = sflc_disk_readBlock(bdev_path, sector, enc_vmb); if (err) { sflc_log_error("Could not read VMB from disk; error %d", err); return err; diff --git a/vuvuzela-userland/src/utils/crypto.c b/vuvuzela-userland/src/utils/crypto.c index b42f50f..dfa6f95 100644 --- a/vuvuzela-userland/src/utils/crypto.c +++ b/vuvuzela-userland/src/utils/crypto.c @@ -95,7 +95,7 @@ int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; @@ -163,7 +163,7 @@ int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *p sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; @@ -205,6 +205,76 @@ bad_open: } +/** + * AES256-XTS encryption. Set ct = NULL for in-place. + * The IV is intepreted as a little-endian "sector number", and incremented by 1. + * + * @param key The 64-byte AES-XTS key + * @param pt The plaintext + * @param pt_len The length of the plaintext, must be a multiple of the AES + * block size (16 bytes) + * @param iv The 16-byte AES-XTS IV + * @param ct A caller-allocated buffer that will contain the output ciphertext, + * cannot overlap with pt. If NULL, in-place encryption. + * + * @return The error code (0 on success) + */ +int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +{ + gcry_cipher_hd_t hd; + gcry_error_t err; + + // Instantiate the handle + err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_XTS, GCRY_CIPHER_SECURE); + if (err) { + sflc_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); + goto bad_open; + } + sflc_log_debug("Successfully instantiated AES256-XTS cipher handle"); + + // Set the key + err = gcry_cipher_setkey(hd, key, SFLC_AESXTS_KEYLEN); + if (err) { + sflc_log_error("Could not set AES-XTS key: error %d", err); + goto bad_setkey; + } + sflc_log_debug("Successfully set the AES-XTS key"); + + // Set the IV (not a counter, as per Gcrypt docs) + err = gcry_cipher_setiv(hd, iv, SFLC_AESXTS_IVLEN); + if (err) { + sflc_log_error("Could not set AES-XTS IV: error %d", err); + goto bad_setiv; + } + sflc_log_debug("Successfully set the IV"); + + // Encrypt + if (ct == NULL) { // In-place + err = gcry_cipher_encrypt(hd, pt, pt_len, NULL, 0); + } + else { // Out-of-place + err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); + } + // Error check + if (err) { + sflc_log_error("Could not encrypt: error %d", err); + goto bad_encrypt; + } + sflc_log_debug("Successfully encrypted"); + + // No prob? + err = 0; + + +bad_encrypt: +bad_setiv: +bad_setkey: + gcry_cipher_close(hd); +bad_open: + return err; +} + + /** *AES-GCM encryption, does not touch the IV. * @@ -233,7 +303,7 @@ int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; @@ -308,7 +378,7 @@ int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char * sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; @@ -378,7 +448,7 @@ int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) { gcry_kdf_hd_t hd; const unsigned long argon_params[4] = - {SFLC_CRYPTO_KEYLEN, SFLC_ARGON_T, SFLC_ARGON_M, SFLC_ARGON_P}; + {SFLC_STANDARD_KEYLEN, SFLC_ARGON_T, SFLC_ARGON_M, SFLC_ARGON_P}; gcry_error_t err; // Instantiate Argon2id handle @@ -405,7 +475,7 @@ int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) sflc_log_debug("Successfully run Argon2id computation"); // Finalise hash - err = gcry_kdf_final(hd, SFLC_CRYPTO_KEYLEN, hash); + err = gcry_kdf_final(hd, SFLC_STANDARD_KEYLEN, hash); if (err) { sflc_log_error("Could not finalise Argon2id hash: error %d", err); goto bad_final; diff --git a/vuvuzela-userland/src/utils/disk.c b/vuvuzela-userland/src/utils/disk.c index 2f78598..40368e6 100644 --- a/vuvuzela-userland/src/utils/disk.c +++ b/vuvuzela-userland/src/utils/disk.c @@ -96,7 +96,7 @@ int64_t sflc_disk_getSize(char * bdev_path) sflc_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); /* Compute size in SFLC sectors */ - ret = (size_bytes / SFLC_SECTOR_SIZE); + ret = (size_bytes / SFLC_BLOCK_SIZE); bad_ioctl: close(fd); @@ -114,7 +114,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf) +int sflc_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) { int fd; int err; @@ -130,7 +130,7 @@ int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf) sflc_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * SFLC_SECTOR_SIZE, SEEK_SET) < 0) { + if (lseek(fd, sector * SFLC_BLOCK_SIZE, SEEK_SET) < 0) { sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; @@ -139,7 +139,7 @@ int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf) sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Read in a loop */ - size_t bytes_to_read = SFLC_SECTOR_SIZE; + size_t bytes_to_read = SFLC_BLOCK_SIZE; while (bytes_to_read > 0) { /* Read syscall */ ssize_t bytes_read = read(fd, buf, bytes_to_read); @@ -172,22 +172,6 @@ bad_open: } -/** - * Writes a single 4096-byte sector to the disk. - * - * @param bdev_path The path of the block device - * @param sector The index of the desired sector - * @param The caller-allocated buffer (must hold 4096 bytes) where the data - * comes from - * - * @return The error code (0 on success) - */ -int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf) -{ - return sflc_disk_writeManySectors(bdev_path, sector, buf, 1); -} - - /** * Writes many 4096-byte sectors to the disk. * @@ -199,7 +183,7 @@ int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf) * * @return The error code (0 on success) */ -int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) +int sflc_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) { int fd; int err; @@ -215,7 +199,7 @@ int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, si sflc_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * SFLC_SECTOR_SIZE, SEEK_SET) < 0) { + if (lseek(fd, sector * SFLC_BLOCK_SIZE, SEEK_SET) < 0) { sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; @@ -224,7 +208,7 @@ int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, si sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Write in a loop */ - size_t bytes_to_write = SFLC_SECTOR_SIZE * num_sectors; + size_t bytes_to_write = SFLC_BLOCK_SIZE * num_sectors; while (bytes_to_write > 0) { /* Write syscall */ ssize_t bytes_written = write(fd, buf, bytes_to_write); diff --git a/vuvuzela-userland/test/crypto/test_argon2id.c b/vuvuzela-userland/test/crypto/test_argon2id.c index 0ded58b..7e1180d 100644 --- a/vuvuzela-userland/test/crypto/test_argon2id.c +++ b/vuvuzela-userland/test/crypto/test_argon2id.c @@ -49,7 +49,7 @@ char SALT[SFLC_ARGON_SALTLEN+1] = "Poor Petrol Pump"; char *test_argon2id() { char pwd[SFLC_BIGBUFSIZE]; - char key[SFLC_CRYPTO_KEYLEN]; + char key[SFLC_STANDARD_KEYLEN]; int err; sflc_log_blue("Testing Argon2id interactively with a fixed salt"); @@ -75,7 +75,7 @@ char *test_argon2id() sflc_log_hex(SALT, SFLC_ARGON_SALTLEN); printf("Argon2id hash (m = %d, t = %d, p = %d):\n", SFLC_ARGON_M, SFLC_ARGON_T, SFLC_ARGON_P); - sflc_log_hex(key, SFLC_CRYPTO_KEYLEN); + sflc_log_hex(key, SFLC_STANDARD_KEYLEN); printf("Go check the result online\n\n"); } From 8ecc634c1f3a050992348dfec98bb0055ca53c1a Mon Sep 17 00:00:00 2001 From: = Date: Wed, 17 Apr 2024 20:51:16 +0200 Subject: [PATCH 45/75] Change sflc to vvz --- vuvuzela-userland/include/cli.h | 22 +-- vuvuzela-userland/include/commands.h | 18 +-- vuvuzela-userland/include/header.h | 44 +++--- vuvuzela-userland/include/operations.h | 16 +- vuvuzela-userland/include/sflc_constants.h | 1 - vuvuzela-userland/include/utils/crypto.h | 42 ++--- vuvuzela-userland/include/utils/disk.h | 24 +-- vuvuzela-userland/include/utils/dm.h | 6 +- vuvuzela-userland/include/utils/file.h | 2 +- vuvuzela-userland/include/utils/input.h | 6 +- vuvuzela-userland/include/utils/log.h | 80 +++++----- vuvuzela-userland/include/utils/string.h | 4 +- .../include/utils/{sflc.h => vvz.h} | 42 ++--- vuvuzela-userland/include/vvz_constants.h | 41 +++++ vuvuzela-userland/src/cli/changepwd.c | 32 ++-- vuvuzela-userland/src/cli/close.c | 14 +- vuvuzela-userland/src/cli/dispatch.c | 88 +++++------ vuvuzela-userland/src/cli/init.c | 34 ++-- vuvuzela-userland/src/cli/open.c | 16 +- vuvuzela-userland/src/cli/testpwd.c | 22 +-- vuvuzela-userland/src/commands/change_pwd.c | 6 +- vuvuzela-userland/src/commands/close.c | 44 +++--- vuvuzela-userland/src/commands/init.c | 58 +++---- vuvuzela-userland/src/commands/open.c | 48 +++--- vuvuzela-userland/src/commands/test_pwd.c | 6 +- .../src/header/device_master_block.c | 90 +++++------ vuvuzela-userland/src/header/position_map.c | 26 +-- .../src/header/volume_master_block.c | 72 ++++----- vuvuzela-userland/src/main.c | 2 +- vuvuzela-userland/src/operations/devmapper.c | 26 +-- vuvuzela-userland/src/operations/dmb.c | 52 +++--- .../src/operations/volume_header.c | 48 +++--- vuvuzela-userland/src/utils/crypto.c | 148 +++++++++--------- vuvuzela-userland/src/utils/disk.c | 52 +++--- vuvuzela-userland/src/utils/dm.c | 56 +++---- vuvuzela-userland/src/utils/file.c | 6 +- vuvuzela-userland/src/utils/input.c | 8 +- vuvuzela-userland/src/utils/string.c | 6 +- .../test/crypto/test_aes256ctr.c | 24 +-- .../test/crypto/test_aes256gcm.c | 22 +-- vuvuzela-userland/test/crypto/test_argon2id.c | 18 +-- vuvuzela-userland/test/main.c | 6 +- 42 files changed, 709 insertions(+), 669 deletions(-) delete mode 120000 vuvuzela-userland/include/sflc_constants.h rename vuvuzela-userland/include/utils/{sflc.h => vvz.h} (71%) create mode 100644 vuvuzela-userland/include/vvz_constants.h diff --git a/vuvuzela-userland/include/cli.h b/vuvuzela-userland/include/cli.h index 838f618..e8b495b 100644 --- a/vuvuzela-userland/include/cli.h +++ b/vuvuzela-userland/include/cli.h @@ -30,15 +30,15 @@ *****************************************************/ /* Action to create volumes */ -#define SFLC_CLI_INITACT "init" +#define VVZ_CLI_INITACT "init" /* Action to open volumes */ -#define SFLC_CLI_OPENACT "open" +#define VVZ_CLI_OPENACT "open" /* Action to close volumes */ -#define SFLC_CLI_CLOSEACT "close" +#define VVZ_CLI_CLOSEACT "close" /* Action to test password */ -#define SFLC_CLI_TESTPWDACT "testpwd" +#define VVZ_CLI_TESTPWDACT "testpwd" /* Action to change password */ -#define SFLC_CLI_CHANGEPWDACT "changepwd" +#define VVZ_CLI_CHANGEPWDACT "changepwd" /***************************************************** @@ -46,18 +46,18 @@ *****************************************************/ /* Called by the main to parse the arguments and dispatch to the right command */ -int sflc_cli_dispatch(int argc, char **argv); +int vvz_cli_dispatch(int argc, char **argv); /* Initializes device and create empty volumes */ -int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill); +int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill); /* Open volumes */ -int sflc_cli_open(char *block_device); +int vvz_cli_open(char *block_device); /* Close volumes */ -int sflc_cli_close(char *block_device); +int vvz_cli_close(char *block_device); /* Test password */ -int sflc_cli_testPwd(char *block_device); +int vvz_cli_testPwd(char *block_device); /* Change password */ -int sflc_cli_changePwd(char *block_device); +int vvz_cli_changePwd(char *block_device); #endif /* _CLI_H_ */ diff --git a/vuvuzela-userland/include/commands.h b/vuvuzela-userland/include/commands.h index 68a14ac..a15ad14 100644 --- a/vuvuzela-userland/include/commands.h +++ b/vuvuzela-userland/include/commands.h @@ -60,7 +60,7 @@ typedef struct /* Option to skip random filling */ bool no_randfill; -} sflc_cmd_InitArgs; +} vvz_cmd_InitArgs; /* Parameters for the open command */ @@ -73,7 +73,7 @@ typedef struct char *pwd; size_t pwd_len; -} sflc_cmd_OpenArgs; +} vvz_cmd_OpenArgs; typedef struct { @@ -81,13 +81,13 @@ typedef struct char *bdev_path; /* Content of the DMB cell */ - sflc_DmbCell *dmb_cell; + vvz_DmbCell *dmb_cell; /* The new password */ char *new_pwd; size_t new_pwd_len; -} sflc_cmd_ChangePwdArgs; +} vvz_cmd_ChangePwdArgs; /***************************************************** @@ -95,19 +95,19 @@ typedef struct *****************************************************/ /* Create N volumes (only formats the device header, does not open the volumes) */ -int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args); +int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args); /* Open M volumes, from the first down to the one whose pwd is provided */ -int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args); +int vvz_cmd_openVolumes(vvz_cmd_OpenArgs *args); /* Close all volumes on the device (reads the list from sysfs) */ -int sflc_cmd_closeVolumes(char *bdev_path); +int vvz_cmd_closeVolumes(char *bdev_path); /* Tests which volume is unlocked by the given password */ -int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell); +int vvz_cmd_testPwd(vvz_cmd_OpenArgs *args, vvz_DmbCell *dmb_cell); /* Changes the specified volume's password */ -int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args); +int vvz_cmd_changePwd(vvz_cmd_ChangePwdArgs *args); #endif /* _COMMANDS_H_ */ diff --git a/vuvuzela-userland/include/header.h b/vuvuzela-userland/include/header.h index 32d5596..6d5181c 100644 --- a/vuvuzela-userland/include/header.h +++ b/vuvuzela-userland/include/header.h @@ -40,18 +40,18 @@ *****************************************************/ /* The DMB contains one IV + one VMB key + one MAC for each volume */ -#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_STANDARD_KEYLEN + SFLC_AESGCM_TAGLEN) +#define VVZ_DMB_CELL_SIZE (VVZ_AESGCM_PADDED_IVLEN + VVZ_STANDARD_KEYLEN + VVZ_AESGCM_TAGLEN) /* Let us enforce that the one DMB can fit cells for all volumes */ -#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL_SIZE) > SFLC_BLOCK_SIZE -#error "Invalid combination of parameters: probably SFLC_DEV_MAX_VOLUMES is too big" +#if VVZ_ARGON_SALTLEN + (VVZ_DEV_MAX_VOLUMES * VVZ_DMB_CELL_SIZE) > VVZ_BLOCK_SIZE +#error "Invalid combination of parameters: probably VVZ_DEV_MAX_VOLUMES is too big" #endif // The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) -#define SFLC_CLEAR_VMB_LEN (SFLC_BLOCK_SIZE - \ - SFLC_AESGCM_PADDED_IVLEN - \ - SFLC_AESGCM_TAGLEN) +#define VVZ_CLEAR_VMB_LEN (VVZ_BLOCK_SIZE - \ + VVZ_AESGCM_PADDED_IVLEN - \ + VVZ_AESGCM_TAGLEN) @@ -66,12 +66,12 @@ */ typedef struct { // Each volume's VMB key - char vmb_keys[SFLC_DEV_MAX_VOLUMES][SFLC_STANDARD_KEYLEN]; + char vmb_keys[VVZ_DEV_MAX_VOLUMES][VVZ_STANDARD_KEYLEN]; // How many of these need actually be encrypted size_t nr_vols; -} sflc_Dmb; +} vvz_Dmb; /** @@ -80,12 +80,12 @@ typedef struct { */ typedef struct { // The unlocked VMB key - char vmb_key[SFLC_STANDARD_KEYLEN]; + char vmb_key[VVZ_STANDARD_KEYLEN]; // The index of the volume opened by this VMB key size_t vol_idx; -} sflc_DmbCell; +} vvz_DmbCell; /** @@ -95,15 +95,15 @@ typedef struct { */ typedef struct { // The key that encrypts the volume's data section - char volume_key[SFLC_STANDARD_KEYLEN]; + char volume_key[VVZ_STANDARD_KEYLEN]; // The key that encrypts the previous volume's master block - char prev_vmb_key[SFLC_STANDARD_KEYLEN]; + char prev_vmb_key[VVZ_STANDARD_KEYLEN]; // The total number of logical slices virtually available to this volume size_t nr_slices; -} sflc_Vmb; +} vvz_Vmb; /***************************************************** @@ -112,11 +112,11 @@ typedef struct { // Starting block of a volume's position map -static inline uint64_t sflc_pmStartBlock(size_t vol_idx, size_t nr_slices) +static inline uint64_t vvz_pmStartBlock(size_t vol_idx, size_t nr_slices) { return 1 + - SFLC_DEV_MAX_VOLUMES + - vol_idx*ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + VVZ_DEV_MAX_VOLUMES + + vol_idx*ceil(nr_slices, VVZ_SLICE_IDX_PER_BLOCK); } @@ -125,21 +125,21 @@ static inline uint64_t sflc_pmStartBlock(size_t vol_idx, size_t nr_slices) *****************************************************/ /* "Encrypt" each VMB key with its pwd, so the DMB is ready to be written on-disk */ -int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); +int vvz_dmb_seal(vvz_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); /* "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF) */ -int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); +int vvz_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, vvz_DmbCell *dmb_cell); /* Re-encrypt the content of a single DMB cell */ -int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len); +int vvz_dmb_setCell(char *disk_block, vvz_DmbCell *dmb_cell, char *pwd, size_t pwd_len); /* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ -int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block); +int vvz_vmb_seal(vvz_Vmb *vmb, char *vmb_key, char *disk_block); /* "Decrypt" a VMB coming from the disk, directly using its key */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); +int vvz_vmb_unseal(char *disk_block, char *vmb_key, vvz_Vmb *vmb); /* Create an encrypted empty position map for the given number of slices (allocates memory) */ -void *sflc_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key); +void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key); diff --git a/vuvuzela-userland/include/operations.h b/vuvuzela-userland/include/operations.h index 13bebde..dbcfd45 100644 --- a/vuvuzela-userland/include/operations.h +++ b/vuvuzela-userland/include/operations.h @@ -42,20 +42,20 @@ *****************************************************/ /* Encrypts and writes the DMB to disk */ -int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb); +int vvz_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, vvz_Dmb *dmb); /* Reads the DMB from disk and outputs the unlocked VMB key */ -int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); +int vvz_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, vvz_DmbCell *dmb_cell); /* Reads the DMB from disk, changes the relevant DMB cell, and writes it back */ -int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); +int vvz_ops_rewriteDmbCell(char *bdev_path, vvz_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); /* Encrypts and writes a volume header (VMB+PM) on-disk */ -int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx); +int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size_t vol_idx); /* Reads a VMB from disk and unlocks it */ -int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb); +int vvz_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, vvz_Vmb *vmb); -/* Build parameter list for ctor in dm_sflc, and send DM ioctl to create virtual block device */ -int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb); +/* Build parameter list for ctor in dm_vvz, and send DM ioctl to create virtual block device */ +int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb *vmb); /* Close the volume via the appropriate ioctl to DM */ -int sflc_ops_closeVolume(char *label); +int vvz_ops_closeVolume(char *label); #endif /* _OPERATIONS_H_ */ diff --git a/vuvuzela-userland/include/sflc_constants.h b/vuvuzela-userland/include/sflc_constants.h deleted file mode 120000 index fab9e42..0000000 --- a/vuvuzela-userland/include/sflc_constants.h +++ /dev/null @@ -1 +0,0 @@ -../../dm-sflc/sflc_constants.h \ No newline at end of file diff --git a/vuvuzela-userland/include/utils/crypto.h b/vuvuzela-userland/include/utils/crypto.h index 8e5f4d8..e9d1ed9 100644 --- a/vuvuzela-userland/include/utils/crypto.h +++ b/vuvuzela-userland/include/utils/crypto.h @@ -33,7 +33,7 @@ #include #include -#include "utils/sflc.h" +#include "utils/vvz.h" /***************************************************** @@ -41,41 +41,41 @@ *****************************************************/ // Key length, for input into AES-CTR and AES-GCM, and for output from Argon -#define SFLC_STANDARD_KEYLEN 32 /* bytes */ +#define VVZ_STANDARD_KEYLEN 32 /* bytes */ // Key length for AES-XTS -#define SFLC_AESXTS_KEYLEN 64 /* bytes */ +#define VVZ_AESXTS_KEYLEN 64 /* bytes */ // IV length for AES-CTR -#define SFLC_AESCTR_IVLEN 16 /* bytes */ +#define VVZ_AESCTR_IVLEN 16 /* bytes */ // IV length for AES-XTS -#define SFLC_AESXTS_IVLEN 16 /* bytes */ +#define VVZ_AESXTS_IVLEN 16 /* bytes */ // IV length for AES-GCM -#define SFLC_AESGCM_IVLEN 12 /* bytes */ +#define VVZ_AESGCM_IVLEN 12 /* bytes */ // IVs occupy 16 bytes on-disk, but only the *FIRST* 12 are used for AES-GCM -#define SFLC_AESGCM_PADDED_IVLEN 16 /* bytes */ +#define VVZ_AESGCM_PADDED_IVLEN 16 /* bytes */ // MAC length for AES-GCM -#define SFLC_AESGCM_TAGLEN 16 /* bytes */ +#define VVZ_AESGCM_TAGLEN 16 /* bytes */ // Content of output plaintext upon MAC verification failure -#define SFLC_AESGCM_POISON_PT 0xFF +#define VVZ_AESGCM_POISON_PT 0xFF /* Argon parameters */ // Argon salt length -#define SFLC_ARGON_SALTLEN 16 /* bytes */ +#define VVZ_ARGON_SALTLEN 16 /* bytes */ // Argon memory parameter // We assume machines with at least 128 MiB available RAM, so 2^17 kiB -#define SFLC_ARGON_M (1 << 17) /* kibibytes */ +#define VVZ_ARGON_M (1 << 17) /* kibibytes */ // Argon iterations count // We aim for 1-2 seconds on a low-end laptop or mobile (it's a one-time operation) -#define SFLC_ARGON_T 3 +#define VVZ_ARGON_T 3 // Argon parallelism parameter (recommended to be 2 * CPU cores) // We assume use even on single core devices -#define SFLC_ARGON_P 2 +#define VVZ_ARGON_P 2 /***************************************************** @@ -83,26 +83,26 @@ *****************************************************/ /* Get slow, strong random bytes (suited for keys) */ -int sflc_rand_getStrongBytes(char *buf, size_t buflen); +int vvz_rand_getStrongBytes(char *buf, size_t buflen); /* Get fast, weak(er) random bytes (suited for IVs and padding) */ -int sflc_rand_getWeakBytes(char *buf, size_t buflen); +int vvz_rand_getWeakBytes(char *buf, size_t buflen); /* AES256-CTR encryption, does not touch the IV. Set ct = NULL for in-place. */ -int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-CTR decryption, does not touch the IV. Set pt = NULL for in-place. */ -int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); +int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); /* AES256-XTS encryption. Set ct = NULL for in-place. * The IV is intepreted as a little-endian "sector number", and incremented by 1 */ -int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-GCM encryption, does not touch the IV */ -int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); +int vvz_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); /* AES256-GCM decryption, does not touch the IV (only decrypts if MAC is valid) */ -int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); +int vvz_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); /* Compute Argon KDF */ -int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); +int vvz_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); #endif /* _UTILS_CRYPTO_H_ */ diff --git a/vuvuzela-userland/include/utils/disk.h b/vuvuzela-userland/include/utils/disk.h index 00dd91c..b36b6a2 100644 --- a/vuvuzela-userland/include/utils/disk.h +++ b/vuvuzela-userland/include/utils/disk.h @@ -36,7 +36,7 @@ #include #include "utils/math.h" -#include "utils/sflc.h" +#include "utils/vvz.h" /***************************************************** @@ -46,25 +46,25 @@ /** * Max slices for given disk size (in 4096-byte blocks). */ -static inline uint32_t sflc_disk_maxSlices(uint64_t size) { +static inline uint32_t vvz_disk_maxSlices(uint64_t size) { uint64_t nr_slices; // Start from upper bound - nr_slices = size / SFLC_SLICE_SCALE; + nr_slices = size / VVZ_SLICE_SCALE; while(true) { if (nr_slices == 0) break; // Stop when this nr_slices can fit in size, including the header - uint64_t posmap_blocks = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); - uint64_t header_size = 1 + SFLC_DEV_MAX_VOLUMES * (1 + posmap_blocks); - if (header_size + nr_slices*SFLC_SLICE_SCALE <= size) + uint64_t posmap_blocks = ceil(nr_slices, VVZ_SLICE_IDX_PER_BLOCK); + uint64_t header_size = 1 + VVZ_DEV_MAX_VOLUMES * (1 + posmap_blocks); + if (header_size + nr_slices*VVZ_SLICE_SCALE <= size) break; nr_slices--; } - return nr_slices > SFLC_MAX_SLICES ? SFLC_MAX_SLICES : (uint32_t) nr_slices; + return nr_slices > VVZ_MAX_SLICES ? VVZ_MAX_SLICES : (uint32_t) nr_slices; } @@ -73,19 +73,19 @@ static inline uint32_t sflc_disk_maxSlices(uint64_t size) { *****************************************************/ /* Checks whether the given path points to a block device */ -bool sflc_disk_isBlockDevice(char *path); +bool vvz_disk_isBlockDevice(char *path); /* Returns the size in 4096-byte sectors (or < 0 if error) */ -int64_t sflc_disk_getSize(char *bdev_path); +int64_t vvz_disk_getSize(char *bdev_path); /* Reads a single 4096-byte block from the disk */ -int sflc_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); +int vvz_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); /* Writes many 4096-byte blocks to the disk */ -int sflc_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); +int vvz_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); /* Writes a single 4096-byte block to the disk */ -#define sflc_disk_writeBlock(bdev_path, bnum, buf) sflc_disk_writeManyBlocks(bdev_path, bnum, buf, 1) +#define vvz_disk_writeBlock(bdev_path, bnum, buf) vvz_disk_writeManyBlocks(bdev_path, bnum, buf, 1) #endif /* _UTILS_DISK_H_ */ diff --git a/vuvuzela-userland/include/utils/dm.h b/vuvuzela-userland/include/utils/dm.h index 3334852..1670a73 100644 --- a/vuvuzela-userland/include/utils/dm.h +++ b/vuvuzela-userland/include/utils/dm.h @@ -35,7 +35,7 @@ #include -#include "utils/sflc.h" +#include "utils/vvz.h" /***************************************************** @@ -48,9 +48,9 @@ *****************************************************/ /* Create a new Shufflecake virtual device (volume) under /dev/mapper */ -int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); +int vvz_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); /* Destroy the virtual device under /dev/mapper */ -int sflc_dm_destroy(char * virt_dev_name); +int vvz_dm_destroy(char * virt_dev_name); #endif /* _UTILS_DM_H_ */ diff --git a/vuvuzela-userland/include/utils/file.h b/vuvuzela-userland/include/utils/file.h index fb03078..b4760c3 100644 --- a/vuvuzela-userland/include/utils/file.h +++ b/vuvuzela-userland/include/utils/file.h @@ -30,7 +30,7 @@ *****************************************************/ /* Malloc's the buffer for the file contents */ -char *sflc_readFile(char *path); +char *vvz_readFile(char *path); #endif /* _UTILS_FILE_H_ */ diff --git a/vuvuzela-userland/include/utils/input.h b/vuvuzela-userland/include/utils/input.h index 52e07fb..068d376 100644 --- a/vuvuzela-userland/include/utils/input.h +++ b/vuvuzela-userland/include/utils/input.h @@ -30,7 +30,7 @@ *****************************************************/ /* Clear a line from stdin, to use after a failed scanf (it didn't actually read input) */ -#define sflc_ignoreLine() scanf("%*[^\n]") +#define vvz_ignoreLine() scanf("%*[^\n]") /***************************************************** @@ -38,9 +38,9 @@ *****************************************************/ /* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int sflc_safeReadLine(char *buf, size_t bufsize); +int vvz_safeReadLine(char *buf, size_t bufsize); /* Reads a password or passphrase (discarding the newline) from stdin in a secure way (no echo) */ -int sflc_safeReadPassphrase(char *buf, size_t bufsize); +int vvz_safeReadPassphrase(char *buf, size_t bufsize); #endif /* _UTILS_INPUT_H_ */ diff --git a/vuvuzela-userland/include/utils/log.h b/vuvuzela-userland/include/utils/log.h index 2088fbb..6790ae5 100644 --- a/vuvuzela-userland/include/utils/log.h +++ b/vuvuzela-userland/include/utils/log.h @@ -37,29 +37,29 @@ *****************************************************/ // Printf colours (regular text) -#define SFLC_LOG_BLK "\033[0;30m" -#define SFLC_LOG_RED "\033[0;31m" -#define SFLC_LOG_GRN "\033[0;32m" -#define SFLC_LOG_YEL "\033[0;33m" -#define SFLC_LOG_BLU "\033[0;34m" -#define SFLC_LOG_MAG "\033[0;35m" -#define SFLC_LOG_CYN "\033[0;36m" -#define SFLC_LOG_WHT "\033[0;37m" +#define VVZ_LOG_BLK "\033[0;30m" +#define VVZ_LOG_RED "\033[0;31m" +#define VVZ_LOG_GRN "\033[0;32m" +#define VVZ_LOG_YEL "\033[0;33m" +#define VVZ_LOG_BLU "\033[0;34m" +#define VVZ_LOG_MAG "\033[0;35m" +#define VVZ_LOG_CYN "\033[0;36m" +#define VVZ_LOG_WHT "\033[0;37m" // Printf colours (bold text) -#define SFLC_LOG_BBLK "\033[1;30m" -#define SFLC_LOG_BRED "\033[1;31m" -#define SFLC_LOG_BGRN "\033[1;32m" -#define SFLC_LOG_BYEL "\033[1;33m" -#define SFLC_LOG_BBLU "\033[1;34m" -#define SFLC_LOG_BMAG "\033[1;35m" -#define SFLC_LOG_BCYN "\033[1;36m" -#define SFLC_LOG_BWHT "\033[1;37m" +#define VVZ_LOG_BBLK "\033[1;30m" +#define VVZ_LOG_BRED "\033[1;31m" +#define VVZ_LOG_BGRN "\033[1;32m" +#define VVZ_LOG_BYEL "\033[1;33m" +#define VVZ_LOG_BBLU "\033[1;34m" +#define VVZ_LOG_BMAG "\033[1;35m" +#define VVZ_LOG_BCYN "\033[1;36m" +#define VVZ_LOG_BWHT "\033[1;37m" // Reset colour -#define SFLC_LOG_RESET "\033[0m" +#define VVZ_LOG_RESET "\033[0m" // Log level: debug implies detailed logs -#ifdef CONFIG_SFLC_LOG_DEBUG -#define CONFIG_SFLC_LOG_DETAILED +#ifdef CONFIG_VVZ_LOG_DEBUG +#define CONFIG_VVZ_LOG_DETAILED #endif @@ -68,42 +68,42 @@ *****************************************************/ // Gives the point in the code where it was called -#define sflc_log_detailed(col, ...) do{ \ - printf(SFLC_LOG_GRN "FUNC " SFLC_LOG_RESET "%s() " \ - SFLC_LOG_GRN "FILE " SFLC_LOG_RESET "%s " \ - SFLC_LOG_GRN "LINE " SFLC_LOG_RESET "%d | ", \ +#define vvz_log_detailed(col, ...) do{ \ + printf(VVZ_LOG_GRN "FUNC " VVZ_LOG_RESET "%s() " \ + VVZ_LOG_GRN "FILE " VVZ_LOG_RESET "%s " \ + VVZ_LOG_GRN "LINE " VVZ_LOG_RESET "%d | ", \ __func__, __FILE__, __LINE__); \ - sflc_log_concise(col, __VA_ARGS__); \ + vvz_log_concise(col, __VA_ARGS__); \ }while(0) // Only writes using the given colour -#define sflc_log_concise(col, ...) do{ \ +#define vvz_log_concise(col, ...) do{ \ printf(col); \ printf(__VA_ARGS__); \ - printf(SFLC_LOG_RESET "\n"); \ + printf(VVZ_LOG_RESET "\n"); \ }while(0) // Maps to one or the other, based on a Makefile switch -#ifdef CONFIG_SFLC_LOG_DETAILED - #define sflc_log_colour(...) sflc_log_detailed(__VA_ARGS__) +#ifdef CONFIG_VVZ_LOG_DETAILED + #define vvz_log_colour(...) vvz_log_detailed(__VA_ARGS__) #else - #define sflc_log_colour(...) sflc_log_concise(__VA_ARGS__) + #define vvz_log_colour(...) vvz_log_concise(__VA_ARGS__) #endif // Using specific colours -#define sflc_log_green(...) sflc_log_colour(SFLC_LOG_GRN, __VA_ARGS__) -#define sflc_log_red(...) sflc_log_colour(SFLC_LOG_RED, __VA_ARGS__) -#define sflc_log_yellow(...) sflc_log_colour(SFLC_LOG_YEL, __VA_ARGS__) -#define sflc_log_blue(...) sflc_log_colour(SFLC_LOG_BLU, __VA_ARGS__) -#define sflc_log_normal(...) sflc_log_colour(SFLC_LOG_RESET, __VA_ARGS__) +#define vvz_log_green(...) vvz_log_colour(VVZ_LOG_GRN, __VA_ARGS__) +#define vvz_log_red(...) vvz_log_colour(VVZ_LOG_RED, __VA_ARGS__) +#define vvz_log_yellow(...) vvz_log_colour(VVZ_LOG_YEL, __VA_ARGS__) +#define vvz_log_blue(...) vvz_log_colour(VVZ_LOG_BLU, __VA_ARGS__) +#define vvz_log_normal(...) vvz_log_colour(VVZ_LOG_RESET, __VA_ARGS__) // With log levels -#define sflc_log_error(...) sflc_log_colour(SFLC_LOG_RED, "[ERROR] " __VA_ARGS__) -#define sflc_log_warn(...) sflc_log_colour(SFLC_LOG_MAG, "[WARN] " __VA_ARGS__) -#ifdef CONFIG_SFLC_LOG_DEBUG - #define sflc_log_debug(...) sflc_log_colour(SFLC_LOG_CYN, "[DEBUG] " __VA_ARGS__) +#define vvz_log_error(...) vvz_log_colour(VVZ_LOG_RED, "[ERROR] " __VA_ARGS__) +#define vvz_log_warn(...) vvz_log_colour(VVZ_LOG_MAG, "[WARN] " __VA_ARGS__) +#ifdef CONFIG_VVZ_LOG_DEBUG + #define vvz_log_debug(...) vvz_log_colour(VVZ_LOG_CYN, "[DEBUG] " __VA_ARGS__) #else - #define sflc_log_debug(...) + #define vvz_log_debug(...) #endif @@ -112,7 +112,7 @@ *****************************************************/ // Log a hex string -static inline void sflc_log_hex(char *str, size_t len) +static inline void vvz_log_hex(char *str, size_t len) { int i; unsigned char *s = (unsigned char *) str; diff --git a/vuvuzela-userland/include/utils/string.h b/vuvuzela-userland/include/utils/string.h index ca42c0e..99f057b 100644 --- a/vuvuzela-userland/include/utils/string.h +++ b/vuvuzela-userland/include/utils/string.h @@ -30,10 +30,10 @@ *****************************************************/ /* Malloc's the buffer for the hex string */ -char *sflc_toHex(char *buf, size_t len); +char *vvz_toHex(char *buf, size_t len); /* Replaces all occurrences of character in-place */ -void sflc_str_replaceAll(char *str, char old, char new); +void vvz_str_replaceAll(char *str, char old, char new); #endif /* _UTILS_STRING_H_ */ diff --git a/vuvuzela-userland/include/utils/sflc.h b/vuvuzela-userland/include/utils/vvz.h similarity index 71% rename from vuvuzela-userland/include/utils/sflc.h rename to vuvuzela-userland/include/utils/vvz.h index 99d0243..3263dca 100644 --- a/vuvuzela-userland/include/utils/sflc.h +++ b/vuvuzela-userland/include/utils/vvz.h @@ -22,11 +22,11 @@ */ /* - * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflc_constans.h + * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO vvz_constans.h */ -#ifndef _UTILS_SFLC_H_ -#define _UTILS_SFLC_H_ +#ifndef _UTILS_VVZ_H_ +#define _UTILS_VVZ_H_ /***************************************************** @@ -39,44 +39,44 @@ *****************************************************/ /* Name of the DM target in the kernel */ -#define SFLC_DM_TARGET_NAME "vvz" +#define VVZ_DM_TARGET_NAME "vvz" /* Sizes */ #define KERNEL_SECTOR_SIZE 512 /* bytes */ -#define SFLC_BLOCK_SIZE 4096 /* bytes */ -#define SFLC_BLOCK_SCALE (SFLC_BLOCK_SIZE / KERNEL_SECTOR_SIZE) -#define SFLC_SLICE_SCALE 256 /* blocks in a slice */ -#define SFLC_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ +#define VVZ_BLOCK_SIZE 4096 /* bytes */ +#define VVZ_BLOCK_SCALE (VVZ_BLOCK_SIZE / KERNEL_SECTOR_SIZE) +#define VVZ_SLICE_SCALE 256 /* blocks in a slice */ +#define VVZ_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ /* Max number of volumes in a device */ -#define SFLC_DEV_MAX_VOLUMES 15 +#define VVZ_DEV_MAX_VOLUMES 15 /* Max total number of open devices at any given time */ -#define SFLC_TOT_MAX_DEVICES 1024 -/* A volume name is sflc__ */ -#define SFLC_MAX_VOL_NAME_LEN 15 +#define VVZ_TOT_MAX_DEVICES 1024 +/* A volume name is vvz__ */ +#define VVZ_MAX_VOL_NAME_LEN 15 /* A slice index is represented over 32 bits */ -#define SFLC_SLICE_IDX_WIDTH 4 /* bytes */ +#define VVZ_SLICE_IDX_WIDTH 4 /* bytes */ /* A position map block contains 1024 slice indices */ -#define SFLC_SLICE_IDX_PER_BLOCK (SFLC_BLOCK_SIZE / SFLC_SLICE_IDX_WIDTH) +#define VVZ_SLICE_IDX_PER_BLOCK (VVZ_BLOCK_SIZE / VVZ_SLICE_IDX_WIDTH) /* A PSI of 0xFFFFFFFF indicates an unassigned LSI */ -#define SFLC_EPM_FILLER 0xFF +#define VVZ_EPM_FILLER 0xFF /* The sysfs file containing the next available device ID */ -#define SFLC_SYSFS_NEXTDEVID "/sys/module/dm_vvz/next_dev_id" +#define VVZ_SYSFS_NEXTDEVID "/sys/module/dm_vvz/next_dev_id" /* The sysfs directory containing a subdir for each (underlying) block device */ -#define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_vvz/bdevs" +#define VVZ_SYSFS_BDEVS_DIR "/sys/module/dm_vvz/bdevs" /* Within each bdev's subdir, this file lists its open volumes */ -#define SFLC_SYSFS_OPENVOLUMES_FILENAME "volumes" +#define VVZ_SYSFS_OPENVOLUMES_FILENAME "volumes" /* TODO: reasonable? */ -#define SFLC_BDEV_PATH_MAX_LEN 1024 +#define VVZ_BDEV_PATH_MAX_LEN 1024 /* For when you can't be bothered to upper-bound a buffer size */ -#define SFLC_BIGBUFSIZE 4096 +#define VVZ_BIGBUFSIZE 4096 -#endif /* _UTILS_SFLC_H_ */ +#endif /* _UTILS_VVZ_H_ */ diff --git a/vuvuzela-userland/include/vvz_constants.h b/vuvuzela-userland/include/vvz_constants.h new file mode 100644 index 0000000..9f27092 --- /dev/null +++ b/vuvuzela-userland/include/vvz_constants.h @@ -0,0 +1,41 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * PLACEHOLDER * + *****************************************************/ + +/* This is just a placeholder for defining constants and parameters that must be the same across shufflecake components (kernel module, userland tool, etc) such as block size, slice size etc */ + + +#define VVZ_VER_MAJOR 0 +#define VVZ_VER_MINOR 4 +#define VVZ_VER_REVISION 0 +#define VVZ_VER_SPECIAL "rc1" + +#define STRINGIFY0(s) # s +#define STRINGIFY(s) STRINGIFY0(s) + +#define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL + + diff --git a/vuvuzela-userland/src/cli/changepwd.c b/vuvuzela-userland/src/cli/changepwd.c index de37779..e0f691f 100644 --- a/vuvuzela-userland/src/cli/changepwd.c +++ b/vuvuzela-userland/src/cli/changepwd.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/input.h" #include "utils/log.h" @@ -45,14 +45,14 @@ * * @return Error code, 0 on success */ -int sflc_cli_changePwd(char *block_device) +int vvz_cli_changePwd(char *block_device) { // Requires: block_device is a correct block device path - sflc_cmd_OpenArgs open_args; - sflc_cmd_ChangePwdArgs change_pwd_args; - sflc_DmbCell dmb_cell; - char old_pwd[SFLC_BIGBUFSIZE]; + vvz_cmd_OpenArgs open_args; + vvz_cmd_ChangePwdArgs change_pwd_args; + vvz_DmbCell dmb_cell; + char old_pwd[VVZ_BIGBUFSIZE]; size_t old_pwd_len; - char new_pwd[SFLC_BIGBUFSIZE]; + char new_pwd[VVZ_BIGBUFSIZE]; size_t new_pwd_len; int err; @@ -60,9 +60,9 @@ int sflc_cli_changePwd(char *block_device) /* Gather password */ printf("Enter the password you want to change: "); - err = sflc_safeReadPassphrase(old_pwd, SFLC_BIGBUFSIZE); + err = vvz_safeReadPassphrase(old_pwd, VVZ_BIGBUFSIZE); if (err) { - sflc_log_error("Could not read password; error %d", err); + vvz_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -72,14 +72,14 @@ int sflc_cli_changePwd(char *block_device) open_args.pwd_len = old_pwd_len; /* Test the password */ - err = sflc_cmd_testPwd(&open_args, &dmb_cell); + err = vvz_cmd_testPwd(&open_args, &dmb_cell); if (err) { - sflc_log_error("Could not test password; error %d", err); + vvz_log_error("Could not test password; error %d", err); return err; } /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= VVZ_DEV_MAX_VOLUMES) { printf("This password does not unlock any volume.\n"); return 0; } @@ -87,9 +87,9 @@ int sflc_cli_changePwd(char *block_device) /* Gather new password (no secure shell) */ printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); printf("Choose new password for volume %lu: ", dmb_cell.vol_idx); - err = sflc_safeReadLine(new_pwd, SFLC_BIGBUFSIZE); + err = vvz_safeReadLine(new_pwd, VVZ_BIGBUFSIZE); if (err) { - sflc_log_error("Could not read new password; error %d", err); + vvz_log_error("Could not read new password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -102,9 +102,9 @@ int sflc_cli_changePwd(char *block_device) change_pwd_args.new_pwd_len = new_pwd_len; /* Change password */ - err = sflc_cmd_changePwd(&change_pwd_args); + err = vvz_cmd_changePwd(&change_pwd_args); if (err) { - sflc_log_error("Could not change password; error %d", err); + vvz_log_error("Could not change password; error %d", err); return err; } printf("Password changed successfully.\n"); diff --git a/vuvuzela-userland/src/cli/close.c b/vuvuzela-userland/src/cli/close.c index fdbaa28..a4c8bbd 100644 --- a/vuvuzela-userland/src/cli/close.c +++ b/vuvuzela-userland/src/cli/close.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/input.h" #include "utils/log.h" @@ -45,16 +45,16 @@ * * @return Error code, 0 on success */ -int sflc_cli_close(char *block_device) +int vvz_cli_close(char *block_device) { // Requires: block_device is a correct block device path -// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; +// char bdev_path[VVZ_BDEV_PATH_MAX_LEN + 2]; // int err; // /* Gather (absolute) path to underlying block device */ // printf("Enter the absolute path to the underlying block device containing the Shufflecake volumes to close: "); -// err = sflc_safeReadLine(bdev_path, SFLC_BDEV_PATH_MAX_LEN + 2); +// err = vvz_safeReadLine(bdev_path, VVZ_BDEV_PATH_MAX_LEN + 2); // if (err) { -// sflc_log_error("Could not read path to underlying block device; error %d", err); +// vvz_log_error("Could not read path to underlying block device; error %d", err); // return err; // } // /* Check that it is absolute */ @@ -66,9 +66,9 @@ int sflc_cli_close(char *block_device) /* Actually perform the command */ -// return sflc_cmd_closeVolumes(bdev_path); +// return vvz_cmd_closeVolumes(bdev_path); - return sflc_cmd_closeVolumes(block_device); + return vvz_cmd_closeVolumes(block_device); } diff --git a/vuvuzela-userland/src/cli/dispatch.c b/vuvuzela-userland/src/cli/dispatch.c index 01da250..ad170fa 100644 --- a/vuvuzela-userland/src/cli/dispatch.c +++ b/vuvuzela-userland/src/cli/dispatch.c @@ -32,10 +32,10 @@ #include #include "cli.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/disk.h" #include "utils/log.h" -#include "sflc_constants.h" +#include "vvz_constants.h" /***************************************************** @@ -43,29 +43,29 @@ *****************************************************/ /* Used by argp to provide the automatic "-V" option */ -const char *argp_program_version = SFLC_VERSION; +const char *argp_program_version = VVZ_VERSION; /* Used by argp to provide the automatic "--help" option */ const char *argp_program_bug_address = ""; /* Signed integer values representing a handle for each option */ -#define SFLC_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option -#define SFLC_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this +#define VVZ_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option +#define VVZ_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this /***************************************************** * TYPES * *****************************************************/ -enum sflc_cli_action { - SFLC_ACT_INIT, - SFLC_ACT_OPEN, - SFLC_ACT_CLOSE, - SFLC_ACT_TESTPWD, - SFLC_ACT_CHANGEPWD +enum vvz_cli_action { + VVZ_ACT_INIT, + VVZ_ACT_OPEN, + VVZ_ACT_CLOSE, + VVZ_ACT_TESTPWD, + VVZ_ACT_CHANGEPWD }; -struct sflc_cli_arguments { - enum sflc_cli_action act; +struct vvz_cli_arguments { + enum vvz_cli_action act; char *block_device; int num_volumes; bool skip_randfill; @@ -111,9 +111,9 @@ static char doc[] = /* Description of each option */ static struct argp_option options[] = { - {"num-volumes", SFLC_OPT_NUMVOLS_KEY, "num", 0, + {"num-volumes", VVZ_OPT_NUMVOLS_KEY, "num", 0, "Specify number of volumes to be created with `init'. Must be an integer between 1 and 15.", 0 }, // TODO: define MAX_VOLS instead of hardcoding 15 - {"skip-randfill", SFLC_OPT_SKIPRAND_KEY, 0, 0, + {"skip-randfill", VVZ_OPT_SKIPRAND_KEY, 0, 0, "Skip pre-overwriting block device with random data, only valid with `init'. Faster but less secure. Use only for debugging or testing."}, {0} }; @@ -136,8 +136,8 @@ static struct argp argp = {options, _parseArgpKey, args_doc, doc}; * @return Error code, 0 on success */ -int sflc_cli_dispatch(int argc, char **argv) { - struct sflc_cli_arguments arguments; +int vvz_cli_dispatch(int argc, char **argv) { + struct vvz_cli_arguments arguments; arguments.act = -1; arguments.block_device = NULL; @@ -148,36 +148,36 @@ int sflc_cli_dispatch(int argc, char **argv) { argp_parse(&argp, argc, argv, 0, 0, &arguments); /* Check options consistency */ - if (arguments.num_volumes && arguments.act != SFLC_ACT_INIT) { + if (arguments.num_volumes && arguments.act != VVZ_ACT_INIT) { printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); return EINVAL; } /* Check options consistency */ - if (arguments.skip_randfill && arguments.act != SFLC_ACT_INIT) { + if (arguments.skip_randfill && arguments.act != VVZ_ACT_INIT) { printf("Error: --skip-randfill can only be combined with `init'.\n"); return EINVAL; } /* Check that input is actually a block device */ - if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !sflc_disk_isBlockDevice(arguments.block_device)) { + if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !vvz_disk_isBlockDevice(arguments.block_device)) { printf("Error: '%s' is not a valid block device.\n", arguments.block_device); return EINVAL; } /* Dispatch to specific command */ - if (arguments.act == SFLC_ACT_INIT) { - return sflc_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); + if (arguments.act == VVZ_ACT_INIT) { + return vvz_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); } - if (arguments.act == SFLC_ACT_OPEN) { - return sflc_cli_open(arguments.block_device); + if (arguments.act == VVZ_ACT_OPEN) { + return vvz_cli_open(arguments.block_device); } - if (arguments.act == SFLC_ACT_CLOSE) { - return sflc_cli_close(arguments.block_device); + if (arguments.act == VVZ_ACT_CLOSE) { + return vvz_cli_close(arguments.block_device); } - if (arguments.act == SFLC_ACT_TESTPWD) { - return sflc_cli_testPwd(arguments.block_device); + if (arguments.act == VVZ_ACT_TESTPWD) { + return vvz_cli_testPwd(arguments.block_device); } - if (arguments.act == SFLC_ACT_CHANGEPWD) { - return sflc_cli_changePwd(arguments.block_device); + if (arguments.act == VVZ_ACT_CHANGEPWD) { + return vvz_cli_changePwd(arguments.block_device); } printf("\n"); @@ -191,26 +191,26 @@ int sflc_cli_dispatch(int argc, char **argv) { *****************************************************/ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { - struct sflc_cli_arguments *arguments = state->input; + struct vvz_cli_arguments *arguments = state->input; switch (key) { /* We are parsing an argument (not an option) */ case ARGP_KEY_ARG: /* We are parsing the command */ if (state->arg_num == 0) { - if (strcmp(arg, SFLC_CLI_INITACT) == 0) { - arguments->act = SFLC_ACT_INIT; - } else if (strcmp(arg, SFLC_CLI_OPENACT) == 0) { - arguments->act = SFLC_ACT_OPEN; - } else if (strcmp(arg, SFLC_CLI_CLOSEACT) == 0) { - arguments->act = SFLC_ACT_CLOSE; - } else if (strcmp(arg, SFLC_CLI_TESTPWDACT) == 0) { - arguments->act = SFLC_ACT_TESTPWD; - } else if (strcmp(arg, SFLC_CLI_CHANGEPWDACT) == 0) { - arguments->act = SFLC_ACT_CHANGEPWD; + if (strcmp(arg, VVZ_CLI_INITACT) == 0) { + arguments->act = VVZ_ACT_INIT; + } else if (strcmp(arg, VVZ_CLI_OPENACT) == 0) { + arguments->act = VVZ_ACT_OPEN; + } else if (strcmp(arg, VVZ_CLI_CLOSEACT) == 0) { + arguments->act = VVZ_ACT_CLOSE; + } else if (strcmp(arg, VVZ_CLI_TESTPWDACT) == 0) { + arguments->act = VVZ_ACT_TESTPWD; + } else if (strcmp(arg, VVZ_CLI_CHANGEPWDACT) == 0) { + arguments->act = VVZ_ACT_CHANGEPWD; } else { argp_error(state, "Invalid action. Please enter one and only one of: `%s', `%s', `%s', '%s', or '%s'.", - SFLC_CLI_INITACT, SFLC_CLI_OPENACT, SFLC_CLI_CLOSEACT, SFLC_CLI_TESTPWDACT, SFLC_CLI_CHANGEPWDACT); + VVZ_CLI_INITACT, VVZ_CLI_OPENACT, VVZ_CLI_CLOSEACT, VVZ_CLI_TESTPWDACT, VVZ_CLI_CHANGEPWDACT); } /* We are parsing the block device */ } else if (state->arg_num == 1) { @@ -222,10 +222,10 @@ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { break; /* We are parsing an option */ - case SFLC_OPT_NUMVOLS_KEY: + case VVZ_OPT_NUMVOLS_KEY: arguments->num_volumes = atoi(arg); break; - case SFLC_OPT_SKIPRAND_KEY: + case VVZ_OPT_SKIPRAND_KEY: arguments->skip_randfill = true; break; diff --git a/vuvuzela-userland/src/cli/init.c b/vuvuzela-userland/src/cli/init.c index 302a96d..fc065d9 100644 --- a/vuvuzela-userland/src/cli/init.c +++ b/vuvuzela-userland/src/cli/init.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/input.h" #include "utils/log.h" @@ -45,12 +45,12 @@ * * @return Error code, 0 on success */ -int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) +int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) { // Requires: block_device is a correct block device path - sflc_cmd_InitArgs args; - char str_nrvols[SFLC_BIGBUFSIZE]; - char *pwds[SFLC_DEV_MAX_VOLUMES]; - size_t pwd_lens[SFLC_DEV_MAX_VOLUMES]; + vvz_cmd_InitArgs args; + char str_nrvols[VVZ_BIGBUFSIZE]; + char *pwds[VVZ_DEV_MAX_VOLUMES]; + size_t pwd_lens[VVZ_DEV_MAX_VOLUMES]; int err; args.bdev_path = block_device; @@ -60,15 +60,15 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) args.nr_vols = num_volumes; } else { // If not, ask user for number of volumes - printf("\nHow many volumes do you want to create (maximum is %d)? ", SFLC_DEV_MAX_VOLUMES); - err = sflc_safeReadLine(str_nrvols, SFLC_BIGBUFSIZE); + printf("\nHow many volumes do you want to create (maximum is %d)? ", VVZ_DEV_MAX_VOLUMES); + err = vvz_safeReadLine(str_nrvols, VVZ_BIGBUFSIZE); if (err) { - sflc_log_error("Error: could not read number of volumes; error %d", err); + vvz_log_error("Error: could not read number of volumes; error %d", err); return err; } /* Parse string */ if (sscanf(str_nrvols, "%lu\n", &args.nr_vols) != 1) { - sflc_log_error("Error: could not parse number of volumes"); + vvz_log_error("Error: could not parse number of volumes"); return EINVAL; } } @@ -78,8 +78,8 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) printf("Error: number of volumes must be a positive integer"); return EINVAL; } - if (args.nr_vols > SFLC_DEV_MAX_VOLUMES) { - printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", SFLC_DEV_MAX_VOLUMES); + if (args.nr_vols > VVZ_DEV_MAX_VOLUMES) { + printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", VVZ_DEV_MAX_VOLUMES); return EINVAL; } @@ -89,13 +89,13 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) size_t i; for (i = 0; i < args.nr_vols; i++) { // Allocate pwd - pwds[i] = malloc(SFLC_BIGBUFSIZE); + pwds[i] = malloc(VVZ_BIGBUFSIZE); /* Read it */ printf("Choose password for volume %lu (must not be empty): ", i); - err = sflc_safeReadLine(pwds[i], SFLC_BIGBUFSIZE); + err = vvz_safeReadLine(pwds[i], VVZ_BIGBUFSIZE); if (err) { - sflc_log_error("Could not read password for volume %lu; error %d", i, err); + vvz_log_error("Could not read password for volume %lu; error %d", i, err); return err; } @@ -103,7 +103,7 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) pwd_lens[i] = strlen(pwds[i]); /* Check non-empty */ if (pwd_lens[i] == 0) { - sflc_log_error("Password cannot be empty!"); + vvz_log_error("Password cannot be empty!"); return EINVAL; } } @@ -114,5 +114,5 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) args.no_randfill = skip_randfill; /* Actually perform the command */ - return sflc_cmd_initVolumes(&args); + return vvz_cmd_initVolumes(&args); } diff --git a/vuvuzela-userland/src/cli/open.c b/vuvuzela-userland/src/cli/open.c index 45464c9..3cfe4dd 100644 --- a/vuvuzela-userland/src/cli/open.c +++ b/vuvuzela-userland/src/cli/open.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/input.h" #include "utils/log.h" @@ -45,10 +45,10 @@ * * @return Error code, 0 on success */ -int sflc_cli_open(char *block_device) +int vvz_cli_open(char *block_device) { // Requires: block_device is a correct block device path - sflc_cmd_OpenArgs args; - char pwd[SFLC_BIGBUFSIZE]; + vvz_cmd_OpenArgs args; + char pwd[VVZ_BIGBUFSIZE]; size_t pwd_len; int err; @@ -56,16 +56,16 @@ int sflc_cli_open(char *block_device) /* Gather password */ printf("Enter the password for the most secret volume you want to open: "); - err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); + err = vvz_safeReadPassphrase(pwd, VVZ_BIGBUFSIZE); if (err) { - sflc_log_error("Could not read password; error %d", err); + vvz_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ pwd_len = strlen(pwd); /* Check non-empty */ if (pwd_len == 0) { - sflc_log_error("Password cannot be empty!"); + vvz_log_error("Password cannot be empty!"); return EINVAL; } /* Assign them */ @@ -73,5 +73,5 @@ int sflc_cli_open(char *block_device) args.pwd_len = pwd_len; /* Actually perform the command */ - return sflc_cmd_openVolumes(&args); + return vvz_cmd_openVolumes(&args); } diff --git a/vuvuzela-userland/src/cli/testpwd.c b/vuvuzela-userland/src/cli/testpwd.c index 550df25..48cf710 100644 --- a/vuvuzela-userland/src/cli/testpwd.c +++ b/vuvuzela-userland/src/cli/testpwd.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/input.h" #include "utils/log.h" @@ -45,12 +45,12 @@ * * @return Error code, 0 on success */ -int sflc_cli_testPwd(char *block_device) +int vvz_cli_testPwd(char *block_device) { // Requires: block_device is a correct block device path - sflc_cmd_OpenArgs args; - sflc_DmbCell dmb_cell; -// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; - char pwd[SFLC_BIGBUFSIZE]; + vvz_cmd_OpenArgs args; + vvz_DmbCell dmb_cell; +// char bdev_path[VVZ_BDEV_PATH_MAX_LEN + 2]; + char pwd[VVZ_BIGBUFSIZE]; size_t pwd_len; int err; @@ -58,9 +58,9 @@ int sflc_cli_testPwd(char *block_device) /* Gather password */ printf("Enter the password you want to test: "); - err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); + err = vvz_safeReadPassphrase(pwd, VVZ_BIGBUFSIZE); if (err) { - sflc_log_error("Could not read password; error %d", err); + vvz_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -70,14 +70,14 @@ int sflc_cli_testPwd(char *block_device) args.pwd_len = pwd_len; /* Actually perform the command */ - err = sflc_cmd_testPwd(&args, &dmb_cell); + err = vvz_cmd_testPwd(&args, &dmb_cell); if (err) { - sflc_log_error("Could not test password; error %d", err); + vvz_log_error("Could not test password; error %d", err); return err; } /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= VVZ_DEV_MAX_VOLUMES) { printf("This password does not unlock any volume.\n"); } else { printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); diff --git a/vuvuzela-userland/src/commands/change_pwd.c b/vuvuzela-userland/src/commands/change_pwd.c index 2ef64e0..a56b3dc 100644 --- a/vuvuzela-userland/src/commands/change_pwd.c +++ b/vuvuzela-userland/src/commands/change_pwd.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/log.h" @@ -51,8 +51,8 @@ * * @return Error code, 0 on success */ -int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args) +int vvz_cmd_changePwd(vvz_cmd_ChangePwdArgs *args) { /* Delegate entirely to the function reading the DMB */ - return sflc_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); + return vvz_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); } diff --git a/vuvuzela-userland/src/commands/close.c b/vuvuzela-userland/src/commands/close.c index 4c180f6..e3784bc 100644 --- a/vuvuzela-userland/src/commands/close.c +++ b/vuvuzela-userland/src/commands/close.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/crypto.h" #include "utils/string.h" #include "utils/file.h" @@ -60,18 +60,18 @@ static int _closeVolumes(char **labels, size_t nr_vols); * * @return Error code, 0 on success */ -int sflc_cmd_closeVolumes(char *bdev_path) +int vvz_cmd_closeVolumes(char *bdev_path) { - char *labels[SFLC_DEV_MAX_VOLUMES]; + char *labels[VVZ_DEV_MAX_VOLUMES]; size_t nr_vols; int err; /* Allocate labels */ size_t i; - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { - labels[i] = malloc(SFLC_MAX_VOL_NAME_LEN + 1); + for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) { + labels[i] = malloc(VVZ_MAX_VOL_NAME_LEN + 1); if (!labels[1]) { - sflc_log_error("Could not allocate volume label %lu", i); + vvz_log_error("Could not allocate volume label %lu", i); return ENOMEM; // Do not free the ones already allocated } } @@ -79,14 +79,14 @@ int sflc_cmd_closeVolumes(char *bdev_path) /* Read them */ err = _readVolumesList(bdev_path, labels, &nr_vols); if (err) { - sflc_log_error("Could not read volume list from sysfs; error %d", err); + vvz_log_error("Could not read volume list from sysfs; error %d", err); goto out; } /* Close the volumes (in reverse order of opening) */ err = _closeVolumes(labels, nr_vols); if (err) { - sflc_log_error("Could not close volumes; error %d", err); + vvz_log_error("Could not close volumes; error %d", err); goto out; } @@ -95,7 +95,7 @@ int sflc_cmd_closeVolumes(char *bdev_path) out: - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { + for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) { free(labels[i]); } return err; @@ -109,20 +109,20 @@ out: /* Reads the list of volumes from sysfs */ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) { - char bdev_path_noslash[SFLC_BDEV_PATH_MAX_LEN + 1]; - char openvolumes_path[SFLC_BIGBUFSIZE]; + char bdev_path_noslash[VVZ_BDEV_PATH_MAX_LEN + 1]; + char openvolumes_path[VVZ_BIGBUFSIZE]; char *str_openvolumes; /* Remove the slashes from the bdev_path (replace with underscores) */ strcpy(bdev_path_noslash, bdev_path); - sflc_str_replaceAll(bdev_path_noslash, '/', '_'); + vvz_str_replaceAll(bdev_path_noslash, '/', '_'); /* Build path to sysfsy file containing open volumes list */ - sprintf(openvolumes_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_path_noslash, SFLC_SYSFS_OPENVOLUMES_FILENAME); + sprintf(openvolumes_path, "%s/%s/%s", VVZ_SYSFS_BDEVS_DIR, bdev_path_noslash, VVZ_SYSFS_OPENVOLUMES_FILENAME); /* Read the sysfs file */ - str_openvolumes = sflc_readFile(openvolumes_path); + str_openvolumes = vvz_readFile(openvolumes_path); if (!str_openvolumes) { - sflc_log_error("Could not read file %s", openvolumes_path); + vvz_log_error("Could not read file %s", openvolumes_path); return EBADF; } @@ -133,8 +133,8 @@ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) str_openvolumes = endptr; /* Just to be sure */ - if (*nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); + if (*nr_vols > VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); return EBADF; } @@ -143,10 +143,10 @@ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) for (i = 0; i < *nr_vols; i++) { /* Trust the content of the sysfs file */ if (sscanf(str_openvolumes, " %s", labels[i]) != 1) { - sflc_log_error("Could not read volume label %lu. Sysfs content:\n%s", i, str_openvolumes); + vvz_log_error("Could not read volume label %lu. Sysfs content:\n%s", i, str_openvolumes); return EBADF; } - sflc_log_debug("Label %lu to close: %s", i, labels[i]); + vvz_log_debug("Label %lu to close: %s", i, labels[i]); /* Skip past the whitespace and the label */ str_openvolumes += 1 + strlen(labels[i]); @@ -164,12 +164,12 @@ static int _closeVolumes(char **labels, size_t nr_vols) /* Eazy peazy */ int i; for (i = nr_vols-1; i >= 0; i--) { - err = sflc_ops_closeVolume(labels[i]); + err = vvz_ops_closeVolume(labels[i]); if (err) { - sflc_log_error("Could not close volume %s; error %d", labels[i], err); + vvz_log_error("Could not close volume %s; error %d", labels[i], err); return err; } - sflc_log_debug("Closed volume %s", labels[i]); + vvz_log_debug("Closed volume %s", labels[i]); printf("Closed volume /dev/mapper/%s\n", labels[i]); } diff --git a/vuvuzela-userland/src/commands/init.c b/vuvuzela-userland/src/commands/init.c index e27e840..69eda0d 100644 --- a/vuvuzela-userland/src/commands/init.c +++ b/vuvuzela-userland/src/commands/init.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -42,9 +42,9 @@ *****************************************************/ /* The device is randomised in chunks of 1024 blocks (arbitrary number) */ -#define SFLC_BLOCKS_IN_RAND_CHUNK 1024 +#define VVZ_BLOCKS_IN_RAND_CHUNK 1024 /* That's 4 MiB */ -#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_BLOCK_SIZE) +#define VVZ_RAND_CHUNK_SIZE (VVZ_BLOCKS_IN_RAND_CHUNK * VVZ_BLOCK_SIZE) /***************************************************** @@ -72,36 +72,36 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); * * @return Error code, 0 on success */ -int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) +int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args) { - sflc_Dmb dmb; - sflc_Vmb vmb; + vvz_Dmb dmb; + vvz_Vmb vmb; int64_t dev_size; size_t nr_slices; int err; /* Sanity check */ - if (args->nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot create %lu volumes on a single device", args->nr_vols); + if (args->nr_vols > VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("Cannot create %lu volumes on a single device", args->nr_vols); return EINVAL; } /* Get device size */ - dev_size = sflc_disk_getSize(args->bdev_path); + dev_size = vvz_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; - sflc_log_error("Could not get device size for %s; error %d", args->bdev_path, err); + vvz_log_error("Could not get device size for %s; error %d", args->bdev_path, err); return err; } /* Convert to number of slices */ - nr_slices = sflc_disk_maxSlices(dev_size); - sflc_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); + nr_slices = vvz_disk_maxSlices(dev_size); + vvz_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); /* Fill disk with random bytes, if requested */ if (!args->no_randfill) { err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); if (err) { - sflc_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); + vvz_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); return err; } } @@ -111,16 +111,16 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) /* Sample the VMB keys */ size_t i; for (i = 0; i < dmb.nr_vols; i++) { - err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_STANDARD_KEYLEN); + err = vvz_rand_getStrongBytes(dmb.vmb_keys[i], VVZ_STANDARD_KEYLEN); if (err) { - sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); + vvz_log_error("Could not sample VMB key number %lu; error %d", i , err); return err; } } /* And write (encrypted) to disk */ - err = sflc_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); + err = vvz_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); if (err) { - sflc_log_error("Could not create DMB and write it to disk; error %d", err); + vvz_log_error("Could not create DMB and write it to disk; error %d", err); return err; } @@ -129,15 +129,15 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) for (i = 0; i < args->nr_vols; i++) { /* This volume's prev_vmb_key */ if (i > 0) { - memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_STANDARD_KEYLEN); + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], VVZ_STANDARD_KEYLEN); } /* Sample this volume's VEK */ - sflc_rand_getStrongBytes(vmb.volume_key, SFLC_STANDARD_KEYLEN); + vvz_rand_getStrongBytes(vmb.volume_key, VVZ_STANDARD_KEYLEN); /* Write complete volume header (VMB + PM) */ - err = sflc_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); + err = vvz_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); if (err) { - sflc_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); + vvz_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); return err; } } @@ -158,9 +158,9 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) int err; /* Allocate chunk */ - rand_chunk = malloc(SFLC_RAND_CHUNK_SIZE); + rand_chunk = malloc(VVZ_RAND_CHUNK_SIZE); if (!rand_chunk) { - sflc_log_error("Could not allocate %d bytes for chunk of random data", SFLC_RAND_CHUNK_SIZE); + vvz_log_error("Could not allocate %d bytes for chunk of random data", VVZ_RAND_CHUNK_SIZE); return ENOMEM; } @@ -169,20 +169,20 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) uint64_t sector = 0; while (blocks_remaining > 0) { uint64_t blocks_to_write = - (blocks_remaining > SFLC_BLOCKS_IN_RAND_CHUNK) ? SFLC_BLOCKS_IN_RAND_CHUNK : blocks_remaining; - uint64_t bytes_to_write = blocks_to_write * SFLC_BLOCK_SIZE; + (blocks_remaining > VVZ_BLOCKS_IN_RAND_CHUNK) ? VVZ_BLOCKS_IN_RAND_CHUNK : blocks_remaining; + uint64_t bytes_to_write = blocks_to_write * VVZ_BLOCK_SIZE; /* Sample random bytes */ - err = sflc_rand_getWeakBytes(rand_chunk, bytes_to_write); + err = vvz_rand_getWeakBytes(rand_chunk, bytes_to_write); if (err) { - sflc_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); + vvz_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); goto out; } /* Write on disk */ - err = sflc_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); + err = vvz_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); if (err) { - sflc_log_error("Could not write random bytes on disk; error %d", err); + vvz_log_error("Could not write random bytes on disk; error %d", err); goto out; } diff --git a/vuvuzela-userland/src/commands/open.c b/vuvuzela-userland/src/commands/open.c index 6c58225..6b789bd 100644 --- a/vuvuzela-userland/src/commands/open.c +++ b/vuvuzela-userland/src/commands/open.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/crypto.h" #include "utils/disk.h" #include "utils/file.h" @@ -63,33 +63,33 @@ static int _getNextDevId(size_t *next_dev_id); * * @return Error code (also if no volume could be opened), 0 on success */ -int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) +int vvz_cmd_openVolumes(vvz_cmd_OpenArgs *args) { int64_t dev_size; size_t nr_slices; - sflc_DmbCell dmb_cell; - sflc_Vmb vmbs[SFLC_DEV_MAX_VOLUMES]; + vvz_DmbCell dmb_cell; + vvz_Vmb vmbs[VVZ_DEV_MAX_VOLUMES]; size_t dev_id; int err; /* Get number of slices */ - dev_size = sflc_disk_getSize(args->bdev_path); + dev_size = vvz_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; - sflc_log_error("Could not read device size for %s; error %d", args->bdev_path, err); + vvz_log_error("Could not read device size for %s; error %d", args->bdev_path, err); return err; } - nr_slices = sflc_disk_maxSlices(dev_size); + nr_slices = vvz_disk_maxSlices(dev_size); /* Find volume opened by the pwd */ - err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); + err = vvz_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); if (err) { - sflc_log_error("Could not read DMB; error %d", err); + vvz_log_error("Could not read DMB; error %d", err); return err; } /* Was there one? */ - if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("The provided password opens no volume on the device"); + if (dmb_cell.vol_idx >= VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("The provided password opens no volume on the device"); return EINVAL; } printf("Password is correct! Opening volumes...\n"); @@ -108,9 +108,9 @@ int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) } /* Read and unlock VMB */ - err = sflc_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); + err = vvz_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); if (err) { - sflc_log_error("Could not read VMB %d on device %s; error %d", + vvz_log_error("Could not read VMB %d on device %s; error %d", i, args->bdev_path, err); return err; } @@ -119,23 +119,23 @@ int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) /* Get the ID that will be assigned to the block device */ err = _getNextDevId(&dev_id); if (err) { - sflc_log_error("Could not get next device ID; error %d", err); + vvz_log_error("Could not get next device ID; error %d", err); return err; } - sflc_log_debug("Next device ID is %lu", dev_id); + vvz_log_debug("Next device ID is %lu", dev_id); /* Open volumes "in order" */ for (i = 0; i <= dmb_cell.vol_idx; i++) { - err = sflc_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); + err = vvz_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); if (err) { - sflc_log_error("Could not open volume %d; error %d. " + vvz_log_error("Could not open volume %d; error %d. " "Previous volumes on the device might have already " "been opened, it's recommended you close them", i, err); return err; } - sflc_log_debug("Successfully opened volume %d with VMB key", i); - printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); + vvz_log_debug("Successfully opened volume %d with VMB key", i); + printf("Opened volume /dev/mapper/vvz_%lu_%d\n", dev_id, i); } return 0; @@ -153,21 +153,21 @@ static int _getNextDevId(size_t *next_dev_id) int err; /* Read sysfs entry */ - str_nextdevid = sflc_readFile(SFLC_SYSFS_NEXTDEVID); + str_nextdevid = vvz_readFile(VVZ_SYSFS_NEXTDEVID); if (!str_nextdevid) { - sflc_log_error("Could not read sysfs entry %s", SFLC_SYSFS_NEXTDEVID); + vvz_log_error("Could not read sysfs entry %s", VVZ_SYSFS_NEXTDEVID); return EINVAL; } /* Parse integer */ if (sscanf(str_nextdevid, "%lu", next_dev_id) != 1) { - sflc_log_error("Error parsing content of file %s", SFLC_SYSFS_NEXTDEVID); + vvz_log_error("Error parsing content of file %s", VVZ_SYSFS_NEXTDEVID); err = EINVAL; goto err_devid; } /* Sanity check */ - if (*next_dev_id >= SFLC_TOT_MAX_DEVICES) { - sflc_log_error("There are already %d open devices, this is the maximum allowed", SFLC_TOT_MAX_DEVICES); + if (*next_dev_id >= VVZ_TOT_MAX_DEVICES) { + vvz_log_error("There are already %d open devices, this is the maximum allowed", VVZ_TOT_MAX_DEVICES); err = E2BIG; goto err_devid; } diff --git a/vuvuzela-userland/src/commands/test_pwd.c b/vuvuzela-userland/src/commands/test_pwd.c index f794347..1d011c7 100644 --- a/vuvuzela-userland/src/commands/test_pwd.c +++ b/vuvuzela-userland/src/commands/test_pwd.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/log.h" @@ -52,8 +52,8 @@ * * @return Error code, 0 on success */ -int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell) +int vvz_cmd_testPwd(vvz_cmd_OpenArgs *args, vvz_DmbCell *dmb_cell) { /* Delegate entirely to the function reading the DMB */ - return sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); + return vvz_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); } diff --git a/vuvuzela-userland/src/header/device_master_block.c b/vuvuzela-userland/src/header/device_master_block.c index 1cfcd9b..a6522d6 100644 --- a/vuvuzela-userland/src/header/device_master_block.c +++ b/vuvuzela-userland/src/header/device_master_block.c @@ -60,21 +60,21 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool * * @return The error code, 0 on success */ -int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) +int vvz_dmb_seal(vvz_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) { char *salt; int err; /* Sanity check */ - if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); + if (dmb->nr_vols > VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); return EINVAL; } /* Randomise whole block */ - err = sflc_rand_getWeakBytes(disk_block, SFLC_BLOCK_SIZE); + err = vvz_rand_getWeakBytes(disk_block, VVZ_BLOCK_SIZE); if (err) { - sflc_log_error("Could not randomise DMB; error %d", err); + vvz_log_error("Could not randomise DMB; error %d", err); return err; } @@ -84,12 +84,12 @@ int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block /* Loop over all VMB keys to encrypt them */ size_t i; for (i = 0; i < dmb->nr_vols; i++) { - char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); + char *dmb_cell = (salt + VVZ_ARGON_SALTLEN) + (i * VVZ_DMB_CELL_SIZE); /* Encrypt it */ err = _encryptVmbKeyWithPwd(salt, pwds[i], pwd_lens[i], dmb->vmb_keys[i], dmb_cell); if (err) { - sflc_log_error("Could not encrypt VMB key number %lu; error %d", i, err); + vvz_log_error("Could not encrypt VMB key number %lu; error %d", i, err); return err; } } @@ -106,50 +106,50 @@ int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block * @param pwd_len Its length * * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vol_idx Its index (>= VVZ_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell) +int vvz_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, vvz_DmbCell *dmb_cell) { // KDF salt char *salt; // The KDF-derived key - char kek[SFLC_STANDARD_KEYLEN]; + char kek[VVZ_STANDARD_KEYLEN]; // The unlocked VMB key - char vmb_key[SFLC_STANDARD_KEYLEN]; + char vmb_key[VVZ_STANDARD_KEYLEN]; // Error code int err; /* Derive KEK once and for all */ salt = disk_block; - err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); + err = vvz_argon2id_derive(pwd, pwd_len, salt, kek); if (err) { - sflc_log_error("Could not perform KDF: error %d", err); + vvz_log_error("Could not perform KDF: error %d", err); goto bad_kdf; } - sflc_log_debug("Successfully derived key-encryption-key with KDF"); + vvz_log_debug("Successfully derived key-encryption-key with KDF"); /* Init dmb->vol_idx to invalid */ - dmb_cell->vol_idx = SFLC_DEV_MAX_VOLUMES; + dmb_cell->vol_idx = VVZ_DEV_MAX_VOLUMES; /* Try all DMB cells */ size_t i; - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { - char *enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); + for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) { + char *enc_dmb_cell = (salt + VVZ_ARGON_SALTLEN) + (i * VVZ_DMB_CELL_SIZE); bool match; /* Try to decrypt this one */ err = _decryptVmbKeyWithPwd(enc_dmb_cell, kek, vmb_key, &match); if (err) { - sflc_log_error("Error decrypting DMB cell number %lu; error %d", i, err); + vvz_log_error("Error decrypting DMB cell number %lu; error %d", i, err); goto bad_decrypt; } /* If MAC matched, mark it, but don't break from the loop (timing attacks) */ if (match) { - sflc_log_debug("The provided password unlocks volume %lu", i); + vvz_log_debug("The provided password unlocks volume %lu", i); dmb_cell->vol_idx = i; - memcpy(dmb_cell->vmb_key, vmb_key, SFLC_STANDARD_KEYLEN); + memcpy(dmb_cell->vmb_key, vmb_key, VVZ_STANDARD_KEYLEN); } } @@ -160,7 +160,7 @@ int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *d bad_decrypt: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLC_STANDARD_KEYLEN); + memset(kek, 0, VVZ_STANDARD_KEYLEN); return err; } @@ -174,28 +174,28 @@ bad_kdf: * * @return Error code, 0 on success */ -int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len) +int vvz_dmb_setCell(char *disk_block, vvz_DmbCell *dmb_cell, char *pwd, size_t pwd_len) { char *salt; char *enc_dmb_cell; int err; /* Sanity check */ - if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + if (dmb_cell->vol_idx >= VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); return EINVAL; } /* Pointers inside DMB */ salt = disk_block; - enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLC_DMB_CELL_SIZE); + enc_dmb_cell = (salt + VVZ_ARGON_SALTLEN) + (dmb_cell->vol_idx * VVZ_DMB_CELL_SIZE); /* Encrypt with KDF-derived key */ err = _encryptVmbKeyWithPwd(salt, pwd, pwd_len, dmb_cell->vmb_key, enc_dmb_cell); if (err) { - sflc_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); + vvz_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); return err; } - sflc_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); + vvz_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); return 0; } @@ -210,36 +210,36 @@ static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vm { // Pointers inside the block char *iv = dmb_cell; - char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLC_STANDARD_KEYLEN; + char *enc_vmb_key = iv + VVZ_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + VVZ_STANDARD_KEYLEN; // Key-encryption-key derived from KDF - char kek[SFLC_STANDARD_KEYLEN]; + char kek[VVZ_STANDARD_KEYLEN]; // Error code int err; /* Derive KEK */ - err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); + err = vvz_argon2id_derive(pwd, pwd_len, salt, kek); if (err) { - sflc_log_error("Could not perform KDF: error %d", err); + vvz_log_error("Could not perform KDF: error %d", err); goto bad_kdf; } - sflc_log_debug("Successfully derived key-encryption-key with KDF"); + vvz_log_debug("Successfully derived key-encryption-key with KDF"); /* Sample VMB_IV */ - err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); + err = vvz_rand_getWeakBytes(iv, VVZ_AESGCM_PADDED_IVLEN); if (err) { - sflc_log_error("Could not sample prologue IV: error %d", err); + vvz_log_error("Could not sample prologue IV: error %d", err); goto bad_sample_iv; } - sflc_log_debug("Successfully sampled prologue IV"); + vvz_log_debug("Successfully sampled prologue IV"); /* Encrypt the VMB key */ - err = sflc_aes256gcm_encrypt(kek, vmb_key, SFLC_STANDARD_KEYLEN, iv, enc_vmb_key, mac); + err = vvz_aes256gcm_encrypt(kek, vmb_key, VVZ_STANDARD_KEYLEN, iv, enc_vmb_key, mac); if (err) { - sflc_log_error("Could not encrypt the VMB key: error %d", err); + vvz_log_error("Could not encrypt the VMB key: error %d", err); goto bad_encrypt; } - sflc_log_debug("Successfully encrypted VMB key with key-encryption-key"); + vvz_log_debug("Successfully encrypted VMB key with key-encryption-key"); // No prob err = 0; @@ -249,7 +249,7 @@ bad_encrypt: bad_sample_iv: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLC_STANDARD_KEYLEN); + memset(kek, 0, VVZ_STANDARD_KEYLEN); return err; } @@ -258,18 +258,18 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool { // Pointers inside the block char *iv = dmb_cell; - char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLC_STANDARD_KEYLEN; + char *enc_vmb_key = iv + VVZ_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + VVZ_STANDARD_KEYLEN; // Error code int err; /* Decrypt the VMB key */ - err = sflc_aes256gcm_decrypt(kek, enc_vmb_key, SFLC_STANDARD_KEYLEN, mac, iv, vmb_key, match); + err = vvz_aes256gcm_decrypt(kek, enc_vmb_key, VVZ_STANDARD_KEYLEN, mac, iv, vmb_key, match); if (err) { - sflc_log_error("Error while decrypting VMB key: error %d", err); + vvz_log_error("Error while decrypting VMB key: error %d", err); return err; } - sflc_log_debug("Decrypted VMB key: MAC match = %d", *match); + vvz_log_debug("Decrypted VMB key: MAC match = %d", *match); return 0; } diff --git a/vuvuzela-userland/src/header/position_map.c b/vuvuzela-userland/src/header/position_map.c index 051161f..e48f304 100644 --- a/vuvuzela-userland/src/header/position_map.c +++ b/vuvuzela-userland/src/header/position_map.c @@ -31,7 +31,7 @@ #include #include "header.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/crypto.h" #include "utils/math.h" #include "utils/log.h" @@ -49,38 +49,38 @@ * position map as well. * * @return The memory buffer containing the position map */ -void *sflc_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) +void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) { - char pmb[SFLC_BLOCK_SIZE]; - char iv[SFLC_AESXTS_IVLEN]; + char pmb[VVZ_BLOCK_SIZE]; + char iv[VVZ_AESXTS_IVLEN]; void *epm; size_t nr_pmbs; int err; // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) - nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + nr_pmbs = ceil(nr_slices, VVZ_SLICE_IDX_PER_BLOCK); // Allocate EPM - epm = malloc(nr_pmbs * SFLC_BLOCK_SIZE); + epm = malloc(nr_pmbs * VVZ_BLOCK_SIZE); if (!epm) { - sflc_log_error("Could not malloc EPM array"); + vvz_log_error("Could not malloc EPM array"); return NULL; } // Fill cleartext PMB with 0xFF - memset(pmb, SFLC_EPM_FILLER, SFLC_BLOCK_SIZE); + memset(pmb, VVZ_EPM_FILLER, VVZ_BLOCK_SIZE); // Set the IV for the first encryption - memset(iv, 0, SFLC_AESXTS_IVLEN); - *((uint64_t)iv) = htole64(sflc_pmStartBlock(vol_idx, nr_slices)); + memset(iv, 0, VVZ_AESXTS_IVLEN); + *((uint64_t)iv) = htole64(vvz_pmStartBlock(vol_idx, nr_slices)); // Loop to encrypt each PMB int i; for (i = 0; i < nr_pmbs; i++) { // Encrypt. Auto-increment IV for next encryption - err = sflc_aes256xts_encrypt(volume_key, pmb, SFLC_BLOCK_SIZE, iv, - epm + i*SFLC_BLOCK_SIZE); + err = vvz_aes256xts_encrypt(volume_key, pmb, VVZ_BLOCK_SIZE, iv, + epm + i*VVZ_BLOCK_SIZE); if (err) { - sflc_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); + vvz_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); free(epm); return NULL; } diff --git a/vuvuzela-userland/src/header/volume_master_block.c b/vuvuzela-userland/src/header/volume_master_block.c index d73d98d..5f153c9 100644 --- a/vuvuzela-userland/src/header/volume_master_block.c +++ b/vuvuzela-userland/src/header/volume_master_block.c @@ -41,10 +41,10 @@ *****************************************************/ /* Serialise the VMB before encrypting it */ -static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb); +static void _serialiseVmb(vvz_Vmb *vmb, char *clear_vmb); /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); +static int _deserialiseVmb(char *clear_vmb, vvz_Vmb *vmb); /***************************************************** @@ -61,44 +61,44 @@ static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); * * @return The error code, 0 on success */ -int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) +int vvz_vmb_seal(vvz_Vmb *vmb, char *vmb_key, char *disk_block) { // Pointers inside the block char *iv = disk_block; - char *enc_vmb = iv + SFLC_AESCTR_IVLEN; + char *enc_vmb = iv + VVZ_AESCTR_IVLEN; // Serialised VMB (dynamically allocated), to be encrypted char *clear_vmb; // Error code int err; /* Allocate large buffer on the heap */ - clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); + clear_vmb = malloc(VVZ_CLEAR_VMB_LEN); if (!clear_vmb) { - sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + vvz_log_error("Could not allocate %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); err = ENOMEM; goto bad_clear_alloc; } - sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + vvz_log_debug("Successfully allocated %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); /* Serialise the struct */ _serialiseVmb(vmb, clear_vmb); - sflc_log_debug("Serialised VMB struct"); + vvz_log_debug("Serialised VMB struct"); /* Sample VMB IV */ - err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); + err = vvz_rand_getWeakBytes(iv, VVZ_AESGCM_PADDED_IVLEN); if (err) { - sflc_log_error("Could not sample VMB IV: error %d", err); + vvz_log_error("Could not sample VMB IV: error %d", err); goto bad_sample_iv; } - sflc_log_debug("Successfully sampled VMB IV"); + vvz_log_debug("Successfully sampled VMB IV"); /* Encrypt the VMB */ - err = sflc_aes256ctr_encrypt(vmb_key, clear_vmb, SFLC_CLEAR_VMB_LEN, iv, enc_vmb); + err = vvz_aes256ctr_encrypt(vmb_key, clear_vmb, VVZ_CLEAR_VMB_LEN, iv, enc_vmb); if (err) { - sflc_log_error("Could not encrypt VMB: error %d", err); + vvz_log_error("Could not encrypt VMB: error %d", err); goto bad_encrypt; } - sflc_log_debug("Successfully encrypted VMB"); + vvz_log_debug("Successfully encrypted VMB"); // No prob err = 0; @@ -107,7 +107,7 @@ int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) bad_encrypt: bad_sample_iv: /* Always wipe and free the cleartext VMB, even on success */ - memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); + memset(clear_vmb, 0, VVZ_CLEAR_VMB_LEN); free(clear_vmb); bad_clear_alloc: return err; @@ -123,40 +123,40 @@ bad_clear_alloc: * * @return An error code, 0 on success */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) +int vvz_vmb_unseal(char *disk_block, char *vmb_key, vvz_Vmb *vmb) { // Pointers inside the block char *iv = disk_block; - char *enc_vmb = iv + SFLC_AESCTR_IVLEN; + char *enc_vmb = iv + VVZ_AESCTR_IVLEN; // Decrypted VMB (dynamically allocated), to be deserialised char *clear_vmb; // Error code int err; /* Allocate large buffer on the heap */ - clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); + clear_vmb = malloc(VVZ_CLEAR_VMB_LEN); if (!clear_vmb) { - sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + vvz_log_error("Could not allocate %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); err = ENOMEM; goto bad_clear_alloc; } - sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + vvz_log_debug("Successfully allocated %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); /* Decrypt the VMB */ - err = sflc_aes256ctr_decrypt(vmb_key, enc_vmb, SFLC_CLEAR_VMB_LEN, iv, clear_vmb); + err = vvz_aes256ctr_decrypt(vmb_key, enc_vmb, VVZ_CLEAR_VMB_LEN, iv, clear_vmb); if (err) { - sflc_log_error("Error while decrypting VMB: error %d", err); + vvz_log_error("Error while decrypting VMB: error %d", err); goto bad_decrypt; } - sflc_log_debug("Successfully decrypted VMB"); + vvz_log_debug("Successfully decrypted VMB"); /* Deserialise the struct */ err = _deserialiseVmb(clear_vmb, vmb); if (err) { - sflc_log_error("Error while deserialising VMB: error %d", err); + vvz_log_error("Error while deserialising VMB: error %d", err); goto bad_deserialise; } - sflc_log_debug("Deserialised VMB struct"); + vvz_log_debug("Deserialised VMB struct"); // No prob err = 0; @@ -165,7 +165,7 @@ int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) bad_deserialise: bad_decrypt: /* Always wipe and free the VMB cleartext, even on success */ - memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); + memset(clear_vmb, 0, VVZ_CLEAR_VMB_LEN); free(clear_vmb); bad_clear_alloc: return err; @@ -177,18 +177,18 @@ bad_clear_alloc: *****************************************************/ /* Serialise the payload before encrypting it */ -static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) +static void _serialiseVmb(vvz_Vmb *vmb, char *clear_vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLC_STANDARD_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + VVZ_STANDARD_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + VVZ_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(p_vol_key, vmb->volume_key, SFLC_STANDARD_KEYLEN); + memcpy(p_vol_key, vmb->volume_key, VVZ_STANDARD_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_STANDARD_KEYLEN); + memcpy(p_prev_vmb_key, vmb->prev_vmb_key, VVZ_STANDARD_KEYLEN); /* Write the number of slices (network byte order) */ *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); @@ -200,18 +200,18 @@ static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) +static int _deserialiseVmb(char *clear_vmb, vvz_Vmb *vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLC_STANDARD_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + VVZ_STANDARD_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + VVZ_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(vmb->volume_key, p_vol_key, SFLC_STANDARD_KEYLEN); + memcpy(vmb->volume_key, p_vol_key, VVZ_STANDARD_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_STANDARD_KEYLEN); + memcpy(vmb->prev_vmb_key, p_prev_vmb_key, VVZ_STANDARD_KEYLEN); /* Read number of slices (network byte order) */ vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); diff --git a/vuvuzela-userland/src/main.c b/vuvuzela-userland/src/main.c index 737b57e..08a4b12 100644 --- a/vuvuzela-userland/src/main.c +++ b/vuvuzela-userland/src/main.c @@ -39,6 +39,6 @@ int main(int argc, char **argv) { - return sflc_cli_dispatch(argc, argv); + return vvz_cli_dispatch(argc, argv); } diff --git a/vuvuzela-userland/src/operations/devmapper.c b/vuvuzela-userland/src/operations/devmapper.c index 91b3b51..2f622b5 100644 --- a/vuvuzela-userland/src/operations/devmapper.c +++ b/vuvuzela-userland/src/operations/devmapper.c @@ -33,7 +33,7 @@ #include "header.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/string.h" @@ -46,7 +46,7 @@ *****************************************************/ /** - * Build parameter list for ctor in dm_sflc, and send DM ioctl to create + * Build parameter list for ctor in dm_vvz, and send DM ioctl to create * virtual block device. * * @param bdev_path The path to the underlying device @@ -56,35 +56,35 @@ * * @return Error code, 0 on success */ -int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb) +int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb *vmb) { - char label[SFLC_BIGBUFSIZE]; + char label[VVZ_BIGBUFSIZE]; char *hex_key; - char params[SFLC_BIGBUFSIZE]; + char params[VVZ_BIGBUFSIZE]; uint64_t num_sectors; int err; /* Build volume label */ - sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); + sprintf(label, "vvz_%lu_%lu", dev_id, vol_idx); /* Get the hex version of the volume's data section key */ - hex_key = sflc_toHex(vmb->volume_key, SFLC_STANDARD_KEYLEN); + hex_key = vvz_toHex(vmb->volume_key, VVZ_STANDARD_KEYLEN); if (!hex_key) { - sflc_log_error("Could not encode volume key to hexadecimal"); + vvz_log_error("Could not encode volume key to hexadecimal"); err = ENOMEM; goto err_hexkey; } /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_BLOCK_SCALE; + num_sectors = ((uint64_t) vmb->nr_slices) * VVZ_BLOCKS_PER_LOG_SLICE * VVZ_BLOCK_SCALE; /* Build param list */ sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); /* Issue ioctl */ - err = sflc_dm_create(label, num_sectors, params); + err = vvz_dm_create(label, num_sectors, params); if (err) { - sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); + vvz_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); goto err_dmcreate; } err = 0; @@ -104,8 +104,8 @@ err_hexkey: * * @return Error code, 0 on success */ -int sflc_ops_closeVolume(char *label) +int vvz_ops_closeVolume(char *label) { /* Issue ioctl */ - return sflc_dm_destroy(label); + return vvz_dm_destroy(label); } diff --git a/vuvuzela-userland/src/operations/dmb.c b/vuvuzela-userland/src/operations/dmb.c index 662742e..b15e583 100644 --- a/vuvuzela-userland/src/operations/dmb.c +++ b/vuvuzela-userland/src/operations/dmb.c @@ -33,7 +33,7 @@ #include "header.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -54,30 +54,30 @@ * * @return Error code, 0 on success */ -int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb) +int vvz_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, vvz_Dmb *dmb) { /* On-disk DMB */ - char enc_dmb[SFLC_BLOCK_SIZE]; + char enc_dmb[VVZ_BLOCK_SIZE]; /* Error code */ int err; /* Sanity check */ - if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); + if (dmb->nr_vols > VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); return EINVAL; } /* Seal DMB */ - err = sflc_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); + err = vvz_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); if (err) { - sflc_log_error("Coul dnot seal DMB; error %d", err); + vvz_log_error("Coul dnot seal DMB; error %d", err); return err; } /* Write it to disk (at sector 0) */ - err = sflc_disk_writeBlock(bdev_path, 0, enc_dmb); + err = vvz_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { - sflc_log_error("Could not write DMB to disk; error %d", err); + vvz_log_error("Could not write DMB to disk; error %d", err); return err; } @@ -93,26 +93,26 @@ int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb * * @param pwd_len Its length * * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vol_idx Its index (>= VVZ_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb) +int vvz_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, vvz_DmbCell *dmb) { - char enc_dmb[SFLC_BLOCK_SIZE]; + char enc_dmb[VVZ_BLOCK_SIZE]; int err; /* Read DMB from disk (at sector 0) */ - err = sflc_disk_readBlock(bdev_path, 0, enc_dmb); + err = vvz_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { - sflc_log_error("Could not read DMB from disk; error %d", err); + vvz_log_error("Could not read DMB from disk; error %d", err); return err; } /* Unseal it */ - err = sflc_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); + err = vvz_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); if (err) { - sflc_log_error("Could not unseal DMB; error %d", err); + vvz_log_error("Could not unseal DMB; error %d", err); return err; } @@ -129,35 +129,35 @@ int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *d * * @return Error code, 0 on success */ -int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) +int vvz_ops_rewriteDmbCell(char *bdev_path, vvz_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) { - char enc_dmb[SFLC_BLOCK_SIZE]; + char enc_dmb[VVZ_BLOCK_SIZE]; int err; /* Sanity check */ - if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + if (dmb_cell->vol_idx >= VVZ_DEV_MAX_VOLUMES) { + vvz_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); return EINVAL; } /* Read DMB from disk (at sector 0) */ - err = sflc_disk_readBlock(bdev_path, 0, enc_dmb); + err = vvz_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { - sflc_log_error("Could not read DMB from disk; error %d", err); + vvz_log_error("Could not read DMB from disk; error %d", err); return err; } /* Update the relevant cell */ - err = sflc_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); + err = vvz_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); if (err) { - sflc_log_error("Could not update DMB cell; error %d", err); + vvz_log_error("Could not update DMB cell; error %d", err); return err; } /* Write it to disk (at sector 0) */ - err = sflc_disk_writeBlock(bdev_path, 0, enc_dmb); + err = vvz_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { - sflc_log_error("Could not write DMB to disk; error %d", err); + vvz_log_error("Could not write DMB to disk; error %d", err); return err; } diff --git a/vuvuzela-userland/src/operations/volume_header.c b/vuvuzela-userland/src/operations/volume_header.c index d35acdd..0ea3ed1 100644 --- a/vuvuzela-userland/src/operations/volume_header.c +++ b/vuvuzela-userland/src/operations/volume_header.c @@ -33,7 +33,7 @@ #include "header.h" #include "header.h" #include "operations.h" -#include "utils/sflc.h" +#include "utils/vvz.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -53,33 +53,33 @@ * * @return Error code, 0 on success */ -int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) +int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size_t vol_idx) { - char enc_vmb[SFLC_BLOCK_SIZE]; - sflc_EncPosMap epm; + char enc_vmb[VVZ_BLOCK_SIZE]; + vvz_EncPosMap epm; uint64_t sector; int err; // Encrypt VMB - err = sflc_vmb_seal(vmb, vmb_key, enc_vmb); + err = vvz_vmb_seal(vmb, vmb_key, enc_vmb); if (err) { - sflc_log_error("Could not seal VMB; error %d", err); + vvz_log_error("Could not seal VMB; error %d", err); goto out; } // Write it to disk - sector = sflc_vmbPosition(vol_idx, vmb->nr_slices); - err = sflc_disk_writeBlock(bdev_path, sector, enc_vmb); + sector = vvz_vmbPosition(vol_idx, vmb->nr_slices); + err = vvz_disk_writeBlock(bdev_path, sector, enc_vmb); if (err) { - sflc_log_error("Could not write VMB to disk; error %d", err); + vvz_log_error("Could not write VMB to disk; error %d", err); goto out; } sector += 1; // Create encrypted empty position map - err = sflc_epm_create(vmb->nr_slices, vmb->volume_key, &epm); + err = vvz_epm_create(vmb->nr_slices, vmb->volume_key, &epm); if (err) { - sflc_log_error("Could not create encrypted empty position map; error %d", err); + vvz_log_error("Could not create encrypted empty position map; error %d", err); goto out; } @@ -88,20 +88,20 @@ int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, si for (i = 0; i < epm.nr_arrays; i++) { char *iv_block = epm.iv_blocks[i]; char *pmb_array = epm.pmb_arrays[i]; - size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); + size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : VVZ_BLOCKS_PER_LOG_SLICE); // First write the IV block - err = sflc_disk_writeBlock(bdev_path, sector, iv_block); + err = vvz_disk_writeBlock(bdev_path, sector, iv_block); if (err) { - sflc_log_error("Could not write IV block to disk; error %d", err); + vvz_log_error("Could not write IV block to disk; error %d", err); goto out; } sector += 1; // Then the whole PMB array - err = sflc_disk_writeManyBlocks(bdev_path, sector, pmb_array, nr_pmbs); + err = vvz_disk_writeManyBlocks(bdev_path, sector, pmb_array, nr_pmbs); if (err) { - sflc_log_error("Could not write PMB array to disk; error %d", err); + vvz_log_error("Could not write PMB array to disk; error %d", err); goto out; } sector += nr_pmbs; @@ -133,30 +133,30 @@ out: * * @return Error code, 0 on success */ -int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) +int vvz_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, vvz_Vmb *vmb) { - char enc_vmb[SFLC_BLOCK_SIZE]; + char enc_vmb[VVZ_BLOCK_SIZE]; uint64_t sector; int err; /* Read encrypted VMB from disk */ - sector = sflc_vmbPosition(vol_idx, nr_slices); - err = sflc_disk_readBlock(bdev_path, sector, enc_vmb); + sector = vvz_vmbPosition(vol_idx, nr_slices); + err = vvz_disk_readBlock(bdev_path, sector, enc_vmb); if (err) { - sflc_log_error("Could not read VMB from disk; error %d", err); + vvz_log_error("Could not read VMB from disk; error %d", err); return err; } /* Unseal it */ - err = sflc_vmb_unseal(enc_vmb, vmb_key, vmb); + err = vvz_vmb_unseal(enc_vmb, vmb_key, vmb); if (err) { - sflc_log_error("Could not unseal VMB; error %d", err); + vvz_log_error("Could not unseal VMB; error %d", err); return err; } /* Compare the number of slices */ if (nr_slices != vmb->nr_slices) { - sflc_log_error("Incompatible header size: the device size was different when the volumes" + vvz_log_error("Incompatible header size: the device size was different when the volumes" "were created. Did you resize the device %s since last time?", bdev_path); return EINVAL; } diff --git a/vuvuzela-userland/src/utils/crypto.c b/vuvuzela-userland/src/utils/crypto.c index dfa6f95..d3b7c46 100644 --- a/vuvuzela-userland/src/utils/crypto.c +++ b/vuvuzela-userland/src/utils/crypto.c @@ -44,7 +44,7 @@ * *@return The error code (0 on success) */ -int sflc_rand_getStrongBytes(char *buf, size_t buflen) +int vvz_rand_getStrongBytes(char *buf, size_t buflen) { gcry_randomize(buf, buflen, GCRY_VERY_STRONG_RANDOM); return 0; @@ -61,7 +61,7 @@ int sflc_rand_getStrongBytes(char *buf, size_t buflen) * *@return The error code (0 on success) */ -int sflc_rand_getWeakBytes(char *buf, size_t buflen) +int vvz_rand_getWeakBytes(char *buf, size_t buflen) { gcry_create_nonce(buf, buflen); return 0; @@ -81,7 +81,7 @@ int sflc_rand_getWeakBytes(char *buf, size_t buflen) * *@return The error code (0 on success) */ -int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -89,26 +89,26 @@ int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); if (err) { - sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + vvz_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); goto bad_open; } - sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); + vvz_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); if (err) { - sflc_log_error("Could not set AES key: error %d", err); + vvz_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflc_log_debug("Successfully set the AES key"); + vvz_log_debug("Successfully set the AES key"); // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); + err = gcry_cipher_setctr(hd, iv, VVZ_AESCTR_IVLEN); if (err) { - sflc_log_error("Could not set AES-CTR IV: error %d", err); + vvz_log_error("Could not set AES-CTR IV: error %d", err); goto bad_setctr; } - sflc_log_debug("Successfully set the IV"); + vvz_log_debug("Successfully set the IV"); // Encrypt if (ct == NULL) { // In-place @@ -119,10 +119,10 @@ int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c } // Error check if (err) { - sflc_log_error("Could not encrypt: error %d", err); + vvz_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - sflc_log_debug("Successfully encrypted"); + vvz_log_debug("Successfully encrypted"); // No prob? err = 0; @@ -149,7 +149,7 @@ bad_open: * *@return The error code (0 on success) */ -int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) +int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -157,26 +157,26 @@ int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *p // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); if (err) { - sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + vvz_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); goto bad_open; } - sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); + vvz_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); if (err) { - sflc_log_error("Could not set AES key: error %d", err); + vvz_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflc_log_debug("Successfully set AES key"); + vvz_log_debug("Successfully set AES key"); // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); + err = gcry_cipher_setctr(hd, iv, VVZ_AESCTR_IVLEN); if (err) { - sflc_log_error("Could not set AES-CTR IV: error %d", err); + vvz_log_error("Could not set AES-CTR IV: error %d", err); goto bad_setctr; } - sflc_log_debug("Successfully set IV"); + vvz_log_debug("Successfully set IV"); // Decrypt if (pt == NULL) { // In-place @@ -187,10 +187,10 @@ int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *p } // Error check if (err) { - sflc_log_error("Could not decrypt: error %d", err); + vvz_log_error("Could not decrypt: error %d", err); goto bad_decrypt; } - sflc_log_debug("Successfully decrypted"); + vvz_log_debug("Successfully decrypted"); // No prob err = 0; @@ -219,7 +219,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -227,26 +227,26 @@ int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_XTS, GCRY_CIPHER_SECURE); if (err) { - sflc_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); + vvz_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); goto bad_open; } - sflc_log_debug("Successfully instantiated AES256-XTS cipher handle"); + vvz_log_debug("Successfully instantiated AES256-XTS cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_AESXTS_KEYLEN); + err = gcry_cipher_setkey(hd, key, VVZ_AESXTS_KEYLEN); if (err) { - sflc_log_error("Could not set AES-XTS key: error %d", err); + vvz_log_error("Could not set AES-XTS key: error %d", err); goto bad_setkey; } - sflc_log_debug("Successfully set the AES-XTS key"); + vvz_log_debug("Successfully set the AES-XTS key"); // Set the IV (not a counter, as per Gcrypt docs) - err = gcry_cipher_setiv(hd, iv, SFLC_AESXTS_IVLEN); + err = gcry_cipher_setiv(hd, iv, VVZ_AESXTS_IVLEN); if (err) { - sflc_log_error("Could not set AES-XTS IV: error %d", err); + vvz_log_error("Could not set AES-XTS IV: error %d", err); goto bad_setiv; } - sflc_log_debug("Successfully set the IV"); + vvz_log_debug("Successfully set the IV"); // Encrypt if (ct == NULL) { // In-place @@ -257,10 +257,10 @@ int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c } // Error check if (err) { - sflc_log_error("Could not encrypt: error %d", err); + vvz_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - sflc_log_debug("Successfully encrypted"); + vvz_log_debug("Successfully encrypted"); // No prob? err = 0; @@ -289,7 +289,7 @@ bad_open: * *@return The error code (0 on success) */ -int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) +int vvz_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -297,42 +297,42 @@ int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *c // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); if (err) { - sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + vvz_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); goto bad_open; } - sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); + vvz_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); if (err) { - sflc_log_error("Could not set AES key: error %d", err); + vvz_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflc_log_debug("Successfully set the AES key"); + vvz_log_debug("Successfully set the AES key"); // Set the IV - err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); + err = gcry_cipher_setiv(hd, iv, VVZ_AESGCM_IVLEN); if (err) { - sflc_log_error("Could not set AES-GCM IV: error %d", err); + vvz_log_error("Could not set AES-GCM IV: error %d", err); goto bad_setiv; } - sflc_log_debug("Successfully set the IV"); + vvz_log_debug("Successfully set the IV"); // Encrypt err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); if (err) { - sflc_log_error("Could not encrypt: error %d", err); + vvz_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - sflc_log_debug("Successfully encrypted"); + vvz_log_debug("Successfully encrypted"); // Get MAC - err = gcry_cipher_gettag(hd, tag, SFLC_AESGCM_TAGLEN); + err = gcry_cipher_gettag(hd, tag, VVZ_AESGCM_TAGLEN); if (err) { - sflc_log_error("Could not get MAC: error %d", err); + vvz_log_error("Could not get MAC: error %d", err); goto bad_gettag; } - sflc_log_debug("Successfully gotten MAC"); + vvz_log_debug("Successfully gotten MAC"); // No prob? err = 0; @@ -364,7 +364,7 @@ bad_open: * *@return The error code (0 on success) */ -int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) +int vvz_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -372,52 +372,52 @@ int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char * // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); if (err) { - sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + vvz_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); goto bad_open; } - sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); + vvz_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); if (err) { - sflc_log_error("Could not set AES key: error %d", err); + vvz_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflc_log_debug("Successfully set AES key"); + vvz_log_debug("Successfully set AES key"); // Set the IV - err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); + err = gcry_cipher_setiv(hd, iv, VVZ_AESGCM_IVLEN); if (err) { - sflc_log_error("Could not set AES-GCM IV: error %d", err); + vvz_log_error("Could not set AES-GCM IV: error %d", err); goto bad_setiv; } - sflc_log_debug("Successfully set IV"); + vvz_log_debug("Successfully set IV"); // Decrypt err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); if (err) { - sflc_log_error("Could not decrypt: error %d", err); + vvz_log_error("Could not decrypt: error %d", err); goto bad_decrypt; } - sflc_log_debug("Successfully decrypted"); + vvz_log_debug("Successfully decrypted"); // Check MAC - err = gcry_cipher_checktag(hd, tag, SFLC_AESGCM_TAGLEN); + err = gcry_cipher_checktag(hd, tag, VVZ_AESGCM_TAGLEN); if (gcry_err_code(err) == GPG_ERR_CHECKSUM) { // Undo decryption - memset(pt, SFLC_AESGCM_POISON_PT, ct_len); + memset(pt, VVZ_AESGCM_POISON_PT, ct_len); // Flag it *match = false; } else if (err) { - sflc_log_error("Could not check MAC: error %d", err); + vvz_log_error("Could not check MAC: error %d", err); goto bad_checktag; } else { // Flag MAC verification success *match = true; } - sflc_log_debug("Successfully checked MAC: match = %d", *match); + vvz_log_debug("Successfully checked MAC: match = %d", *match); // No prob, whether MAC verified or not err = 0; @@ -444,11 +444,11 @@ bad_open: * * @return The error code (0 on success) */ -int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) +int vvz_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) { gcry_kdf_hd_t hd; const unsigned long argon_params[4] = - {SFLC_STANDARD_KEYLEN, SFLC_ARGON_T, SFLC_ARGON_M, SFLC_ARGON_P}; + {VVZ_STANDARD_KEYLEN, VVZ_ARGON_T, VVZ_ARGON_M, VVZ_ARGON_P}; gcry_error_t err; // Instantiate Argon2id handle @@ -456,31 +456,31 @@ int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) &hd, GCRY_KDF_ARGON2, GCRY_KDF_ARGON2ID, argon_params, 4, pwd, pwd_len, - salt, SFLC_ARGON_SALTLEN, + salt, VVZ_ARGON_SALTLEN, NULL, 0, /* Optional secret value K */ NULL, 0 /* Optional associated data X */ ); if (err) { - sflc_log_error("Could not open Argon2id handle: error %d", err); + vvz_log_error("Could not open Argon2id handle: error %d", err); goto bad_open; } - sflc_log_debug("Successfully opened Argon2id handle"); + vvz_log_debug("Successfully opened Argon2id handle"); // Run the computation err = gcry_kdf_compute(hd, NULL); if (err) { - sflc_log_error("Could not run Argon2id computation: error %d", err); + vvz_log_error("Could not run Argon2id computation: error %d", err); goto bad_compute; } - sflc_log_debug("Successfully run Argon2id computation"); + vvz_log_debug("Successfully run Argon2id computation"); // Finalise hash - err = gcry_kdf_final(hd, SFLC_STANDARD_KEYLEN, hash); + err = gcry_kdf_final(hd, VVZ_STANDARD_KEYLEN, hash); if (err) { - sflc_log_error("Could not finalise Argon2id hash: error %d", err); + vvz_log_error("Could not finalise Argon2id hash: error %d", err); goto bad_final; } - sflc_log_debug("Successfully finalised Argon2id hash"); + vvz_log_debug("Successfully finalised Argon2id hash"); // All in order err = 0; diff --git a/vuvuzela-userland/src/utils/disk.c b/vuvuzela-userland/src/utils/disk.c index 40368e6..3b4d392 100644 --- a/vuvuzela-userland/src/utils/disk.c +++ b/vuvuzela-userland/src/utils/disk.c @@ -54,7 +54,7 @@ * * @return true iff it's a block device */ -bool sflc_disk_isBlockDevice(char *path) +bool vvz_disk_isBlockDevice(char *path) { struct stat path_stat; if (stat(path, &path_stat) != 0) { @@ -70,7 +70,7 @@ bool sflc_disk_isBlockDevice(char *path) * * @return The size (in 4096-byte sectors) of the disk, or -errno if error */ -int64_t sflc_disk_getSize(char * bdev_path) +int64_t vvz_disk_getSize(char * bdev_path) { int fd; uint64_t size_bytes; @@ -79,24 +79,24 @@ int64_t sflc_disk_getSize(char * bdev_path) /* Open file */ fd = open(bdev_path, O_RDONLY); if (fd < 0) { - sflc_log_error("Could not open file %s", bdev_path); + vvz_log_error("Could not open file %s", bdev_path); perror("Cause: "); ret = -errno; goto bad_open; } - sflc_log_debug("Opened file %s", bdev_path); + vvz_log_debug("Opened file %s", bdev_path); /* Get size in bytes */ if (ioctl(fd, BLKGETSIZE64, &size_bytes) < 0) { - sflc_log_error("Could not ioctl file %s", bdev_path); + vvz_log_error("Could not ioctl file %s", bdev_path); perror("Cause: "); ret = -errno; goto bad_ioctl; } - sflc_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); + vvz_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); - /* Compute size in SFLC sectors */ - ret = (size_bytes / SFLC_BLOCK_SIZE); + /* Compute size in VVZ sectors */ + ret = (size_bytes / VVZ_BLOCK_SIZE); bad_ioctl: close(fd); @@ -114,7 +114,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflc_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) +int vvz_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) { int fd; int err; @@ -122,29 +122,29 @@ int sflc_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) /* Open file */ fd = open(bdev_path, O_RDONLY); if (fd < 0) { - sflc_log_error("Could not open file %s", bdev_path); + vvz_log_error("Could not open file %s", bdev_path); perror("Cause: "); err = errno; goto bad_open; } - sflc_log_debug("Opened file %s", bdev_path); + vvz_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * SFLC_BLOCK_SIZE, SEEK_SET) < 0) { - sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + if (lseek(fd, sector * VVZ_BLOCK_SIZE, SEEK_SET) < 0) { + vvz_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_lseek; } - sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + vvz_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Read in a loop */ - size_t bytes_to_read = SFLC_BLOCK_SIZE; + size_t bytes_to_read = VVZ_BLOCK_SIZE; while (bytes_to_read > 0) { /* Read syscall */ ssize_t bytes_read = read(fd, buf, bytes_to_read); if (bytes_read < 0) { - sflc_log_error("Could not read file %s at sector %lu", bdev_path, sector); + vvz_log_error("Could not read file %s at sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_read; @@ -152,7 +152,7 @@ int sflc_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) /* Partial read? No problem just log */ if (bytes_read < bytes_to_read) { - sflc_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", + vvz_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", bdev_path, sector, bytes_read, bytes_to_read); } @@ -183,7 +183,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflc_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) +int vvz_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) { int fd; int err; @@ -191,29 +191,29 @@ int sflc_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, siz /* Open file */ fd = open(bdev_path, O_WRONLY); if (fd < 0) { - sflc_log_error("Could not open file %s", bdev_path); + vvz_log_error("Could not open file %s", bdev_path); perror("Cause: "); err = errno; goto bad_open; } - sflc_log_debug("Opened file %s", bdev_path); + vvz_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * SFLC_BLOCK_SIZE, SEEK_SET) < 0) { - sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + if (lseek(fd, sector * VVZ_BLOCK_SIZE, SEEK_SET) < 0) { + vvz_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_lseek; } - sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + vvz_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Write in a loop */ - size_t bytes_to_write = SFLC_BLOCK_SIZE * num_sectors; + size_t bytes_to_write = VVZ_BLOCK_SIZE * num_sectors; while (bytes_to_write > 0) { /* Write syscall */ ssize_t bytes_written = write(fd, buf, bytes_to_write); if (bytes_written < 0) { - sflc_log_red("Could not write file %s at sector %lu", bdev_path, sector); + vvz_log_red("Could not write file %s at sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_write; @@ -221,7 +221,7 @@ int sflc_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, siz /* Partial write? No problem just log */ if (bytes_written < bytes_to_write) { - sflc_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", + vvz_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", bdev_path, sector, bytes_written, bytes_to_write); } diff --git a/vuvuzela-userland/src/utils/dm.c b/vuvuzela-userland/src/utils/dm.c index 6c2d054..31e3f14 100644 --- a/vuvuzela-userland/src/utils/dm.c +++ b/vuvuzela-userland/src/utils/dm.c @@ -53,7 +53,7 @@ * * @return The error code (0 on success) */ -int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) +int vvz_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) { struct dm_task *dmt; uint32_t cookie = 0; @@ -64,60 +64,60 @@ int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) char * dup_virt_dev_name = strdup(virt_dev_name); char * dup_params = strdup(params); - sflc_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); + vvz_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); /* Instantiate the DM task (with the CREATE ioctl command) */ if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) { - sflc_log_error("Cannot create dm_task"); + vvz_log_error("Cannot create dm_task"); err = 1; goto dup_free; } - sflc_log_debug("Successfully created dm_task"); + vvz_log_debug("Successfully created dm_task"); /* Set the name of the target device (to be created) */ if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - sflc_log_error("Cannot set device name"); + vvz_log_error("Cannot set device name"); err = 2; goto out; } - sflc_log_debug("Successfully set device name"); + vvz_log_debug("Successfully set device name"); /* State that it is a Shufflecake device, pass the start and size, and the * constructor parameters */ - if (!dm_task_add_target(dmt, 0, num_sectors, SFLC_DM_TARGET_NAME, dup_params)) { - sflc_log_error("Cannot add DM target and parameters"); + if (!dm_task_add_target(dmt, 0, num_sectors, VVZ_DM_TARGET_NAME, dup_params)) { + vvz_log_error("Cannot add DM target and parameters"); err = 3; goto out; } - sflc_log_debug("Successfully added DM target and parameters"); + vvz_log_debug("Successfully added DM target and parameters"); /* Say that we want a new node under /dev/mapper */ if (!dm_task_set_add_node(dmt, DM_ADD_NODE_ON_CREATE)) { - sflc_log_error("Cannot add /dev/mapper node"); + vvz_log_error("Cannot add /dev/mapper node"); err = 4; goto out; } - sflc_log_debug("Successfully set the ADD_NODE flag"); + vvz_log_debug("Successfully set the ADD_NODE flag"); /* Get a cookie (request ID, basically) to wait for task completion */ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - sflc_log_error("Cannot get cookie"); + vvz_log_error("Cannot get cookie"); err = 5; goto out; } - sflc_log_debug("Successfully got a cookie"); + vvz_log_debug("Successfully got a cookie"); /* Run the task */ if (!dm_task_run(dmt)) { - sflc_log_error("Cannot issue ioctl"); + vvz_log_error("Cannot issue ioctl"); err = 6; goto out; } - sflc_log_debug("Successfully run DM task"); + vvz_log_debug("Successfully run DM task"); /* Wait for completion */ dm_udev_wait(cookie); - sflc_log_debug("Task completed"); + vvz_log_debug("Task completed"); // No prob err = 0; @@ -139,7 +139,7 @@ dup_free: * * @return error code (0 on success) */ -int sflc_dm_destroy(char * virt_dev_name) +int vvz_dm_destroy(char * virt_dev_name) { struct dm_task *dmt; uint32_t cookie = 0; @@ -149,47 +149,47 @@ int sflc_dm_destroy(char * virt_dev_name) /* Just to be sure, let's get it on the heap */ char * dup_virt_dev_name = strdup(virt_dev_name); - sflc_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); + vvz_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); /* Instantiate the DM task (with the REMOVE ioctl command) */ if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) { - sflc_log_error("Cannot create dm_task"); + vvz_log_error("Cannot create dm_task"); err = 1; goto dup_free; } - sflc_log_debug("Successfully created dm_task"); + vvz_log_debug("Successfully created dm_task"); /* Set the name of the target device (to be closed) */ if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - sflc_log_error("Cannot set device name"); + vvz_log_error("Cannot set device name"); err = 2; goto out; } - sflc_log_debug("Successfully set device name"); + vvz_log_debug("Successfully set device name"); /* Get a cookie (request ID, basically) to wait for task completion */ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - sflc_log_error("Cannot set cookie"); + vvz_log_error("Cannot set cookie"); err = 3; goto out; } - sflc_log_debug("Successfully got a cookie"); + vvz_log_debug("Successfully got a cookie"); /* Needed for some reason */ dm_task_retry_remove(dmt); - sflc_log_debug("Successful retry_remove"); + vvz_log_debug("Successful retry_remove"); /* Run the task */ if (!dm_task_run(dmt)) { - sflc_log_error("Cannot issue ioctl"); + vvz_log_error("Cannot issue ioctl"); err = 4; goto out; } - sflc_log_debug("Successfully run task"); + vvz_log_debug("Successfully run task"); /* Wait for completion */ dm_udev_wait(cookie); - sflc_log_debug("Task completed"); + vvz_log_debug("Task completed"); // No prob err = 0; diff --git a/vuvuzela-userland/src/utils/file.c b/vuvuzela-userland/src/utils/file.c index a8e70e2..84b13ff 100644 --- a/vuvuzela-userland/src/utils/file.c +++ b/vuvuzela-userland/src/utils/file.c @@ -38,7 +38,7 @@ *****************************************************/ /* Reads the entire content of a file in a malloc-ed string */ -char *sflc_readFile(char *path) +char *vvz_readFile(char *path) { int filesize; FILE *fp; @@ -47,7 +47,7 @@ char *sflc_readFile(char *path) /* Open file */ fp = fopen(path, "r"); if (fp == NULL) { - sflc_log_error("Could not open file %s", path); + vvz_log_error("Could not open file %s", path); perror("Reason: "); goto bad_fopen; } @@ -60,7 +60,7 @@ char *sflc_readFile(char *path) /* Allocate */ content = malloc(filesize + 1); if (content == NULL) { - sflc_log_error("Could not malloc %d bytes for file content", filesize); + vvz_log_error("Could not malloc %d bytes for file content", filesize); goto bad_malloc; } diff --git a/vuvuzela-userland/src/utils/input.c b/vuvuzela-userland/src/utils/input.c index ffc0b02..8a7b776 100644 --- a/vuvuzela-userland/src/utils/input.c +++ b/vuvuzela-userland/src/utils/input.c @@ -41,13 +41,13 @@ *****************************************************/ /* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int sflc_safeReadLine(char *buf, size_t bufsize) +int vvz_safeReadLine(char *buf, size_t bufsize) { size_t len; /* Read from stdin */ if (fgets(buf, bufsize, stdin) == NULL) { - sflc_log_error("Could not read from stdin"); + vvz_log_error("Could not read from stdin"); return EBADFD; } @@ -62,7 +62,7 @@ int sflc_safeReadLine(char *buf, size_t bufsize) /* Reads a password/passphrase in a secure way (no echo) */ -int sflc_safeReadPassphrase(char *buf, size_t bufsize) +int vvz_safeReadPassphrase(char *buf, size_t bufsize) { size_t len; struct termios old, new; @@ -79,7 +79,7 @@ int sflc_safeReadPassphrase(char *buf, size_t bufsize) if (fgets(buf, bufsize, stdin) == NULL) { // If reading the password failed, ensure echoing is turned back on tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); - sflc_log_error("Could not read from stdin"); + vvz_log_error("Could not read from stdin"); return EBADFD; } diff --git a/vuvuzela-userland/src/utils/string.c b/vuvuzela-userland/src/utils/string.c index c6cf998..555a127 100644 --- a/vuvuzela-userland/src/utils/string.c +++ b/vuvuzela-userland/src/utils/string.c @@ -38,7 +38,7 @@ *****************************************************/ /* Malloc's the buffer for the hex string */ -char *sflc_toHex(char *buf, size_t len) +char *vvz_toHex(char *buf, size_t len) { unsigned char *u = (unsigned char *) buf; char *hex; @@ -46,7 +46,7 @@ char *sflc_toHex(char *buf, size_t len) /* Allocate buffer */ hex = malloc((len * 2) + 1); if (!hex) { - sflc_log_error("Could not allocate buffer for hex string"); + vvz_log_error("Could not allocate buffer for hex string"); return NULL; } @@ -61,7 +61,7 @@ char *sflc_toHex(char *buf, size_t len) } -void sflc_str_replaceAll(char * str, char old, char new) +void vvz_str_replaceAll(char * str, char old, char new) { int i; for (i = 0; str[i] != '\0'; i++) { diff --git a/vuvuzela-userland/test/crypto/test_aes256ctr.c b/vuvuzela-userland/test/crypto/test_aes256ctr.c index 700a910..356cd15 100644 --- a/vuvuzela-userland/test/crypto/test_aes256ctr.c +++ b/vuvuzela-userland/test/crypto/test_aes256ctr.c @@ -56,10 +56,10 @@ char *test_aes256ctr_encrypt_inplace() char iv[] = AES256CTR_TEST_IV; int err; - sflc_log_blue("Testing AES256-CTR encryption in-place"); + vvz_log_blue("Testing AES256-CTR encryption in-place"); // Encrypt in-place - err = sflc_aes256ctr_encrypt(key, msg, msg_len, iv, NULL); + err = vvz_aes256ctr_encrypt(key, msg, msg_len, iv, NULL); // Check error mu_assert("Error while encrypting", !err); @@ -73,7 +73,7 @@ char *test_aes256ctr_encrypt_inplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } @@ -87,10 +87,10 @@ char *test_aes256ctr_encrypt_outofplace() char iv[] = AES256CTR_TEST_IV; int err; - sflc_log_blue("Testing AES256-CTR encryption out-of-place"); + vvz_log_blue("Testing AES256-CTR encryption out-of-place"); // Encrypt out-of-place - err = sflc_aes256ctr_encrypt(key, msg, msg_len, iv, ct); + err = vvz_aes256ctr_encrypt(key, msg, msg_len, iv, ct); // Check error mu_assert("Error while encrypting", !err); @@ -107,7 +107,7 @@ char *test_aes256ctr_encrypt_outofplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } @@ -120,10 +120,10 @@ char *test_aes256ctr_decrypt_inplace() char iv[] = AES256CTR_TEST_IV; int err; - sflc_log_blue("Testing AES256-CTR decryption in-place"); + vvz_log_blue("Testing AES256-CTR decryption in-place"); // Decrypt in-place - err = sflc_aes256ctr_decrypt(key, msg, msg_len, iv, NULL); + err = vvz_aes256ctr_decrypt(key, msg, msg_len, iv, NULL); // Check error mu_assert("Error while decrypting", !err); @@ -137,7 +137,7 @@ char *test_aes256ctr_decrypt_inplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } @@ -151,10 +151,10 @@ char *test_aes256ctr_decrypt_outofplace() char iv[] = AES256CTR_TEST_IV; int err; - sflc_log_blue("Testing AES256-CTR decryption out-of-place"); + vvz_log_blue("Testing AES256-CTR decryption out-of-place"); // Decrypt out-of-place - err = sflc_aes256ctr_decrypt(key, msg, msg_len, iv, pt); + err = vvz_aes256ctr_decrypt(key, msg, msg_len, iv, pt); // Check error mu_assert("Error while decrypting", !err); @@ -171,7 +171,7 @@ char *test_aes256ctr_decrypt_outofplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } diff --git a/vuvuzela-userland/test/crypto/test_aes256gcm.c b/vuvuzela-userland/test/crypto/test_aes256gcm.c index b332c51..dfc8dfd 100644 --- a/vuvuzela-userland/test/crypto/test_aes256gcm.c +++ b/vuvuzela-userland/test/crypto/test_aes256gcm.c @@ -56,20 +56,20 @@ char *test_aes256gcm_encrypt() char key[] = AES256GCM_TEST_KEY; char iv[] = AES256GCM_TEST_IV; char ct[sizeof(pt)]; - char tag[SFLC_AESGCM_TAGLEN]; + char tag[VVZ_AESGCM_TAGLEN]; int err; - sflc_log_blue("Testing AES256-GCM encryption"); + vvz_log_blue("Testing AES256-GCM encryption"); // Encrypt - err = sflc_aes256gcm_encrypt(key, pt, pt_len, iv, ct, tag); + err = vvz_aes256gcm_encrypt(key, pt, pt_len, iv, ct, tag); // Check error mu_assert("Error while encrypting", !err); // Check outcome mu_assert("Ciphertext mismatch", memcmp(ct, CT, pt_len) == 0); - mu_assert("MAC mismatch", memcmp(tag, TAG, SFLC_AESGCM_TAGLEN) == 0); + mu_assert("MAC mismatch", memcmp(tag, TAG, VVZ_AESGCM_TAGLEN) == 0); // Check key untouched mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); @@ -77,7 +77,7 @@ char *test_aes256gcm_encrypt() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } @@ -93,10 +93,10 @@ char *test_aes256gcm_decrypt_good() char pt[sizeof(ct)]; int err; - sflc_log_blue("Testing AES256-GCM decryption with the proper MAC"); + vvz_log_blue("Testing AES256-GCM decryption with the proper MAC"); // Decrypt - err = sflc_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); + err = vvz_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); // Check error mu_assert("Error while decrypting", !err); @@ -114,7 +114,7 @@ char *test_aes256gcm_decrypt_good() // Check MAC untouched mu_assert("MAC changed", memcmp(tag, TAG, sizeof(tag)) == 0); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } @@ -130,13 +130,13 @@ char *test_aes256gcm_decrypt_fail() char pt[sizeof(ct)]; int err; - sflc_log_blue("Testing AES256-GCM decryption without the proper MAC"); + vvz_log_blue("Testing AES256-GCM decryption without the proper MAC"); // Corrupt the MAC tag[0] += 1; // Decrypt - err = sflc_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); + err = vvz_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); // Check error mu_assert("Error while decrypting", !err); @@ -154,7 +154,7 @@ char *test_aes256gcm_decrypt_fail() mu_assert("Tail of MAC changed", memcmp(tag+1, TAG+1, sizeof(tag)-1) == 0); mu_assert("Head of MAC changed", tag[0] == TAG[0]+1); - sflc_log_green("OK"); + vvz_log_green("OK"); return NULL; } diff --git a/vuvuzela-userland/test/crypto/test_argon2id.c b/vuvuzela-userland/test/crypto/test_argon2id.c index 7e1180d..7a26ab9 100644 --- a/vuvuzela-userland/test/crypto/test_argon2id.c +++ b/vuvuzela-userland/test/crypto/test_argon2id.c @@ -39,7 +39,7 @@ * CONSTANT VARIABLES * *****************************************************/ -char SALT[SFLC_ARGON_SALTLEN+1] = "Poor Petrol Pump"; +char SALT[VVZ_ARGON_SALTLEN+1] = "Poor Petrol Pump"; /***************************************************** @@ -48,17 +48,17 @@ char SALT[SFLC_ARGON_SALTLEN+1] = "Poor Petrol Pump"; char *test_argon2id() { - char pwd[SFLC_BIGBUFSIZE]; - char key[SFLC_STANDARD_KEYLEN]; + char pwd[VVZ_BIGBUFSIZE]; + char key[VVZ_STANDARD_KEYLEN]; int err; - sflc_log_blue("Testing Argon2id interactively with a fixed salt"); + vvz_log_blue("Testing Argon2id interactively with a fixed salt"); // Loop until user breaks out while (true) { /* Collect password */ printf("Choose password to hash (empty to skip): "); - err = sflc_safeReadLine(pwd, SFLC_BIGBUFSIZE); + err = vvz_safeReadLine(pwd, VVZ_BIGBUFSIZE); mu_assert("Could not read password", !err); /* Check if empty */ @@ -67,15 +67,15 @@ char *test_argon2id() } /* Hash it */ - err = sflc_argon2id_derive(pwd, strlen(pwd), SALT, key); + err = vvz_argon2id_derive(pwd, strlen(pwd), SALT, key); mu_assert("Could not hash password", !err); /* Print it */ printf("Salt used ASCII: \"%s\". Hex:\n", SALT); - sflc_log_hex(SALT, SFLC_ARGON_SALTLEN); + vvz_log_hex(SALT, VVZ_ARGON_SALTLEN); printf("Argon2id hash (m = %d, t = %d, p = %d):\n", - SFLC_ARGON_M, SFLC_ARGON_T, SFLC_ARGON_P); - sflc_log_hex(key, SFLC_STANDARD_KEYLEN); + VVZ_ARGON_M, VVZ_ARGON_T, VVZ_ARGON_P); + vvz_log_hex(key, VVZ_STANDARD_KEYLEN); printf("Go check the result online\n\n"); } diff --git a/vuvuzela-userland/test/main.c b/vuvuzela-userland/test/main.c index 565aa2c..ee4e805 100644 --- a/vuvuzela-userland/test/main.c +++ b/vuvuzela-userland/test/main.c @@ -49,10 +49,10 @@ int main() char *result = all_tests(); if (result != NULL) { - sflc_log_red("\nTEST FAILED: %s", result); + vvz_log_red("\nTEST FAILED: %s", result); } else { - sflc_log_green("\nALL TESTS PASSED"); + vvz_log_green("\nALL TESTS PASSED"); } return result != NULL; @@ -65,7 +65,7 @@ int main() static char *all_tests() { - sflc_log_yellow("Running crypto tests"); + vvz_log_yellow("Running crypto tests"); mu_run_test(test_aes256ctr_encrypt_inplace); mu_run_test(test_aes256ctr_encrypt_outofplace); mu_run_test(test_aes256ctr_decrypt_inplace); From f67fa1197cb36d360aa3f2ed9782a2801f41d4e0 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 17 Apr 2024 21:24:55 +0200 Subject: [PATCH 46/75] Finish init --- vuvuzela-userland/Makefile | 4 +- vuvuzela-userland/include/header.h | 3 +- vuvuzela-userland/src/commands/init.c | 2 +- vuvuzela-userland/src/header/position_map.c | 4 +- .../src/header/volume_master_block.c | 8 +-- vuvuzela-userland/src/operations/devmapper.c | 2 +- .../src/operations/volume_header.c | 51 +++++-------------- 7 files changed, 26 insertions(+), 48 deletions(-) diff --git a/vuvuzela-userland/Makefile b/vuvuzela-userland/Makefile index ee59323..19abeb7 100644 --- a/vuvuzela-userland/Makefile +++ b/vuvuzela-userland/Makefile @@ -61,10 +61,10 @@ DEPS := $(PROJ_DEPS) $(TEST_DEPS) DIRS := $(sort $(dir $(BIN_DIR) $(PROJ_OBJS) $(TEST_OBJS) $(PROJ_DEPS) $(TEST_DEPS))) # The target binaries -MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake +MAIN_BIN := $(PROJ_OUT_DIR)/vuvuzela TEST_BIN := $(TEST_OUT_DIR)/tests # Their symlink -MAIN_LINK := shufflecake +MAIN_LINK := vuvuzela TEST_LINK := tests diff --git a/vuvuzela-userland/include/header.h b/vuvuzela-userland/include/header.h index 6d5181c..2423b40 100644 --- a/vuvuzela-userland/include/header.h +++ b/vuvuzela-userland/include/header.h @@ -33,6 +33,7 @@ #include #include "utils/crypto.h" +#include "utils/math.h" /***************************************************** @@ -95,7 +96,7 @@ typedef struct { */ typedef struct { // The key that encrypts the volume's data section - char volume_key[VVZ_STANDARD_KEYLEN]; + char volume_key[VVZ_AESXTS_KEYLEN]; // The key that encrypts the previous volume's master block char prev_vmb_key[VVZ_STANDARD_KEYLEN]; diff --git a/vuvuzela-userland/src/commands/init.c b/vuvuzela-userland/src/commands/init.c index 69eda0d..592eb3c 100644 --- a/vuvuzela-userland/src/commands/init.c +++ b/vuvuzela-userland/src/commands/init.c @@ -132,7 +132,7 @@ int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args) memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], VVZ_STANDARD_KEYLEN); } /* Sample this volume's VEK */ - vvz_rand_getStrongBytes(vmb.volume_key, VVZ_STANDARD_KEYLEN); + vvz_rand_getStrongBytes(vmb.volume_key, VVZ_AESXTS_KEYLEN); /* Write complete volume header (VMB + PM) */ err = vvz_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); diff --git a/vuvuzela-userland/src/header/position_map.c b/vuvuzela-userland/src/header/position_map.c index e48f304..7d72f1d 100644 --- a/vuvuzela-userland/src/header/position_map.c +++ b/vuvuzela-userland/src/header/position_map.c @@ -63,7 +63,7 @@ void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) // Allocate EPM epm = malloc(nr_pmbs * VVZ_BLOCK_SIZE); if (!epm) { - vvz_log_error("Could not malloc EPM array"); + vvz_log_error("Could not malloc EPM"); return NULL; } @@ -71,7 +71,7 @@ void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) memset(pmb, VVZ_EPM_FILLER, VVZ_BLOCK_SIZE); // Set the IV for the first encryption memset(iv, 0, VVZ_AESXTS_IVLEN); - *((uint64_t)iv) = htole64(vvz_pmStartBlock(vol_idx, nr_slices)); + *((uint64_t*)iv) = htole64(vvz_pmStartBlock(vol_idx, nr_slices)); // Loop to encrypt each PMB int i; diff --git a/vuvuzela-userland/src/header/volume_master_block.c b/vuvuzela-userland/src/header/volume_master_block.c index 5f153c9..72c36b5 100644 --- a/vuvuzela-userland/src/header/volume_master_block.c +++ b/vuvuzela-userland/src/header/volume_master_block.c @@ -181,11 +181,11 @@ static void _serialiseVmb(vvz_Vmb *vmb, char *clear_vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + VVZ_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + VVZ_AESXTS_KEYLEN; char *p_nr_slices = p_prev_vmb_key + VVZ_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(p_vol_key, vmb->volume_key, VVZ_STANDARD_KEYLEN); + memcpy(p_vol_key, vmb->volume_key, VVZ_AESXTS_KEYLEN); /* Copy the previous volume's VMB key */ memcpy(p_prev_vmb_key, vmb->prev_vmb_key, VVZ_STANDARD_KEYLEN); @@ -204,11 +204,11 @@ static int _deserialiseVmb(char *clear_vmb, vvz_Vmb *vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + VVZ_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + VVZ_AESXTS_KEYLEN; char *p_nr_slices = p_prev_vmb_key + VVZ_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(vmb->volume_key, p_vol_key, VVZ_STANDARD_KEYLEN); + memcpy(vmb->volume_key, p_vol_key, VVZ_AESXTS_KEYLEN); /* Copy the previous volume's VMB key */ memcpy(vmb->prev_vmb_key, p_prev_vmb_key, VVZ_STANDARD_KEYLEN); diff --git a/vuvuzela-userland/src/operations/devmapper.c b/vuvuzela-userland/src/operations/devmapper.c index 2f622b5..4df1c62 100644 --- a/vuvuzela-userland/src/operations/devmapper.c +++ b/vuvuzela-userland/src/operations/devmapper.c @@ -76,7 +76,7 @@ int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb * } /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vmb->nr_slices) * VVZ_BLOCKS_PER_LOG_SLICE * VVZ_BLOCK_SCALE; + num_sectors = ((uint64_t) vmb->nr_slices) * VVZ_SLICE_SCALE * VVZ_BLOCK_SCALE; /* Build param list */ sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); diff --git a/vuvuzela-userland/src/operations/volume_header.c b/vuvuzela-userland/src/operations/volume_header.c index 0ea3ed1..84922f2 100644 --- a/vuvuzela-userland/src/operations/volume_header.c +++ b/vuvuzela-userland/src/operations/volume_header.c @@ -56,7 +56,7 @@ int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size_t vol_idx) { char enc_vmb[VVZ_BLOCK_SIZE]; - vvz_EncPosMap epm; + void *epm; uint64_t sector; int err; @@ -68,52 +68,29 @@ int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size } // Write it to disk - sector = vvz_vmbPosition(vol_idx, vmb->nr_slices); + sector = 1 + vol_idx; err = vvz_disk_writeBlock(bdev_path, sector, enc_vmb); if (err) { vvz_log_error("Could not write VMB to disk; error %d", err); goto out; } - sector += 1; // Create encrypted empty position map - err = vvz_epm_create(vmb->nr_slices, vmb->volume_key, &epm); - if (err) { - vvz_log_error("Could not create encrypted empty position map; error %d", err); + epm = vvz_epm_create(vmb->nr_slices, vol_idx, vmb->volume_key); + if (!epm) { + vvz_log_error("Could not create encrypted empty position map."); + err = -ENOMEM; goto out; } - // Loop over PMB arrays to write them to disk - int i; - for (i = 0; i < epm.nr_arrays; i++) { - char *iv_block = epm.iv_blocks[i]; - char *pmb_array = epm.pmb_arrays[i]; - size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : VVZ_BLOCKS_PER_LOG_SLICE); - - // First write the IV block - err = vvz_disk_writeBlock(bdev_path, sector, iv_block); - if (err) { - vvz_log_error("Could not write IV block to disk; error %d", err); - goto out; - } - sector += 1; - - // Then the whole PMB array - err = vvz_disk_writeManyBlocks(bdev_path, sector, pmb_array, nr_pmbs); - if (err) { - vvz_log_error("Could not write PMB array to disk; error %d", err); - goto out; - } - sector += nr_pmbs; - - // Free them both - free(iv_block); - free(pmb_array); + // Write to disk + sector = vvz_pmStartBlock(vol_idx, sector); + err = vvz_disk_writeManyBlocks(bdev_path, sector, epm, + ceil(vmb->nr_slices, VVZ_SLICE_IDX_PER_BLOCK)); + if (err) { + vvz_log_error("Could not write encrypted PosMap; error %d", err); } - - // Free containers - free(epm.iv_blocks); - free(epm.pmb_arrays); + free(epm); out: @@ -140,7 +117,7 @@ int vvz_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol int err; /* Read encrypted VMB from disk */ - sector = vvz_vmbPosition(vol_idx, nr_slices); + sector = 1 + vol_idx; err = vvz_disk_readBlock(bdev_path, sector, enc_vmb); if (err) { vvz_log_error("Could not read VMB from disk; error %d", err); From 2bbe3672900541d08a11d24f0d993b70c1889619 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 17 Apr 2024 22:35:03 +0200 Subject: [PATCH 47/75] Finish open --- vuvuzela-userland/include/utils/disk.h | 3 +++ vuvuzela-userland/src/operations/devmapper.c | 5 ++-- .../src/operations/volume_header.c | 2 +- vuvuzela-userland/src/utils/disk.c | 26 +++++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/vuvuzela-userland/include/utils/disk.h b/vuvuzela-userland/include/utils/disk.h index b36b6a2..a007f39 100644 --- a/vuvuzela-userland/include/utils/disk.h +++ b/vuvuzela-userland/include/utils/disk.h @@ -72,6 +72,9 @@ static inline uint32_t vvz_disk_maxSlices(uint64_t size) { * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ +/* Returns a malloc'ed string formatted as : */ +char *vvz_disk_getDeviceName(char *bdev_path); + /* Checks whether the given path points to a block device */ bool vvz_disk_isBlockDevice(char *path); diff --git a/vuvuzela-userland/src/operations/devmapper.c b/vuvuzela-userland/src/operations/devmapper.c index 4df1c62..4e54af2 100644 --- a/vuvuzela-userland/src/operations/devmapper.c +++ b/vuvuzela-userland/src/operations/devmapper.c @@ -68,7 +68,7 @@ int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb * sprintf(label, "vvz_%lu_%lu", dev_id, vol_idx); /* Get the hex version of the volume's data section key */ - hex_key = vvz_toHex(vmb->volume_key, VVZ_STANDARD_KEYLEN); + hex_key = vvz_toHex(vmb->volume_key, VVZ_AESXTS_KEYLEN); if (!hex_key) { vvz_log_error("Could not encode volume key to hexadecimal"); err = ENOMEM; @@ -79,7 +79,7 @@ int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb * num_sectors = ((uint64_t) vmb->nr_slices) * VVZ_SLICE_SCALE * VVZ_BLOCK_SCALE; /* Build param list */ - sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); + sprintf(params, "%lu %s %lu %lu %s", dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); /* Issue ioctl */ err = vvz_dm_create(label, num_sectors, params); @@ -91,6 +91,7 @@ int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb * err_dmcreate: + memset(hex_key, 0, strlen(hex_key)); free(hex_key); err_hexkey: return err; diff --git a/vuvuzela-userland/src/operations/volume_header.c b/vuvuzela-userland/src/operations/volume_header.c index 84922f2..a0c0176 100644 --- a/vuvuzela-userland/src/operations/volume_header.c +++ b/vuvuzela-userland/src/operations/volume_header.c @@ -79,7 +79,7 @@ int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size epm = vvz_epm_create(vmb->nr_slices, vol_idx, vmb->volume_key); if (!epm) { vvz_log_error("Could not create encrypted empty position map."); - err = -ENOMEM; + err = ENOMEM; goto out; } diff --git a/vuvuzela-userland/src/utils/disk.c b/vuvuzela-userland/src/utils/disk.c index 3b4d392..795d0d9 100644 --- a/vuvuzela-userland/src/utils/disk.c +++ b/vuvuzela-userland/src/utils/disk.c @@ -30,11 +30,13 @@ *****************************************************/ #include +#include #include #include #include #include #include +#include #include #include @@ -47,6 +49,30 @@ *****************************************************/ +/** + * Returns a malloc'ed string formatted as : + * + * @param bdev_path The path to the block device + * + * @return A string version of the device ID + */ +char *vvz_disk_getDeviceName(char *bdev_path) +{ + struct stat sb; + char *dev_name; + + if (stat(bdev_path, &sb) != 0) + return NULL; + dev_name = malloc(VVZ_BIGBUFSIZE); + if (!dev_name) + return NULL; + + sprintf(dev_name, "%u:%u", major(sb.st_dev), minor(sb.st_dev)); + + return dev_name; +} + + /** * Checks whether the given path points to a block device. * From 4b1dc837af689366d76a5bccd21edb0752168c4f Mon Sep 17 00:00:00 2001 From: = Date: Wed, 17 Apr 2024 23:22:36 +0200 Subject: [PATCH 48/75] Add sysfs entry for number of volumes --- dm-vvz/device.c | 1 + dm-vvz/sysfs.c | 9 +++++++++ dm-vvz/vvz.c | 5 +++++ dm-vvz/vvz.h | 3 +++ 4 files changed, 18 insertions(+) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index cff41dc..1eb195f 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -57,6 +57,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) return ERR_PTR(-ENOMEM); } sdev->dev_id = dev_id; + sdev->nr_volumes = 0; /* The calling ->ctr() will set sdev->dm_dev */ diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index d234331..c0efb8b 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -91,6 +91,13 @@ static ssize_t dev_id_show(struct kobject *kobj, struct kobj_attribute *kattr, c return sysfs_emit(buf, "%u\n", sdev->dev_id); } +static ssize_t volumes_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); + + return sysfs_emit(buf, "%lu\n", sdev->nr_volumes); +} + static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) { struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); @@ -112,10 +119,12 @@ static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kat } static struct kobj_attribute dev_id_kattr = __ATTR_RO(dev_id); +static struct kobj_attribute volumes_kattr = __ATTR_RO(volumes); static struct kobj_attribute tot_slices_kattr = __ATTR_RO(tot_slices); static struct kobj_attribute free_slices_kattr = __ATTR_RO(free_slices); static struct attribute *vvz_device_default_attrs[] = { &dev_id_kattr.attr, + &volumes_kattr.attr, &tot_slices_kattr.attr, &free_slices_kattr.attr, NULL diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 4367d95..aef3c45 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -168,6 +168,8 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) err = PTR_ERR(svol); goto bad_vol_create; } + /* We expect ->ctr() calls to be strictly sequential */ + sdev->nr_volumes++; /* Only accept one block per request for simplicity TODO: improve to one slice*/ ti->max_io_len = VVZ_BLOCK_SCALE; @@ -204,6 +206,9 @@ static void vvz_dtr(struct dm_target *ti) size_t vol_idx = svol->vol_idx; vvz_vol_destroy(svol); + /* We expect ->dtr() calls to be strictly sequential */ + sdev->nr_volumes--; + if (vol_idx == 0) { vvz_remove_device_global(sdev->dev_id); dm_put_device(ti, sdev->dm_dev); diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index a954761..f73ef8d 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -59,6 +59,9 @@ struct vvz_device sector_t posmap_size_sectors; sector_t dev_header_size_sectors; + /* Number of volumes */ + size_t nr_volumes; + /* Shuffled array of PSIs */ struct mutex slices_lock; u32 *prmslices; From 4e2344674b8bffeb86b939187c4aa1e59a34723b Mon Sep 17 00:00:00 2001 From: = Date: Wed, 17 Apr 2024 23:22:49 +0200 Subject: [PATCH 49/75] Finish close --- vuvuzela-userland/include/utils/vvz.h | 4 +- vuvuzela-userland/src/commands/close.c | 72 +++++++++++++++----------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/vuvuzela-userland/include/utils/vvz.h b/vuvuzela-userland/include/utils/vvz.h index 3263dca..71bc399 100644 --- a/vuvuzela-userland/include/utils/vvz.h +++ b/vuvuzela-userland/include/utils/vvz.h @@ -69,8 +69,10 @@ #define VVZ_SYSFS_NEXTDEVID "/sys/module/dm_vvz/next_dev_id" /* The sysfs directory containing a subdir for each (underlying) block device */ #define VVZ_SYSFS_BDEVS_DIR "/sys/module/dm_vvz/bdevs" -/* Within each bdev's subdir, this file lists its open volumes */ +/* Within each bdev's subdir, this file shows its number of open volumes */ #define VVZ_SYSFS_OPENVOLUMES_FILENAME "volumes" +/* Within each bdev's subdir, this file shows its Shufflecake device ID */ +#define VVZ_SYSFS_DEVID_FILENAME "dev_id" /* TODO: reasonable? */ #define VVZ_BDEV_PATH_MAX_LEN 1024 diff --git a/vuvuzela-userland/src/commands/close.c b/vuvuzela-userland/src/commands/close.c index e3784bc..e14ee21 100644 --- a/vuvuzela-userland/src/commands/close.c +++ b/vuvuzela-userland/src/commands/close.c @@ -35,6 +35,7 @@ #include "utils/crypto.h" #include "utils/string.h" #include "utils/file.h" +#include "utils/disk.h" #include "utils/log.h" @@ -43,7 +44,7 @@ *****************************************************/ /* Reads the list of volumes from sysfs */ -static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols); +static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols); /* Close them all (in reverse order of opening) */ static int _closeVolumes(char **labels, size_t nr_vols); @@ -77,7 +78,7 @@ int vvz_cmd_closeVolumes(char *bdev_path) } /* Read them */ - err = _readVolumesList(bdev_path, labels, &nr_vols); + err = _buildVolumesList(bdev_path, labels, &nr_vols); if (err) { vvz_log_error("Could not read volume list from sysfs; error %d", err); goto out; @@ -106,31 +107,50 @@ out: * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -/* Reads the list of volumes from sysfs */ -static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) +/* Reads from sysfs to build the volumes list */ +static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols) { - char bdev_path_noslash[VVZ_BDEV_PATH_MAX_LEN + 1]; - char openvolumes_path[VVZ_BIGBUFSIZE]; - char *str_openvolumes; + char *bdev_name; + char devid_path[VVZ_BIGBUFSIZE]; + char *str_devid; + size_t dev_id; + char nrvolumes_path[VVZ_BIGBUFSIZE]; + char *str_nrvolumes; - /* Remove the slashes from the bdev_path (replace with underscores) */ - strcpy(bdev_path_noslash, bdev_path); - vvz_str_replaceAll(bdev_path_noslash, '/', '_'); - /* Build path to sysfsy file containing open volumes list */ - sprintf(openvolumes_path, "%s/%s/%s", VVZ_SYSFS_BDEVS_DIR, bdev_path_noslash, VVZ_SYSFS_OPENVOLUMES_FILENAME); + /* Get device name as : */ + bdev_name = vvz_disk_getDeviceName(bdev_path); + if(!bdev_name) { + vvz_log_error("Could not allocate device name"); + return ENOMEM; + } + /* Build path to sysfs file containing device ID */ + sprintf(devid_path, "%s/%s/%s", VVZ_SYSFS_BDEVS_DIR, bdev_name, VVZ_SYSFS_DEVID_FILENAME); + /* Build path to sysfs file containing number of open volumes */ + sprintf(nrvolumes_path, "%s/%s/%s", VVZ_SYSFS_BDEVS_DIR, bdev_name, VVZ_SYSFS_OPENVOLUMES_FILENAME); - /* Read the sysfs file */ - str_openvolumes = vvz_readFile(openvolumes_path); - if (!str_openvolumes) { - vvz_log_error("Could not read file %s", openvolumes_path); + /* Read the device ID */ + str_devid = vvz_readFile(devid_path); + if (!str_devid) { + vvz_log_error("Could not read file %s", devid_path); + return EBADF; + } + /* Parse the device ID */ + if (sscanf(str_devid, "%lu", &dev_id) != 1) { + vvz_log_error("Could not parse device ID:\n%s", str_devid); return EBADF; } + /* Read the number of volumes */ + str_nrvolumes = vvz_readFile(nrvolumes_path); + if (!str_nrvolumes) { + vvz_log_error("Could not read file %s", nrvolumes_path); + return EBADF; + } /* Parse the number of volumes */ - char *endptr; - *nr_vols = strtoul(str_openvolumes, &endptr, 10); - /* Skip past the number of volumes (lands on a whitespace before the first label) */ - str_openvolumes = endptr; + if (sscanf(str_nrvolumes, "%lu", nr_vols) != 1) { + vvz_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); + return EBADF; + } /* Just to be sure */ if (*nr_vols > VVZ_DEV_MAX_VOLUMES) { @@ -138,18 +158,10 @@ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) return EBADF; } - /* Read labels */ + /* Build labels */ size_t i; for (i = 0; i < *nr_vols; i++) { - /* Trust the content of the sysfs file */ - if (sscanf(str_openvolumes, " %s", labels[i]) != 1) { - vvz_log_error("Could not read volume label %lu. Sysfs content:\n%s", i, str_openvolumes); - return EBADF; - } - vvz_log_debug("Label %lu to close: %s", i, labels[i]); - - /* Skip past the whitespace and the label */ - str_openvolumes += 1 + strlen(labels[i]); + sprintf(labels[i], "vvz_%lu_%lu", dev_id, i); } return 0; From ec5e83a23e469f3ad787fd4057c41f6bbc0c1974 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 23 Apr 2024 21:15:00 +0200 Subject: [PATCH 50/75] Move dm_dev to volume --- dm-vvz/device.c | 38 ++++++++++++++++++++++++++++++++++---- dm-vvz/posmap.c | 4 ++-- dm-vvz/read.c | 2 +- dm-vvz/sysfs.c | 16 ++++++++++++++-- dm-vvz/volume.c | 14 +++++++++++++- dm-vvz/vvz.c | 29 +++++++++++++---------------- dm-vvz/vvz.h | 22 ++++++++++++++-------- dm-vvz/write.c | 2 +- 8 files changed, 92 insertions(+), 35 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 1eb195f..ef641c5 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -27,6 +27,8 @@ #include #include "vvz.h" +#include + /* Depth of the mempool backing the bio_set */ #define VVZ_BIOSET_BIOS 64 @@ -45,12 +47,15 @@ static void fisheryates_u32(u32 *v, u32 len) return; } -struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) +struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) { struct vvz_device *sdev; + dev_t devt; int i; int err; + DMWARN("ALLOCATING DEVICE"); + mdelay(5000); sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); if (!sdev) { DMERR("Could not allocate device"); @@ -59,7 +64,13 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) sdev->dev_id = dev_id; sdev->nr_volumes = 0; - /* The calling ->ctr() will set sdev->dm_dev */ + /* Look up block device and set name */ + err = lookup_bdev(bdev_path, &devt); + if (err) { + DMERR("Could not look up block device"); + goto bad_lookup; + } + format_dev_t(sdev->name, devt); /* Compute sizes */ sdev->tot_slices = tot_slices; @@ -74,12 +85,17 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) /* Shuffled PSIs */ mutex_init(&sdev->slices_lock); + DMWARN("ALLOCATING SLICES_OFLD: %u bytes", tot_slices); + mdelay(5000); sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); if (!sdev->slices_ofld) { DMERR("Could not allocate PSI occupation bitfield"); err = -ENOMEM; goto bad_ofld; } + + DMWARN("ALLOCATING PRMSLICES: %u bytes", tot_slices*4); + mdelay(5000); sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); if (!sdev->prmslices) { DMERR("Could not allocate shuffled PSI array"); @@ -89,10 +105,14 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) /* Generate a permutation */ for (i = 0; i < tot_slices; i++) sdev->prmslices[i] = i; + DMWARN("FISHER-YATES"); + mdelay(5000); fisheryates_u32(sdev->prmslices, tot_slices); sdev->prmslices_octr = 0; /* Bioset */ + DMWARN("BIOSET"); + mdelay(5000); err = bioset_init(&sdev->bioset, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); if (err) { DMERR("Could not init bioset; error %d", err); @@ -100,6 +120,8 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) } /* Client for dm-io */ + DMWARN("DM-IO"); + mdelay(5000); sdev->io_client = dm_io_client_create(); if (IS_ERR(sdev->io_client)) { err = PTR_ERR(sdev->io_client); @@ -108,18 +130,22 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) } /* I/O workqueue */ + DMWARN("IOQUEUE"); + mdelay(5000); sdev->io_queue = alloc_workqueue("vvz_%s_io", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, - 0, sdev->dm_dev->name); + 0, sdev->name); if (!sdev->io_queue) { err = -ENOMEM; DMERR("Could not allocate I/O workqueue"); goto bad_io_wq; } /* Decryption workqueue */ + DMWARN("CRYPTQUEUE"); + mdelay(5000); sdev->crypt_queue = alloc_workqueue("vvz_%s_crypt", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, - 0, sdev->dm_dev->name); + 0, sdev->name); if (!sdev->crypt_queue) { err = -ENOMEM; DMERR("Could not allocate decryption workqueue"); @@ -127,9 +153,12 @@ struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices) } /* Register to sysfs, once initialised */ + DMWARN("SYSFS"); + mdelay(5000); err = vvz_sysfs_register_device(sdev); if (err) { DMERR("Could not register device with sysfs; error %d", err); + mdelay(5000); goto bad_sysfs; } @@ -149,6 +178,7 @@ bad_bioset: bad_prmslices: vfree(sdev->slices_ofld); bad_ofld: +bad_lookup: kfree(sdev); return ERR_PTR(err); } diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 03e194a..4d6f538 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -113,7 +113,7 @@ static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) int err; /* Sync + flush TODO GFP mask ok? */ - bio = bio_alloc_bioset(sdev->dm_dev->bdev, 1, + bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, REQ_OP_WRITE | REQ_SYNC | REQ_FUA, GFP_NOIO, &sdev->bioset); if (!bio) { @@ -238,7 +238,7 @@ static int read_encrypted_posmap(struct vvz_volume *svol) .client = svol->sdev->io_client }; struct dm_io_region io_region = { - .bdev = svol->sdev->dm_dev->bdev, + .bdev = svol->dm_dev->bdev, .sector = VVZ_POSMAP_START_SECTOR(svol), .count = svol->sdev->posmap_size_sectors }; diff --git a/dm-vvz/read.c b/dm-vvz/read.c index 36f7761..0170a2c 100644 --- a/dm-vvz/read.c +++ b/dm-vvz/read.c @@ -60,7 +60,7 @@ void vvz_read_work_fn(struct work_struct *work) we can decrypt in place. */ /* Shallow copy */ - phys_bio = bio_alloc_clone(sdev->dm_dev->bdev, orig_bio, GFP_NOIO, &sdev->bioset); + phys_bio = bio_alloc_clone(svol->dm_dev->bdev, orig_bio, GFP_NOIO, &sdev->bioset); if (!phys_bio) { DMERR("Could not clone original bio"); orig_bio->bi_status = BLK_STS_IOERR; diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index c0efb8b..f28343b 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -23,6 +23,7 @@ #include "vvz.h" +#include /* *---------------------------- @@ -134,7 +135,8 @@ ATTRIBUTE_GROUPS(vvz_device_default); static void vvz_device_kobj_release(struct kobject *kobj) { struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - + DMWARN("COMPLETE"); + mdelay(5000); complete(&sdev->kobj_released); } @@ -149,22 +151,32 @@ int vvz_sysfs_register_device(struct vvz_device *sdev) int err; /* Completion */ + DMWARN("INIT COMPLETION"); + mdelay(5000); init_completion(&sdev->kobj_released); /* Register directory :/ under bdevs/ */ sdev->kobj.kset = bdevs_kset; + DMWARN("INIT AND ADD"); + mdelay(5000); err = kobject_init_and_add(&sdev->kobj, &vvz_device_ktype, NULL, - "%s", sdev->dm_dev->name); + "%s", sdev->name); if (err) goto bad; /* Emit uevent */ + DMWARN("UEVENT"); + mdelay(5000); kobject_uevent(&sdev->kobj, KOBJ_ADD); return 0; bad: + DMWARN("PUT"); + mdelay(5000); kobject_put(&sdev->kobj); + DMWARN("WAIT COMPLETION"); + mdelay(5000); wait_for_completion(&sdev->kobj_released); return err; } diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 51ad740..2f7fe60 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -25,7 +25,8 @@ #include "vvz.h" -struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *enckey) +struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, + u8 *enckey, struct dm_target *ti) { struct vvz_volume *svol; int err; @@ -40,6 +41,14 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *e svol->vol_idx = vol_idx; sprintf(svol->name, "vvz_%u_%lu", sdev->dev_id, vol_idx); + svol->ti = ti; + err = dm_get_device(ti, sdev->name, + dm_table_get_mode(ti->table), &svol->dm_dev); + if (err) { + ti->error = "Device lookup failed"; + goto bad_dm_dev; + } + /* Crypto */ svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (IS_ERR(svol->tfm)) { @@ -87,6 +96,8 @@ bad_posmap_alloc: bad_tfm_setkey: crypto_free_skcipher(svol->tfm); bad_tfm_alloc: + dm_put_device(ti, svol->dm_dev); +bad_dm_dev: kfree(svol); return ERR_PTR(err); } @@ -97,6 +108,7 @@ void vvz_vol_destroy(struct vvz_volume *svol) vvz_sysfs_unregister_volume(svol); vfree(svol->posmap); crypto_free_skcipher(svol->tfm); + dm_put_device(svol->ti, svol->dm_dev); kfree(svol); return; diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index aef3c45..3e5a0a8 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -27,6 +27,7 @@ #include "vvz_constants.h" #include "vvz.h" +#include /* *---------------------------- @@ -131,18 +132,16 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* Create device, if this is the first volume, otherwise retrieve it */ if (vol_idx == 0) { - sdev = vvz_dev_create(dev_id, tot_slices); + DMWARN("CREATING DEVICE"); + mdelay(2000); + sdev = vvz_dev_create(dev_id, bdev_path, tot_slices); if (IS_ERR(sdev)) { ti->error = "Could not instantiate device"; return PTR_ERR(sdev); } - /* Set dm_dev */ - err = dm_get_device(ti, bdev_path, dm_table_get_mode(ti->table), &sdev->dm_dev); - if (err) { - ti->error = "Device lookup failed"; - goto bad_dm_dev; - } /* Insert in global array */ + DMWARN("INSERTING DEVICE GLOBAL"); + mdelay(2000); err = vvz_add_device_global(dev_id, sdev); if (err) { ti->error = "Could not add device to global array"; @@ -162,7 +161,9 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* Create volume */ - svol = vvz_vol_create(sdev, vol_idx, enckey); + DMWARN("CREATING VOLUME"); + mdelay(2000); + svol = vvz_vol_create(sdev, vol_idx, enckey, ti); if (IS_ERR(svol)) { ti->error = "Could not instantiate volume"; err = PTR_ERR(svol); @@ -190,8 +191,6 @@ bad_vol_create: if (vol_idx == 0) { vvz_remove_device_global(dev_id); bad_dev_global: - dm_put_device(ti, sdev->dm_dev); -bad_dm_dev: vvz_dev_destroy(sdev); } return err; @@ -203,15 +202,13 @@ static void vvz_dtr(struct dm_target *ti) { struct vvz_volume *svol = ti->private; struct vvz_device *sdev = svol->sdev; - size_t vol_idx = svol->vol_idx; vvz_vol_destroy(svol); /* We expect ->dtr() calls to be strictly sequential */ sdev->nr_volumes--; - if (vol_idx == 0) { + if (sdev->nr_volumes == 0) { vvz_remove_device_global(sdev->dev_id); - dm_put_device(ti, sdev->dm_dev); vvz_dev_destroy(sdev); } @@ -243,7 +240,7 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) DMWARN("Non-empty flush request!"); return DM_MAPIO_KILL; } - bio_set_dev(bio, svol->sdev->dm_dev->bdev); + bio_set_dev(bio, svol->dm_dev->bdev); return DM_MAPIO_REMAPPED; } @@ -251,7 +248,7 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) sio->svol = svol; sio->orig_bio = bio; sio->lsi = lblk_num >> VVZ_SLICE_SHIFT; - sio->block_offset = lblk_num & GENMASK(VVZ_SLICE_SHIFT - 1, 0); + sio->block_offset = lblk_num & ((1U << VVZ_SLICE_SHIFT) - 1); /* Enqueue */ if (bio_data_dir(bio) == READ) @@ -281,7 +278,7 @@ static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn struct vvz_volume *svol = ti->private; struct vvz_device *sdev = svol->sdev; - return fn(ti, svol->sdev->dm_dev, 0, sdev->dev_header_size_sectors + + return fn(ti, svol->dm_dev, 0, sdev->dev_header_size_sectors + (ti->len * VVZ_BLOCK_SCALE), data); } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index f73ef8d..9867610 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -50,16 +50,16 @@ struct vvz_device { /* Shufflecake-unique device ID */ u32 dev_id; + /* : */ + char name[16]; - /* Underlying block device */ - struct dm_dev *dm_dev; + /* Logical size of each volume */ u32 tot_slices; - /* Header sizes in 512-byte sectors */ sector_t posmap_size_sectors; sector_t dev_header_size_sectors; - /* Number of volumes */ + /* Number of volumes. No need for an atomic_t */ size_t nr_volumes; /* Shuffled array of PSIs */ @@ -85,10 +85,15 @@ struct vvz_volume /* Backing device */ struct vvz_device *sdev; + /* Underlying block device. This can't go in the vvz_device struct, + * because each ti grabs its own reference. */ + struct dm_dev *dm_dev; + struct dm_target *ti; + /* Volume index within the device */ size_t vol_idx; - /* Name: vvz__ */ - char name[16]; + /* Volume name: vvz__ */ + char name[32]; /* Position map */ struct mutex posmap_lock; @@ -154,11 +159,12 @@ extern u32 vvz_free_devid; /* The lowest free devID */ */ /* Device */ -struct vvz_device *vvz_dev_create(u32 dev_id, u32 tot_slices); +struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices); void vvz_dev_destroy(struct vvz_device *sdev); /* Volume */ -struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, u8 *enckey); +struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, + u8 *enckey, struct dm_target *ti); void vvz_vol_destroy(struct vvz_volume *svol); /* Sysfs */ diff --git a/dm-vvz/write.c b/dm-vvz/write.c index 79e5e7e..4fc1964 100644 --- a/dm-vvz/write.c +++ b/dm-vvz/write.c @@ -60,7 +60,7 @@ void vvz_write_work_fn(struct work_struct *work) mutex_unlock(&svol->posmap_lock); /* Allocate physical bio */ - phys_bio = bio_alloc_bioset(sdev->dm_dev->bdev, 1, orig_bio->bi_opf, + phys_bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, orig_bio->bi_opf, GFP_NOIO, &sdev->bioset); if (!phys_bio) { DMERR("Could not allocate physical bio"); From 40c7cbdc6c484f02139cf219a5f24ce540c2602a Mon Sep 17 00:00:00 2001 From: = Date: Fri, 26 Apr 2024 00:47:17 +0200 Subject: [PATCH 51/75] Fix major:minor --- vuvuzela-userland/src/utils/disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vuvuzela-userland/src/utils/disk.c b/vuvuzela-userland/src/utils/disk.c index 795d0d9..8b35caa 100644 --- a/vuvuzela-userland/src/utils/disk.c +++ b/vuvuzela-userland/src/utils/disk.c @@ -67,7 +67,7 @@ char *vvz_disk_getDeviceName(char *bdev_path) if (!dev_name) return NULL; - sprintf(dev_name, "%u:%u", major(sb.st_dev), minor(sb.st_dev)); + sprintf(dev_name, "%u:%u", major(sb.st_rdev), minor(sb.st_rdev)); return dev_name; } From 3e78cff0e1b9400498137c3a5ed99628899de7e5 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 26 Apr 2024 00:47:46 +0200 Subject: [PATCH 52/75] Add PSI sanity check --- dm-vvz/device.c | 26 ++++++++++++++------------ dm-vvz/posmap.c | 15 ++++++++++++++- dm-vvz/sysfs.c | 22 ++++++++++++++-------- dm-vvz/volume.c | 16 ++++++++++++++++ dm-vvz/vvz.c | 11 ++++++----- 5 files changed, 64 insertions(+), 26 deletions(-) diff --git a/dm-vvz/device.c b/dm-vvz/device.c index ef641c5..33910ef 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -55,7 +55,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) int err; DMWARN("ALLOCATING DEVICE"); - mdelay(5000); + msleep(2000); sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); if (!sdev) { DMERR("Could not allocate device"); @@ -86,7 +86,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) /* Shuffled PSIs */ mutex_init(&sdev->slices_lock); DMWARN("ALLOCATING SLICES_OFLD: %u bytes", tot_slices); - mdelay(5000); + msleep(2000); sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); if (!sdev->slices_ofld) { DMERR("Could not allocate PSI occupation bitfield"); @@ -95,7 +95,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } DMWARN("ALLOCATING PRMSLICES: %u bytes", tot_slices*4); - mdelay(5000); + msleep(2000); sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); if (!sdev->prmslices) { DMERR("Could not allocate shuffled PSI array"); @@ -106,13 +106,13 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) for (i = 0; i < tot_slices; i++) sdev->prmslices[i] = i; DMWARN("FISHER-YATES"); - mdelay(5000); + msleep(2000); fisheryates_u32(sdev->prmslices, tot_slices); sdev->prmslices_octr = 0; /* Bioset */ DMWARN("BIOSET"); - mdelay(5000); + msleep(2000); err = bioset_init(&sdev->bioset, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); if (err) { DMERR("Could not init bioset; error %d", err); @@ -120,8 +120,8 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } /* Client for dm-io */ - DMWARN("DM-IO"); - mdelay(5000); + DMWARN("DMIO"); + msleep(2000); sdev->io_client = dm_io_client_create(); if (IS_ERR(sdev->io_client)) { err = PTR_ERR(sdev->io_client); @@ -131,7 +131,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) /* I/O workqueue */ DMWARN("IOQUEUE"); - mdelay(5000); + msleep(2000); sdev->io_queue = alloc_workqueue("vvz_%s_io", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->name); @@ -142,7 +142,7 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } /* Decryption workqueue */ DMWARN("CRYPTQUEUE"); - mdelay(5000); + msleep(2000); sdev->crypt_queue = alloc_workqueue("vvz_%s_crypt", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->name); @@ -153,14 +153,16 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } /* Register to sysfs, once initialised */ - DMWARN("SYSFS"); - mdelay(5000); + DMWARN("DEVICE SYSFS"); + msleep(2000); err = vvz_sysfs_register_device(sdev); if (err) { DMERR("Could not register device with sysfs; error %d", err); - mdelay(5000); + msleep(2000); goto bad_sysfs; } + DMWARN("DEVICE DONE"); + msleep(2000); return sdev; diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 4d6f538..3a4b77c 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -24,6 +24,7 @@ #include #include "vvz.h" +#include /* *---------------------------- @@ -276,6 +277,12 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) goto skip_create_mapping; } + /* If PSI out of bounds, something's seriously wrong */ + if (psi >= sdev->tot_slices) { + DMERR("Decrypted PSI out of bounds: %lu >= %lu", psi, sdev->tot_slices); + return -EDOM; + } + /* If PSI already taken, sample a new one */ if (sdev->slices_ofld[psi]) { DMWARN("Corruption of volume %lu: LSI %u was evicted from PSI %u", @@ -285,7 +292,7 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) return err; posmap_block_dirty = true; } - /* Either way, create the mapping locally */ + /* Whether sanitised or not, create the mapping locally */ _create_local_slice_mapping(svol, lsi, psi); skip_create_mapping: @@ -318,11 +325,15 @@ int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) struct vvz_device *sdev = svol->sdev; /* Read raw posmap from disk */ + DMWARN("READ ENC POSMAP"); + msleep(2000); err = read_encrypted_posmap(svol); if (err) return err; /* Decrypt in place */ + DMWARN("DECRYPT POSMAP"); + msleep(2000); err = vvz_crypt_blocks_vm(svol->tfm, svol->posmap, svol->posmap, svol->sdev->posmap_size_sectors >> VVZ_BLOCK_SHIFT, VVZ_POSMAP_START_SECTOR(svol) >> VVZ_BLOCK_SHIFT, @@ -333,6 +344,8 @@ int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) /* Deserialise and sanitise as you go */ if (mutex_lock_interruptible(&sdev->slices_lock)) return -ERESTARTSYS; + DMWARN("DESER SANIT POSMAP"); + msleep(2000); err = _deserialise_and_sanitise_posmap(svol); mutex_unlock(&sdev->slices_lock); if (err) diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index f28343b..f82ab59 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -151,21 +151,21 @@ int vvz_sysfs_register_device(struct vvz_device *sdev) int err; /* Completion */ - DMWARN("INIT COMPLETION"); - mdelay(5000); + DMWARN("DEV INIT COMPLETION"); + msleep(2000); init_completion(&sdev->kobj_released); /* Register directory :/ under bdevs/ */ sdev->kobj.kset = bdevs_kset; - DMWARN("INIT AND ADD"); - mdelay(5000); + DMWARN("DEV INIT AND ADD"); + msleep(2000); err = kobject_init_and_add(&sdev->kobj, &vvz_device_ktype, NULL, "%s", sdev->name); if (err) goto bad; /* Emit uevent */ - DMWARN("UEVENT"); - mdelay(5000); + DMWARN("DEV UEVENT"); + msleep(2000); kobject_uevent(&sdev->kobj, KOBJ_ADD); return 0; @@ -173,10 +173,10 @@ int vvz_sysfs_register_device(struct vvz_device *sdev) bad: DMWARN("PUT"); - mdelay(5000); + msleep(2000); kobject_put(&sdev->kobj); DMWARN("WAIT COMPLETION"); - mdelay(5000); + msleep(2000); wait_for_completion(&sdev->kobj_released); return err; } @@ -232,14 +232,20 @@ int vvz_sysfs_register_volume(struct vvz_volume *svol) int err; /* Completion */ + DMWARN("VOL INIT COMPLETION"); + msleep(2000); init_completion(&svol->kobj_released); /* Register directory name>/ under device directory */ + DMWARN("VOL INIT AND ADD"); + msleep(2000); err = kobject_init_and_add(&svol->kobj, &vvz_volume_ktype, &svol->sdev->kobj, "%s", svol->name); if (err) goto bad; /* Emit uevent */ + DMWARN("VOL UEVENT"); + msleep(2000); kobject_uevent(&svol->kobj, KOBJ_ADD); return 0; diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 2f7fe60..0cfd471 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -23,6 +23,7 @@ #include #include "vvz.h" +#include struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, @@ -31,6 +32,9 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, struct vvz_volume *svol; int err; + + DMWARN("ALLOCATING VOLUME"); + msleep(2000); svol = kzalloc(sizeof(*svol), GFP_KERNEL); if (!svol) { DMERR("Could not allocate volume"); @@ -42,6 +46,8 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, sprintf(svol->name, "vvz_%u_%lu", sdev->dev_id, vol_idx); svol->ti = ti; + DMWARN("DMDEV"); + msleep(2000); err = dm_get_device(ti, sdev->name, dm_table_get_mode(ti->table), &svol->dm_dev); if (err) { @@ -50,12 +56,16 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, } /* Crypto */ + DMWARN("SKCIPHER"); + msleep(2000); svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (IS_ERR(svol->tfm)) { err = PTR_ERR(svol->tfm); DMERR("Could not allocate AES-XTS cipher handle; error %d", err); goto bad_tfm_alloc; } + DMWARN("SETKEY"); + msleep(2000); err = crypto_skcipher_setkey(svol->tfm, enckey, VVZ_XTS_KEYLEN); if (err) { DMERR("Could not set key in crypto transform; error %d", err); @@ -65,6 +75,8 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, /* Position map */ mutex_init(&svol->posmap_lock); /* Slight over-allocation, to fit a whole number of blocks */ + DMWARN("ALLOCATING POSMAP"); + msleep(2000); svol->posmap = vmalloc(sdev->posmap_size_sectors * SECTOR_SIZE); if (!svol->posmap) { DMERR("Could not allocate position map"); @@ -73,6 +85,8 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, } svol->nr_mapped_slices = 0; /* Load from disk */ + DMWARN("LOAD POSMAP"); + msleep(2000); err = vvz_load_and_sanitise_posmap(svol); if (err) { DMERR("Could not load position map from disk; error %d", err); @@ -80,6 +94,8 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, } /* Register to sysfs, once initialised */ + DMWARN("VOLUME SYSFS"); + msleep(2000); err = vvz_sysfs_register_volume(svol); if (err) { DMERR("Could not register volume with sysfs; error %d", err); diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 3e5a0a8..3ebf783 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -133,7 +133,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* Create device, if this is the first volume, otherwise retrieve it */ if (vol_idx == 0) { DMWARN("CREATING DEVICE"); - mdelay(2000); + msleep(2000); sdev = vvz_dev_create(dev_id, bdev_path, tot_slices); if (IS_ERR(sdev)) { ti->error = "Could not instantiate device"; @@ -141,7 +141,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* Insert in global array */ DMWARN("INSERTING DEVICE GLOBAL"); - mdelay(2000); + msleep(2000); err = vvz_add_device_global(dev_id, sdev); if (err) { ti->error = "Could not add device to global array"; @@ -162,7 +162,7 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* Create volume */ DMWARN("CREATING VOLUME"); - mdelay(2000); + msleep(2000); svol = vvz_vol_create(sdev, vol_idx, enckey, ti); if (IS_ERR(svol)) { ti->error = "Could not instantiate volume"; @@ -171,6 +171,8 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* We expect ->ctr() calls to be strictly sequential */ sdev->nr_volumes++; + DMWARN("ALL DONE"); + msleep(2000); /* Only accept one block per request for simplicity TODO: improve to one slice*/ ti->max_io_len = VVZ_BLOCK_SCALE; @@ -278,8 +280,7 @@ static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn struct vvz_volume *svol = ti->private; struct vvz_device *sdev = svol->sdev; - return fn(ti, svol->dm_dev, 0, sdev->dev_header_size_sectors + - (ti->len * VVZ_BLOCK_SCALE), data); + return fn(ti, svol->dm_dev, 0, sdev->dev_header_size_sectors + ti->len, data); } From c9106426b386fc11f27891c5a7e13ee1768f4e38 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 1 May 2024 17:18:52 +0200 Subject: [PATCH 53/75] fix: epm generation and writing --- vuvuzela-userland/include/utils/crypto.h | 2 +- vuvuzela-userland/include/utils/log.h | 4 ++-- vuvuzela-userland/src/header/position_map.c | 15 +++++++++++---- vuvuzela-userland/src/operations/volume_header.c | 2 +- vuvuzela-userland/src/utils/crypto.c | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/vuvuzela-userland/include/utils/crypto.h b/vuvuzela-userland/include/utils/crypto.h index e9d1ed9..c47ca9b 100644 --- a/vuvuzela-userland/include/utils/crypto.h +++ b/vuvuzela-userland/include/utils/crypto.h @@ -93,7 +93,7 @@ int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); /* AES256-XTS encryption. Set ct = NULL for in-place. - * The IV is intepreted as a little-endian "sector number", and incremented by 1 */ + * The IV is intepreted as a little-endian "sector number" */ int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-GCM encryption, does not touch the IV */ diff --git a/vuvuzela-userland/include/utils/log.h b/vuvuzela-userland/include/utils/log.h index 6790ae5..60a251f 100644 --- a/vuvuzela-userland/include/utils/log.h +++ b/vuvuzela-userland/include/utils/log.h @@ -120,13 +120,13 @@ static inline void vvz_log_hex(char *str, size_t len) for (i = 0; i < len; i++) { printf("%02x ", s[i]); // Nice aligned wrapping - if (i % 16 == 15) { + if (i % 32 == 31) { printf("\n"); } } // Always end with a newline - if (i % 16 != 0) { + if (i % 32 != 0) { printf("\n"); } diff --git a/vuvuzela-userland/src/header/position_map.c b/vuvuzela-userland/src/header/position_map.c index 7d72f1d..4abdab3 100644 --- a/vuvuzela-userland/src/header/position_map.c +++ b/vuvuzela-userland/src/header/position_map.c @@ -55,6 +55,7 @@ void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) char iv[VVZ_AESXTS_IVLEN]; void *epm; size_t nr_pmbs; + uint64_t pblk_num; int err; // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) @@ -69,14 +70,17 @@ void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) // Fill cleartext PMB with 0xFF memset(pmb, VVZ_EPM_FILLER, VVZ_BLOCK_SIZE); - // Set the IV for the first encryption - memset(iv, 0, VVZ_AESXTS_IVLEN); - *((uint64_t*)iv) = htole64(vvz_pmStartBlock(vol_idx, nr_slices)); + // First physical block number + pblk_num = vvz_pmStartBlock(vol_idx, nr_slices); // Loop to encrypt each PMB int i; for (i = 0; i < nr_pmbs; i++) { - // Encrypt. Auto-increment IV for next encryption + // Set IV + memset(iv, 0, VVZ_AESXTS_IVLEN); + *((uint64_t*)iv) = htole64(pblk_num); + + // Encrypt err = vvz_aes256xts_encrypt(volume_key, pmb, VVZ_BLOCK_SIZE, iv, epm + i*VVZ_BLOCK_SIZE); if (err) { @@ -84,6 +88,9 @@ void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) free(epm); return NULL; } + + // Increment block number + pblk_num++; } return epm; diff --git a/vuvuzela-userland/src/operations/volume_header.c b/vuvuzela-userland/src/operations/volume_header.c index a0c0176..9c5e611 100644 --- a/vuvuzela-userland/src/operations/volume_header.c +++ b/vuvuzela-userland/src/operations/volume_header.c @@ -84,7 +84,7 @@ int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size } // Write to disk - sector = vvz_pmStartBlock(vol_idx, sector); + sector = vvz_pmStartBlock(vol_idx, vmb->nr_slices); err = vvz_disk_writeManyBlocks(bdev_path, sector, epm, ceil(vmb->nr_slices, VVZ_SLICE_IDX_PER_BLOCK)); if (err) { diff --git a/vuvuzela-userland/src/utils/crypto.c b/vuvuzela-userland/src/utils/crypto.c index d3b7c46..6f93c4a 100644 --- a/vuvuzela-userland/src/utils/crypto.c +++ b/vuvuzela-userland/src/utils/crypto.c @@ -207,7 +207,7 @@ bad_open: /** * AES256-XTS encryption. Set ct = NULL for in-place. - * The IV is intepreted as a little-endian "sector number", and incremented by 1. + * The IV is intepreted as a little-endian "sector number". * * @param key The 64-byte AES-XTS key * @param pt The plaintext From a3178d9753557709a68007269089f6ffde4fb4b9 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 1 May 2024 17:20:06 +0200 Subject: [PATCH 54/75] Open kinda works i'd say --- dm-vvz/crypto.c | 29 ++++++++++++++++++++++------- dm-vvz/device.c | 27 +-------------------------- dm-vvz/posmap.c | 10 +--------- dm-vvz/sysfs.c | 20 -------------------- dm-vvz/volume.c | 19 ++----------------- dm-vvz/vvz.c | 10 ---------- dm-vvz/vvz.h | 1 + 7 files changed, 27 insertions(+), 89 deletions(-) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index be1e687..b5f7c4d 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -26,6 +26,8 @@ #include #include "vvz_constants.h" +#include "vvz.h" + /** * Encrypt/decrypt exactly one block, already encoded in the scatterlist. @@ -70,16 +72,23 @@ static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, struct page *dst_page, u64 pblk_num, int rw) { - struct scatterlist dst, src; + struct scatterlist dst, src, *p_dst; + bool is_inplace; + + /* Use same scatterlist if in-place */ + is_inplace = (src_page == dst_page); + p_dst = is_inplace ? &src : &dst; /* We assume PAGE_SIZE == VVZ_BLOCK_SIZE */ /* And orig_bio to start at offset 0 within the page */ sg_init_table(&src, 1); sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); - sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); + if (is_inplace) { + sg_init_table(&dst, 1); + sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); + } - return crypt_sg(tfm, &src, &dst, pblk_num, rw); + return crypt_sg(tfm, &src, p_dst, pblk_num, rw); } @@ -87,17 +96,23 @@ int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, u64 num_blocks, u64 first_pblk_num, int rw) { - struct scatterlist dst, src; + struct scatterlist dst, src, *p_dst; u64 pblk_num; + bool is_inplace; int err; + /* Use same scatterlist if in-place */ + is_inplace = (src_buf == dst_buf); + p_dst = is_inplace ? &src : &dst; + for (pblk_num = first_pblk_num; pblk_num < first_pblk_num + num_blocks; pblk_num++) { sg_init_one(&src, src_buf, VVZ_BLOCK_SIZE); - sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); + if (is_inplace) + sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); - err = crypt_sg(tfm, &src, &dst, pblk_num, rw); + err = crypt_sg(tfm, &src, p_dst, pblk_num, rw); if (err) return err; diff --git a/dm-vvz/device.c b/dm-vvz/device.c index 33910ef..fd7cab3 100644 --- a/dm-vvz/device.c +++ b/dm-vvz/device.c @@ -27,8 +27,6 @@ #include #include "vvz.h" -#include - /* Depth of the mempool backing the bio_set */ #define VVZ_BIOSET_BIOS 64 @@ -54,8 +52,6 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) int i; int err; - DMWARN("ALLOCATING DEVICE"); - msleep(2000); sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); if (!sdev) { DMERR("Could not allocate device"); @@ -85,8 +81,6 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) /* Shuffled PSIs */ mutex_init(&sdev->slices_lock); - DMWARN("ALLOCATING SLICES_OFLD: %u bytes", tot_slices); - msleep(2000); sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); if (!sdev->slices_ofld) { DMERR("Could not allocate PSI occupation bitfield"); @@ -94,8 +88,6 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) goto bad_ofld; } - DMWARN("ALLOCATING PRMSLICES: %u bytes", tot_slices*4); - msleep(2000); sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); if (!sdev->prmslices) { DMERR("Could not allocate shuffled PSI array"); @@ -105,14 +97,10 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) /* Generate a permutation */ for (i = 0; i < tot_slices; i++) sdev->prmslices[i] = i; - DMWARN("FISHER-YATES"); - msleep(2000); fisheryates_u32(sdev->prmslices, tot_slices); sdev->prmslices_octr = 0; /* Bioset */ - DMWARN("BIOSET"); - msleep(2000); err = bioset_init(&sdev->bioset, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); if (err) { DMERR("Could not init bioset; error %d", err); @@ -120,8 +108,6 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } /* Client for dm-io */ - DMWARN("DMIO"); - msleep(2000); sdev->io_client = dm_io_client_create(); if (IS_ERR(sdev->io_client)) { err = PTR_ERR(sdev->io_client); @@ -130,8 +116,6 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } /* I/O workqueue */ - DMWARN("IOQUEUE"); - msleep(2000); sdev->io_queue = alloc_workqueue("vvz_%s_io", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->name); @@ -141,8 +125,6 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) goto bad_io_wq; } /* Decryption workqueue */ - DMWARN("CRYPTQUEUE"); - msleep(2000); sdev->crypt_queue = alloc_workqueue("vvz_%s_crypt", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 0, sdev->name); @@ -153,16 +135,9 @@ struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) } /* Register to sysfs, once initialised */ - DMWARN("DEVICE SYSFS"); - msleep(2000); err = vvz_sysfs_register_device(sdev); - if (err) { - DMERR("Could not register device with sysfs; error %d", err); - msleep(2000); + if (err) goto bad_sysfs; - } - DMWARN("DEVICE DONE"); - msleep(2000); return sdev; diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 3a4b77c..0c5e1e8 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -24,8 +24,6 @@ #include #include "vvz.h" -#include - /* *---------------------------- * Create slice mapping @@ -279,7 +277,7 @@ static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) /* If PSI out of bounds, something's seriously wrong */ if (psi >= sdev->tot_slices) { - DMERR("Decrypted PSI out of bounds: %lu >= %lu", psi, sdev->tot_slices); + DMERR("Decrypted PSI out of bounds: %u >= %u", psi, sdev->tot_slices); return -EDOM; } @@ -325,15 +323,11 @@ int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) struct vvz_device *sdev = svol->sdev; /* Read raw posmap from disk */ - DMWARN("READ ENC POSMAP"); - msleep(2000); err = read_encrypted_posmap(svol); if (err) return err; /* Decrypt in place */ - DMWARN("DECRYPT POSMAP"); - msleep(2000); err = vvz_crypt_blocks_vm(svol->tfm, svol->posmap, svol->posmap, svol->sdev->posmap_size_sectors >> VVZ_BLOCK_SHIFT, VVZ_POSMAP_START_SECTOR(svol) >> VVZ_BLOCK_SHIFT, @@ -344,8 +338,6 @@ int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) /* Deserialise and sanitise as you go */ if (mutex_lock_interruptible(&sdev->slices_lock)) return -ERESTARTSYS; - DMWARN("DESER SANIT POSMAP"); - msleep(2000); err = _deserialise_and_sanitise_posmap(svol); mutex_unlock(&sdev->slices_lock); if (err) diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c index f82ab59..efd3df2 100644 --- a/dm-vvz/sysfs.c +++ b/dm-vvz/sysfs.c @@ -23,8 +23,6 @@ #include "vvz.h" -#include - /* *---------------------------- * Top-level entries @@ -135,8 +133,6 @@ ATTRIBUTE_GROUPS(vvz_device_default); static void vvz_device_kobj_release(struct kobject *kobj) { struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - DMWARN("COMPLETE"); - mdelay(5000); complete(&sdev->kobj_released); } @@ -151,32 +147,22 @@ int vvz_sysfs_register_device(struct vvz_device *sdev) int err; /* Completion */ - DMWARN("DEV INIT COMPLETION"); - msleep(2000); init_completion(&sdev->kobj_released); /* Register directory :/ under bdevs/ */ sdev->kobj.kset = bdevs_kset; - DMWARN("DEV INIT AND ADD"); - msleep(2000); err = kobject_init_and_add(&sdev->kobj, &vvz_device_ktype, NULL, "%s", sdev->name); if (err) goto bad; /* Emit uevent */ - DMWARN("DEV UEVENT"); - msleep(2000); kobject_uevent(&sdev->kobj, KOBJ_ADD); return 0; bad: - DMWARN("PUT"); - msleep(2000); kobject_put(&sdev->kobj); - DMWARN("WAIT COMPLETION"); - msleep(2000); wait_for_completion(&sdev->kobj_released); return err; } @@ -232,20 +218,14 @@ int vvz_sysfs_register_volume(struct vvz_volume *svol) int err; /* Completion */ - DMWARN("VOL INIT COMPLETION"); - msleep(2000); init_completion(&svol->kobj_released); /* Register directory name>/ under device directory */ - DMWARN("VOL INIT AND ADD"); - msleep(2000); err = kobject_init_and_add(&svol->kobj, &vvz_volume_ktype, &svol->sdev->kobj, "%s", svol->name); if (err) goto bad; /* Emit uevent */ - DMWARN("VOL UEVENT"); - msleep(2000); kobject_uevent(&svol->kobj, KOBJ_ADD); return 0; diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c index 0cfd471..7de135b 100644 --- a/dm-vvz/volume.c +++ b/dm-vvz/volume.c @@ -23,7 +23,6 @@ #include #include "vvz.h" -#include struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, @@ -32,9 +31,6 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, struct vvz_volume *svol; int err; - - DMWARN("ALLOCATING VOLUME"); - msleep(2000); svol = kzalloc(sizeof(*svol), GFP_KERNEL); if (!svol) { DMERR("Could not allocate volume"); @@ -46,8 +42,6 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, sprintf(svol->name, "vvz_%u_%lu", sdev->dev_id, vol_idx); svol->ti = ti; - DMWARN("DMDEV"); - msleep(2000); err = dm_get_device(ti, sdev->name, dm_table_get_mode(ti->table), &svol->dm_dev); if (err) { @@ -56,17 +50,14 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, } /* Crypto */ - DMWARN("SKCIPHER"); - msleep(2000); svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (IS_ERR(svol->tfm)) { err = PTR_ERR(svol->tfm); DMERR("Could not allocate AES-XTS cipher handle; error %d", err); goto bad_tfm_alloc; } - DMWARN("SETKEY"); - msleep(2000); - err = crypto_skcipher_setkey(svol->tfm, enckey, VVZ_XTS_KEYLEN); + memcpy(svol->enckey, enckey, VVZ_XTS_KEYLEN); + err = crypto_skcipher_setkey(svol->tfm, svol->enckey, VVZ_XTS_KEYLEN); if (err) { DMERR("Could not set key in crypto transform; error %d", err); goto bad_tfm_setkey; @@ -75,8 +66,6 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, /* Position map */ mutex_init(&svol->posmap_lock); /* Slight over-allocation, to fit a whole number of blocks */ - DMWARN("ALLOCATING POSMAP"); - msleep(2000); svol->posmap = vmalloc(sdev->posmap_size_sectors * SECTOR_SIZE); if (!svol->posmap) { DMERR("Could not allocate position map"); @@ -85,8 +74,6 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, } svol->nr_mapped_slices = 0; /* Load from disk */ - DMWARN("LOAD POSMAP"); - msleep(2000); err = vvz_load_and_sanitise_posmap(svol); if (err) { DMERR("Could not load position map from disk; error %d", err); @@ -94,8 +81,6 @@ struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, } /* Register to sysfs, once initialised */ - DMWARN("VOLUME SYSFS"); - msleep(2000); err = vvz_sysfs_register_volume(svol); if (err) { DMERR("Could not register volume with sysfs; error %d", err); diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 3ebf783..9024dd4 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -27,8 +27,6 @@ #include "vvz_constants.h" #include "vvz.h" -#include - /* *---------------------------- * Device mapper target @@ -132,16 +130,12 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) /* Create device, if this is the first volume, otherwise retrieve it */ if (vol_idx == 0) { - DMWARN("CREATING DEVICE"); - msleep(2000); sdev = vvz_dev_create(dev_id, bdev_path, tot_slices); if (IS_ERR(sdev)) { ti->error = "Could not instantiate device"; return PTR_ERR(sdev); } /* Insert in global array */ - DMWARN("INSERTING DEVICE GLOBAL"); - msleep(2000); err = vvz_add_device_global(dev_id, sdev); if (err) { ti->error = "Could not add device to global array"; @@ -161,8 +155,6 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* Create volume */ - DMWARN("CREATING VOLUME"); - msleep(2000); svol = vvz_vol_create(sdev, vol_idx, enckey, ti); if (IS_ERR(svol)) { ti->error = "Could not instantiate volume"; @@ -171,8 +163,6 @@ static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* We expect ->ctr() calls to be strictly sequential */ sdev->nr_volumes++; - DMWARN("ALL DONE"); - msleep(2000); /* Only accept one block per request for simplicity TODO: improve to one slice*/ ti->max_io_len = VVZ_BLOCK_SCALE; diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 9867610..3aa66b2 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -105,6 +105,7 @@ struct vvz_volume struct completion kobj_released; /* Crypto */ + u8 enckey[VVZ_XTS_KEYLEN]; struct crypto_skcipher *tfm; }; From 76ea163f433ac27f017920aee90f096dfa81c23b Mon Sep 17 00:00:00 2001 From: Tommaso Gagliardoni Date: Sun, 30 Jun 2024 23:27:53 +0200 Subject: [PATCH 55/75] feat: Add CLI flag and VVZ constants for legacy VS lite mode --- dm-vvz/vvz_constants.h | 5 +++ vuvuzela-userland/include/cli.h | 8 ++--- vuvuzela-userland/include/commands.h | 11 +++--- vuvuzela-userland/include/vvz_constants.h | 42 +---------------------- vuvuzela-userland/src/cli/dispatch.c | 18 ++++++++-- 5 files changed, 31 insertions(+), 53 deletions(-) mode change 100644 => 120000 vuvuzela-userland/include/vvz_constants.h diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h index 16b1f73..7ed62d1 100644 --- a/dm-vvz/vvz_constants.h +++ b/dm-vvz/vvz_constants.h @@ -43,6 +43,11 @@ #define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL +#define VVZ_MODE_LEGACY 0 +#define VVZ_MODE_LITE 1 +#define VVZ_MODE_FULL 2 + + #define VVZ_BLOCK_SIZE 4096 /* bytes */ #define VVZ_BLOCK_SHIFT 3 #define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* 8 sectors in a block */ diff --git a/vuvuzela-userland/include/cli.h b/vuvuzela-userland/include/cli.h index e8b495b..b58b313 100644 --- a/vuvuzela-userland/include/cli.h +++ b/vuvuzela-userland/include/cli.h @@ -49,15 +49,15 @@ int vvz_cli_dispatch(int argc, char **argv); /* Initializes device and create empty volumes */ -int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill); +int vvz_cli_init(char *block_device, int vvz_mode, int num_volumes, int skip_randfill); /* Open volumes */ -int vvz_cli_open(char *block_device); +int vvz_cli_open(char *block_device, int vvz_mode); /* Close volumes */ int vvz_cli_close(char *block_device); /* Test password */ -int vvz_cli_testPwd(char *block_device); +int vvz_cli_testPwd(char *block_device, int vvz_mode); /* Change password */ -int vvz_cli_changePwd(char *block_device); +int vvz_cli_changePwd(char *block_device, int vvz_mode); #endif /* _CLI_H_ */ diff --git a/vuvuzela-userland/include/commands.h b/vuvuzela-userland/include/commands.h index a15ad14..1cdab7d 100644 --- a/vuvuzela-userland/include/commands.h +++ b/vuvuzela-userland/include/commands.h @@ -50,13 +50,13 @@ typedef struct { /* Underlying block device */ char *bdev_path; - + /* Shufflecake mode (legacy,lite,full) */ + int vvz_mode; /* Number of volumes */ size_t nr_vols; /* Volumes' passwords */ char **pwds; size_t *pwd_lens; - /* Option to skip random filling */ bool no_randfill; @@ -68,7 +68,8 @@ typedef struct { /* Underlying block device */ char *bdev_path; - + /* Shufflecake mode (legacy,lite,full) */ + int vvz_mode; /* The only password provided */ char *pwd; size_t pwd_len; @@ -79,10 +80,10 @@ typedef struct { /* Underlying block device */ char *bdev_path; - + /* Shufflecake mode (legacy,lite,full) */ + int vvz_mode; /* Content of the DMB cell */ vvz_DmbCell *dmb_cell; - /* The new password */ char *new_pwd; size_t new_pwd_len; diff --git a/vuvuzela-userland/include/vvz_constants.h b/vuvuzela-userland/include/vvz_constants.h deleted file mode 100644 index 9f27092..0000000 --- a/vuvuzela-userland/include/vvz_constants.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * PLACEHOLDER * - *****************************************************/ - -/* This is just a placeholder for defining constants and parameters that must be the same across shufflecake components (kernel module, userland tool, etc) such as block size, slice size etc */ - - -#define VVZ_VER_MAJOR 0 -#define VVZ_VER_MINOR 4 -#define VVZ_VER_REVISION 0 -#define VVZ_VER_SPECIAL "rc1" - -#define STRINGIFY0(s) # s -#define STRINGIFY(s) STRINGIFY0(s) - -#define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL - - diff --git a/vuvuzela-userland/include/vvz_constants.h b/vuvuzela-userland/include/vvz_constants.h new file mode 120000 index 0000000..5c10997 --- /dev/null +++ b/vuvuzela-userland/include/vvz_constants.h @@ -0,0 +1 @@ +../../dm-vvz/vvz_constants.h \ No newline at end of file diff --git a/vuvuzela-userland/src/cli/dispatch.c b/vuvuzela-userland/src/cli/dispatch.c index ad170fa..3debf68 100644 --- a/vuvuzela-userland/src/cli/dispatch.c +++ b/vuvuzela-userland/src/cli/dispatch.c @@ -67,6 +67,7 @@ enum vvz_cli_action { struct vvz_cli_arguments { enum vvz_cli_action act; char *block_device; + int sflc_mode; int num_volumes; bool skip_randfill; }; @@ -115,6 +116,8 @@ static struct argp_option options[] = { "Specify number of volumes to be created with `init'. Must be an integer between 1 and 15.", 0 }, // TODO: define MAX_VOLS instead of hardcoding 15 {"skip-randfill", VVZ_OPT_SKIPRAND_KEY, 0, 0, "Skip pre-overwriting block device with random data, only valid with `init'. Faster but less secure. Use only for debugging or testing."}, + {"legacy", VVZ_OPT_LEGACY, 0, 0, + "Use the old (pre-v0.5.0) Shufflecake format. Only valid with `init`, `open', `testpwd', `changepwd'. Use of this option is not recommended. This mode is going to be deprecated in future versions."}, {0} }; @@ -141,6 +144,7 @@ int vvz_cli_dispatch(int argc, char **argv) { arguments.act = -1; arguments.block_device = NULL; + arguments.vvz_mode = VVZ_MODE_LITE; arguments.num_volumes = 0; arguments.skip_randfill = false; @@ -152,6 +156,11 @@ int vvz_cli_dispatch(int argc, char **argv) { printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); return EINVAL; } + /* Legacy mode should not be specified with `close' action */ + if (arguments.vvz_mode && arguments.act == VVZ_ACT_CLOSE) { + printf("Error: --legacy should not be used with `close'.\n"); + return EINVAL; + } /* Check options consistency */ if (arguments.skip_randfill && arguments.act != VVZ_ACT_INIT) { printf("Error: --skip-randfill can only be combined with `init'.\n"); @@ -168,16 +177,16 @@ int vvz_cli_dispatch(int argc, char **argv) { return vvz_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); } if (arguments.act == VVZ_ACT_OPEN) { - return vvz_cli_open(arguments.block_device); + return vvz_cli_open(arguments.block_device arguments.vvz_mode,); } if (arguments.act == VVZ_ACT_CLOSE) { return vvz_cli_close(arguments.block_device); } if (arguments.act == VVZ_ACT_TESTPWD) { - return vvz_cli_testPwd(arguments.block_device); + return vvz_cli_testPwd(arguments.block_device arguments.vvz_mode,); } if (arguments.act == VVZ_ACT_CHANGEPWD) { - return vvz_cli_changePwd(arguments.block_device); + return vvz_cli_changePwd(arguments.block_device arguments.vvz_mode,); } printf("\n"); @@ -225,6 +234,9 @@ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { case VVZ_OPT_NUMVOLS_KEY: arguments->num_volumes = atoi(arg); break; + case VVZ_OPT_LEGACY: + arguments->vvz_mode = VVZ_MODE_LEGACY; + break; case VVZ_OPT_SKIPRAND_KEY: arguments->skip_randfill = true; break; From ae3805df5e1a5f848f20561f155c021ecb4bbce4 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 28 Jul 2024 18:19:48 +0200 Subject: [PATCH 56/75] fix: all errors it seems --- dm-vvz/crypto.c | 4 ++-- dm-vvz/posmap.c | 50 ++++++++++++++++++++++++++++++++++++++----------- dm-vvz/read.c | 32 ++++++++++++++++++++++++++++++- dm-vvz/vvz.c | 42 ++++++++++++++++++++++++++++++++--------- dm-vvz/vvz.h | 1 + dm-vvz/write.c | 12 ++++++++++++ 6 files changed, 118 insertions(+), 23 deletions(-) diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c index b5f7c4d..e4a2c0d 100644 --- a/dm-vvz/crypto.c +++ b/dm-vvz/crypto.c @@ -83,7 +83,7 @@ int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, /* And orig_bio to start at offset 0 within the page */ sg_init_table(&src, 1); sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); - if (is_inplace) { + if (!is_inplace) { sg_init_table(&dst, 1); sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); } @@ -109,7 +109,7 @@ int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_bu pblk_num < first_pblk_num + num_blocks; pblk_num++) { sg_init_one(&src, src_buf, VVZ_BLOCK_SIZE); - if (is_inplace) + if (!is_inplace) sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); err = crypt_sg(tfm, &src, p_dst, pblk_num, rw); diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c index 0c5e1e8..6d8711c 100644 --- a/dm-vvz/posmap.c +++ b/dm-vvz/posmap.c @@ -22,8 +22,18 @@ */ #include +#include #include "vvz.h" + +/* Helpers */ + +#define IS_PSI_TAKEN(sdev, psi) ( (sdev)->slices_ofld[(psi)] ) +#define NEXT_RANDOM_PSI(sdev) ( (sdev)->prmslices[(sdev)->prmslices_octr] ) +#define IS_LAST_LSI_IN_BLOCK(lsi, sdev) ( (((lsi)+1) % VVZ_PSIS_PER_BLOCK == 0) || \ + (((lsi)+1) == (sdev)->tot_slices) ) + + /* *---------------------------- * Create slice mapping @@ -40,13 +50,26 @@ static int peek_next_free_psi(struct vvz_device *sdev, u32 *psi) { if (unlikely(!sdev->nr_free_slices)) return -ENOSPC; - if (unlikely(sdev->prmslices_octr >= sdev->tot_slices)) + if (unlikely(sdev->prmslices_octr >= sdev->tot_slices)) { + DMCRIT("octr = %u, tot_slices = %u, free_slices = %u", sdev->prmslices_octr, sdev->tot_slices, sdev->nr_free_slices); + print_hex_dump(KERN_CRIT, "prmslices(REV) ", DUMP_PREFIX_OFFSET, 32, 4, sdev->prmslices, 4*sdev->tot_slices, false); + msleep(10000); + print_hex_dump(KERN_CRIT, "ofld(REV) ", DUMP_PREFIX_OFFSET, 32, 1, sdev->slices_ofld, sdev->tot_slices, false); + msleep(10000); return -ENOTRECOVERABLE; // Grave inconsistency + } /* Invariant: @prmslices_octr points to a free slice */ - *psi = sdev->prmslices[sdev->prmslices_octr]; - if (unlikely(sdev->slices_ofld[*psi])) + *psi = NEXT_RANDOM_PSI(sdev); + if (unlikely(IS_PSI_TAKEN(sdev, *psi))){ + DMCRIT("octr = %u, tot_slices = %u, free_slices = %u", sdev->prmslices_octr, sdev->tot_slices, sdev->nr_free_slices); + DMCRIT("PSI %u is occupied", *psi); + print_hex_dump(KERN_CRIT, "prmslices ", DUMP_PREFIX_OFFSET, 32, 4, sdev->prmslices, 4*sdev->tot_slices, false); + msleep(10000); + print_hex_dump(KERN_CRIT, "ofld ", DUMP_PREFIX_OFFSET, 32, 1, sdev->slices_ofld, sdev->tot_slices, false); + msleep(10000); return -ENOTRECOVERABLE; // Grave inconsistency + } return 0; } @@ -61,16 +84,15 @@ static int peek_next_free_psi(struct vvz_device *sdev, u32 *psi) static void _create_local_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 psi) { struct vvz_device *sdev = svol->sdev; - u32 i; /* Grab it from the device */ sdev->slices_ofld[psi] = true; sdev->nr_free_slices--; // Preserve the invariant: @prmslices_octr must point to a free slice - for (i = sdev->prmslices_octr; - i < sdev->tot_slices && sdev->slices_ofld[i]; - i++); - sdev->prmslices_octr = i; + while(sdev->prmslices_octr < sdev->tot_slices && + IS_PSI_TAKEN(sdev, NEXT_RANDOM_PSI(sdev))) { + sdev->prmslices_octr++; + } /* Insert in the volume */ svol->posmap[lsi] = psi; @@ -143,9 +165,13 @@ static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) u32 lsi; for (lsi = first_lsi; lsi < last_lsi; lsi++) { u32 psi = svol->posmap[lsi]; - __be32 *be_psi = (__be32*) (page_ptr + (lsi * sizeof(__be32))); + __be32 *be_psi = (__be32*) (page_ptr + ((lsi-first_lsi) * sizeof(__be32))); *be_psi = cpu_to_be32(psi); } + +// print_hex_dump(KERN_WARNING, "page_ptr(REV) ", DUMP_PREFIX_OFFSET, 32, 4, page_ptr, VVZ_BLOCK_SIZE, false); +// msleep(100); + kunmap_local(page_ptr); /* Encrypt the block in place */ @@ -297,8 +323,7 @@ skip_create_mapping: /* Only check dirty bit at the end of the posmap block */ if (posmap_block_dirty && - (((lsi+1) % VVZ_PSIS_PER_BLOCK == 0) || - ((lsi+1) == sdev->tot_slices))) { + IS_LAST_LSI_IN_BLOCK(lsi, sdev)) { err = store_posmap_block(svol, lsi/VVZ_PSIS_PER_BLOCK); if (err) return err; @@ -343,6 +368,9 @@ int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) if (err) return err; +// print_hex_dump(KERN_CRIT, "posmap(REV) ", DUMP_PREFIX_OFFSET, 32, 4, svol->posmap, 4*sdev->tot_slices, false); +// msleep(2000); + return 0; } diff --git a/dm-vvz/read.c b/dm-vvz/read.c index 0170a2c..cd61934 100644 --- a/dm-vvz/read.c +++ b/dm-vvz/read.c @@ -22,6 +22,7 @@ */ #include "vvz.h" +#include static void vvz_read_endio(struct bio *phys_bio); @@ -50,15 +51,24 @@ void vvz_read_work_fn(struct work_struct *work) /* If LSI is unmapped, short-circuit and return all zeros */ if (psi == VVZ_PSI_INVALID) { + zero_fill_bio(orig_bio); orig_bio->bi_status = BLK_STS_OK; goto endio; } + sio->psi = psi; + +// DMWARN("READ: LSI=%u, PSI=%u, offset=%u", lsi, psi, sio->block_offset); +// msleep(100); /* Shallow-copy the bio and submit it (different bi_endio). We can shallow-copy because we don't need to own the pages, we can decrypt in place. */ + + //DMWARN("READ: shallow copying"); + //msleep(500); + /* Shallow copy */ phys_bio = bio_alloc_clone(svol->dm_dev->bdev, orig_bio, GFP_NOIO, &sdev->bioset); if (!phys_bio) { @@ -69,6 +79,9 @@ void vvz_read_work_fn(struct work_struct *work) /* Insert in the I/O struct */ sio->phys_bio = phys_bio; +// DMWARN("READ: submitting bio"); +// msleep(500); + /* Remap sector */ phys_bio->bi_iter.bi_sector = VVZ_PHYS_BIO_SECTOR(sdev, psi, block_offset); /* Set fields for the endio */ @@ -91,6 +104,9 @@ static void vvz_read_endio(struct bio *phys_bio) { struct vvz_io *sio = phys_bio->bi_private; +// DMWARN("READ ENDIO: queueing decryption"); +// //msleep(500); + /* Can't decrypt here in ISR: submit to decryption workqueue. * Can reuse the same work item, though, since it was popped out of the * io_queue already */ @@ -115,23 +131,37 @@ static void vvz_decrypt_work_fn(struct work_struct *work) goto endio; } +// DMWARN("DECRYPT FN: decrypting page in place"); +// msleep(2000); + /* Decrypt page in-place */ err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_page, - phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, READ); + VVZ_PHYS_BIO_SECTOR(svol->sdev, sio->psi, sio->block_offset) >> VVZ_BLOCK_SHIFT, + READ); if (err) { DMERR("Could not decrypt bio; error %d", err); orig_bio->bi_status = BLK_STS_IOERR; goto endio; } +// print_hex_dump(KERN_WARNING, "readpage ", DUMP_PREFIX_OFFSET, 32, 1, bvl.bv_page, VVZ_BLOCK_SIZE, true); +// msleep(2000); + +// DMWARN("DECRYPT FN: bio_advance"); +// msleep(300); + /* Advance original bio by one block */ bio_advance(orig_bio, VVZ_BLOCK_SIZE); orig_bio->bi_status = BLK_STS_OK; endio: /* Free the physical bio */ +// DMWARN("DECRYPT FN: bio_put"); +// msleep(300); bio_put(phys_bio); /* End original bio */ +// DMWARN("DECRYPT FN: bio_endio\n\n\n\n"); +// msleep(300); bio_endio(orig_bio); return; diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index 9024dd4..b8a6693 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -27,6 +27,8 @@ #include "vvz_constants.h" #include "vvz.h" +#include + /* *---------------------------- * Device mapper target @@ -214,15 +216,10 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) struct vvz_volume *svol = ti->private; sector_t lblk_num = bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT; - /* Accept one block at a time TODO improve */ - if (unlikely(bio->bi_iter.bi_size > VVZ_BLOCK_SIZE)) - dm_accept_partial_bio(bio, VVZ_BLOCK_SCALE); - /* Only one segment, single page, starting at 0 TODO improve */ - if (unlikely(bio_segments(bio) > 1 || - bio_offset(bio) != 0)) { - DMWARN("Unaligned bio!"); - return DM_MAPIO_KILL; - } + if (unlikely(!bio_has_data(bio))) { + DMWARN("No-data bio: bio_op() = %d, bi_opf = %u, bi_io_vec = %p, bi_idx = %u", bio_op(bio), bio->bi_opf, bio->bi_io_vec, bio->bi_iter.bi_idx); + msleep(100); + } /* Flush requests are just passed down, since our position map is * currently write-through, so we have no volatile cache */ @@ -230,12 +227,34 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) /* Has to be empty though */ if (bio_sectors(bio)) { DMWARN("Non-empty flush request!"); + msleep(100); return DM_MAPIO_KILL; } + DMWARN("REQ_PREFLUSH empty (phew), sector: %llu", bio->bi_iter.bi_sector); + msleep(3000); bio_set_dev(bio, svol->dm_dev->bdev); return DM_MAPIO_REMAPPED; } + /* Accept one block at a time TODO improve */ + if (unlikely(bio->bi_iter.bi_size > VVZ_BLOCK_SIZE)) { + DMWARN("Big bio: %u", bio->bi_iter.bi_size); + msleep(300); + dm_accept_partial_bio(bio, VVZ_BLOCK_SCALE); + } + /* Only one segment, single page, starting at 0 TODO improve */ + if (unlikely(bio_segments(bio) > 1 || + bio_offset(bio) != 0)) { + DMWARN("Unaligned bio!"); + msleep(3000); + return DM_MAPIO_KILL; + } + if (unlikely(bio->bi_iter.bi_size != VVZ_BLOCK_SIZE)) { + DMWARN("Wrong bio size: %u", bio->bi_iter.bi_size); + msleep(3000); + return DM_MAPIO_KILL; + } + /* Init I/O struct */ sio->svol = svol; sio->orig_bio = bio; @@ -270,6 +289,11 @@ static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn struct vvz_volume *svol = ti->private; struct vvz_device *sdev = svol->sdev; + if (!fn) { + dump_stack(); + msleep(2000); + return -EINVAL; + } return fn(ti, svol->dm_dev, 0, sdev->dev_header_size_sectors + ti->len, data); } diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h index 3aa66b2..de4ec73 100644 --- a/dm-vvz/vvz.h +++ b/dm-vvz/vvz.h @@ -117,6 +117,7 @@ struct vvz_io struct bio *phys_bio; u32 lsi; u32 block_offset; + u32 psi; struct work_struct work; }; diff --git a/dm-vvz/write.c b/dm-vvz/write.c index 4fc1964..36ee151 100644 --- a/dm-vvz/write.c +++ b/dm-vvz/write.c @@ -22,6 +22,7 @@ */ #include "vvz.h" +#include static void vvz_write_endio(struct bio *phys_bio); @@ -41,6 +42,10 @@ void vvz_write_work_fn(struct work_struct *work) u32 psi; int err; +// DMWARN("WRITE: dequeued. Sector = %llu", orig_bio->bi_iter.bi_sector); +// msleep(100); + + /* Read existing mapping, or create new one */ if (mutex_lock_interruptible(&svol->posmap_lock)) { orig_bio->bi_status = BLK_STS_IOERR; @@ -49,6 +54,9 @@ void vvz_write_work_fn(struct work_struct *work) psi = svol->posmap[lsi]; /* If LSI unmapped, create new mapping, while holding the lock */ if (psi == VVZ_PSI_INVALID) { +// DMWARN("WRITE: unmapped LSI %u, sampling PSI", lsi); +// msleep(100); + err = vvz_create_persistent_slice_mapping(svol, lsi, &psi); if (err){ DMERR("Could not create slice mapping; error %d", err); @@ -56,8 +64,11 @@ void vvz_write_work_fn(struct work_struct *work) orig_bio->bi_status = BLK_STS_IOERR; goto endio; } +// DMWARN("WRITE: sampled PSI %u for LSI %u", psi, lsi); +// msleep(100); } mutex_unlock(&svol->posmap_lock); + sio->psi = psi; /* Allocate physical bio */ phys_bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, orig_bio->bi_opf, @@ -117,6 +128,7 @@ static void vvz_write_endio(struct bio *phys_bio) /* If physical bio failed, then fail-fast */ if (phys_bio->bi_status != BLK_STS_OK) { orig_bio->bi_status = phys_bio->bi_status; + DMWARN("WRITE ENDIO: phys_bio failed"); goto endio; } From 57cd8f0c13ade6bbecb786bbc9919eca3e134329 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 28 Jul 2024 18:30:46 +0200 Subject: [PATCH 57/75] Comment out prints --- dm-vvz/vvz.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c index b8a6693..a61b688 100644 --- a/dm-vvz/vvz.c +++ b/dm-vvz/vvz.c @@ -217,8 +217,8 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) sector_t lblk_num = bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT; if (unlikely(!bio_has_data(bio))) { - DMWARN("No-data bio: bio_op() = %d, bi_opf = %u, bi_io_vec = %p, bi_idx = %u", bio_op(bio), bio->bi_opf, bio->bi_io_vec, bio->bi_iter.bi_idx); - msleep(100); +// DMWARN("No-data bio: bio_op() = %d, bi_opf = %u, bi_io_vec = %p, bi_idx = %u", bio_op(bio), bio->bi_opf, bio->bi_io_vec, bio->bi_iter.bi_idx); +// msleep(100); } /* Flush requests are just passed down, since our position map is @@ -227,11 +227,11 @@ static int vvz_map(struct dm_target *ti, struct bio *bio) /* Has to be empty though */ if (bio_sectors(bio)) { DMWARN("Non-empty flush request!"); - msleep(100); + msleep(3000); return DM_MAPIO_KILL; } - DMWARN("REQ_PREFLUSH empty (phew), sector: %llu", bio->bi_iter.bi_sector); - msleep(3000); +// DMWARN("REQ_PREFLUSH empty (phew), sector: %llu", bio->bi_iter.bi_sector); +// msleep(100); bio_set_dev(bio, svol->dm_dev->bdev); return DM_MAPIO_REMAPPED; } From 8755ba0014f578548f387a1bb9a7acfcbaef2d68 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 2 Aug 2024 17:47:49 +0200 Subject: [PATCH 58/75] Begin unification --- dm-sflc/Kbuild | 19 +- dm-sflc/crypto/rand/selftest.c | 114 ------- dm-sflc/crypto/symkey/selftest.c | 261 ---------------- dm-sflc/dev_vol.c | 185 ++++++++++++ dm-sflc/{ => old}/crypto/rand/rand.c | 54 ++-- dm-sflc/{ => old}/crypto/rand/rand.h | 17 +- dm-sflc/{ => old}/crypto/symkey/skreq_pool.c | 18 +- dm-sflc/{ => old}/crypto/symkey/skreq_pool.h | 10 +- dm-sflc/{ => old}/crypto/symkey/symkey.c | 50 +-- dm-sflc/{ => old}/crypto/symkey/symkey.h | 29 +- dm-sflc/{ => old}/device/device.c | 211 ++++--------- dm-sflc/{ => old}/device/device.h | 93 +++--- dm-sflc/{ => old}/device/iv.c | 67 +++-- dm-sflc/{ => old}/device/rawio.c | 14 +- dm-sflc/{ => old}/device/rmap.c | 14 +- dm-sflc/{ => old}/device/volumes.c | 43 +-- dm-sflc/{ => old}/log/log.h | 6 +- dm-sflc/{module.c => old/sflc_old.c} | 96 +----- dm-sflc/{target/target.h => old/sflc_old.h} | 40 +-- dm-sflc/old/sysfs.c | 142 +++++++++ dm-sflc/old/target.c | 150 +++++++++ dm-sflc/{ => old}/utils/bio.c | 12 +- dm-sflc/{ => old}/utils/bio.h | 10 +- dm-sflc/{ => old}/utils/pools.c | 94 +++--- dm-sflc/{ => old}/utils/pools.h | 22 +- dm-sflc/{ => old}/utils/string.c | 8 +- dm-sflc/{ => old}/utils/string.h | 10 +- dm-sflc/{ => old}/utils/vector.c | 10 +- dm-sflc/{ => old}/utils/vector.h | 8 +- dm-sflc/{ => old}/utils/workqueues.c | 30 +- dm-sflc/{ => old}/utils/workqueues.h | 14 +- dm-sflc/{ => old}/volume/fmap.c | 86 +++--- dm-sflc/{ => old}/volume/io.c | 24 +- dm-sflc/{ => old}/volume/read.c | 82 ++--- dm-sflc/{ => old}/volume/volume.c | 94 ++++-- dm-sflc/{ => old}/volume/volume.h | 69 ++--- dm-sflc/{ => old}/volume/write.c | 66 ++-- dm-sflc/sflc.c | 270 +++++++++++++++++ dm-sflc/sflc.h | 117 +++++++ dm-sflc/sflc_constants.h | 30 +- dm-sflc/sysfs.c | 206 +++++++++++++ dm-sflc/sysfs/devices.c | 301 ------------------- dm-sflc/sysfs/sysfs.c | 132 -------- dm-sflc/sysfs/sysfs.h | 125 -------- dm-sflc/sysfs/volumes.c | 151 ---------- dm-sflc/target/target.c | 280 ----------------- 46 files changed, 1714 insertions(+), 2170 deletions(-) delete mode 100644 dm-sflc/crypto/rand/selftest.c delete mode 100644 dm-sflc/crypto/symkey/selftest.c create mode 100644 dm-sflc/dev_vol.c rename dm-sflc/{ => old}/crypto/rand/rand.c (77%) rename dm-sflc/{ => old}/crypto/rand/rand.h (85%) rename dm-sflc/{ => old}/crypto/symkey/skreq_pool.c (82%) rename dm-sflc/{ => old}/crypto/symkey/skreq_pool.h (89%) rename dm-sflc/{ => old}/crypto/symkey/symkey.c (75%) rename dm-sflc/{ => old}/crypto/symkey/symkey.h (78%) rename dm-sflc/{ => old}/device/device.c (53%) rename dm-sflc/{ => old}/device/device.h (71%) rename dm-sflc/{ => old}/device/iv.c (82%) rename dm-sflc/{ => old}/device/rawio.c (89%) rename dm-sflc/{ => old}/device/rmap.c (89%) rename dm-sflc/{ => old}/device/volumes.c (70%) rename dm-sflc/{ => old}/log/log.h (95%) rename dm-sflc/{module.c => old/sflc_old.c} (52%) rename dm-sflc/{target/target.h => old/sflc_old.h} (69%) create mode 100644 dm-sflc/old/sysfs.c create mode 100644 dm-sflc/old/target.c rename dm-sflc/{ => old}/utils/bio.c (88%) rename dm-sflc/{ => old}/utils/bio.h (91%) rename dm-sflc/{ => old}/utils/pools.c (56%) rename dm-sflc/{ => old}/utils/pools.h (81%) rename dm-sflc/{ => old}/utils/string.c (92%) rename dm-sflc/{ => old}/utils/string.h (88%) rename dm-sflc/{ => old}/utils/vector.c (92%) rename dm-sflc/{ => old}/utils/vector.h (92%) rename dm-sflc/{ => old}/utils/workqueues.c (76%) rename dm-sflc/{ => old}/utils/workqueues.h (86%) rename dm-sflc/{ => old}/volume/fmap.c (81%) rename dm-sflc/{ => old}/volume/io.c (83%) rename dm-sflc/{ => old}/volume/read.c (72%) rename dm-sflc/{ => old}/volume/volume.c (57%) rename dm-sflc/{ => old}/volume/volume.h (70%) rename dm-sflc/{ => old}/volume/write.c (77%) create mode 100644 dm-sflc/sflc.c create mode 100644 dm-sflc/sflc.h create mode 100644 dm-sflc/sysfs.c delete mode 100644 dm-sflc/sysfs/devices.c delete mode 100644 dm-sflc/sysfs/sysfs.c delete mode 100644 dm-sflc/sysfs/sysfs.h delete mode 100644 dm-sflc/sysfs/volumes.c delete mode 100644 dm-sflc/target/target.c diff --git a/dm-sflc/Kbuild b/dm-sflc/Kbuild index a86d8b9..5c5c705 100644 --- a/dm-sflc/Kbuild +++ b/dm-sflc/Kbuild @@ -21,18 +21,18 @@ # If not, see . # -MODULE_NAME := dm-sflc +MODULE_NAME := dm_sflc obj-m := $(MODULE_NAME).o -OBJ_LIST := module.o -OBJ_LIST += sysfs/sysfs.o sysfs/devices.o sysfs/volumes.o -OBJ_LIST += target/target.o -OBJ_LIST += device/device.o device/volumes.o device/rawio.o device/rmap.o device/iv.o -OBJ_LIST += volume/volume.o volume/io.o volume/read.o volume/write.o volume/fmap.o -OBJ_LIST += utils/string.o utils/bio.o utils/pools.o utils/workqueues.o utils/vector.o -OBJ_LIST += crypto/rand/rand.o crypto/rand/selftest.o -OBJ_LIST += crypto/symkey/symkey.o crypto/symkey/skreq_pool.o crypto/symkey/selftest.o +OBJ_LIST := sflc.o dev_vol.o sysfs.o + +OBJ_LIST += old/sflc_old.o old/target.o old/sysfs.o +OBJ_LIST += old/device/device.o old/device/volumes.o old/device/rawio.o old/device/rmap.o old/device/iv.o +OBJ_LIST += old/volume/volume.o old/volume/io.o old/volume/read.o old/volume/write.o old/volume/fmap.o +OBJ_LIST += old/utils/string.o old/utils/bio.o old/utils/pools.o old/utils/workqueues.o old/utils/vector.o +OBJ_LIST += old/crypto/rand/rand.o +OBJ_LIST += old/crypto/symkey/symkey.o old/crypto/symkey/skreq_pool.o $(MODULE_NAME)-y += $(OBJ_LIST) @@ -41,7 +41,6 @@ $(MODULE_NAME)-y += $(OBJ_LIST) ccflags-y := -O2 ccflags-y += -I$(src) ccflags-y += -Wall -Wno-declaration-after-statement -ccflags-y += -fmacro-prefix-map=$(src)/= # Strip the non-project directories from the filename used in the logs # Debug CC flags ccflags-$(CONFIG_SFLC_DEBUG) += -DDEBUG diff --git a/dm-sflc/crypto/rand/selftest.c b/dm-sflc/crypto/rand/selftest.c deleted file mode 100644 index f0705b9..0000000 --- a/dm-sflc/crypto/rand/selftest.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - -#include "rand.h" -#include "log/log.h" - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/***************************************************** - * PRIVATE VARIABLES * - *****************************************************/ - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static void dumpHex(u8 * buf, unsigned count); - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Selftest to see (by eye :D) if generated bytes are actually random */ -int sflc_rand_selftest(void) -{ - u8 * buf; - int err; - - buf = kmalloc(32, GFP_KERNEL); - if (!buf) { - pr_err("Could not allocate random scratchpad\n"); - return -ENOMEM; - } - - /* Get random bytes the first time */ - err = sflc_rand_getBytes(buf, 32); - if (err) { - pr_err("Got error when trying to read random bytes the first time: %d\n", err); - kfree(buf); - return err; - } - pr_debug("Here's 32 random bytes, fresh fresh!\n"); - dumpHex(buf, 32); - - /* Do it again */ - err = sflc_rand_getBytes(buf, 32); - if (err) { - pr_err("Got error when trying to read random bytes the second time: %d\n", err); - kfree(buf); - return err; - } - pr_debug("Here's another 32 random bytes, fresh fresh pure questi!\n"); - dumpHex(buf, 32); - - pr_info("All well in the crypto rand self test? (Check random bytes)\n"); - kfree(buf); - - return 0; -} - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -static void dumpHex(u8 * buf, unsigned count) -{ - char * hex; - - hex = kmalloc(6*count + 1, GFP_KERNEL); - if (!hex) { - pr_err("Could not allocate hex dump string\n"); - return; - } - - int i; - for (i = 0; i < count; i++) { - sprintf(hex+6*i, "0x%02X, ", buf[i]); - } - - pr_notice("---- Hex dump ----\n"); - pr_notice("%s", hex); - pr_notice("---- End of hex dump ----\n"); - - kfree(hex); - return; -} diff --git a/dm-sflc/crypto/symkey/selftest.c b/dm-sflc/crypto/symkey/selftest.c deleted file mode 100644 index 332250d..0000000 --- a/dm-sflc/crypto/symkey/selftest.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "symkey.h" -#include "log/log.h" - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define KEYS \ -{ \ - {0xF6, 0xD6, 0x6D, 0x6B, 0xD5, 0x2D, 0x59, 0xBB, 0x07, 0x96, 0x36, 0x58, 0x79, 0xEF, 0xF8, 0x86, \ - 0xC6, 0x6D, 0xD5, 0x1A, 0x5B, 0x6A, 0x99, 0x74, 0x4B, 0x50, 0x59, 0x0C, 0x87, 0xA2, 0x38, 0x84}, \ - \ - {0xFF, 0x7A, 0x61, 0x7C, 0xE6, 0x91, 0x48, 0xE4, 0xF1, 0x72, 0x6E, 0x2F, 0x43, 0x58, 0x1D, 0xE2, \ - 0xAA, 0x62, 0xD9, 0xF8, 0x05, 0x53, 0x2E, 0xDF, 0xF1, 0xEE, 0xD6, 0x87, 0xFB, 0x54, 0x15, 0x3D}, \ -} - -#define IVS \ -{ \ - {0x00, 0xFA, 0xAC, 0x24, 0xC1, 0x58, 0x5E, 0xF1, 0x5A, 0x43, 0xD8, 0x75, 0x00, 0x00, 0x00, 0x01}, \ - \ - {0x00, 0x1C, 0xC5, 0xB7, 0x51, 0xA5, 0x1D, 0x70, 0xA1, 0xC1, 0x11, 0x48, 0x00, 0x00, 0x00, 0x01}, \ -} - -#define PLAINTEXTS \ -{ \ - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \ - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, \ - \ - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \ - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, \ -} - -#define CIPHERTEXTS \ -{ \ - {0xF0, 0x5E, 0x23, 0x1B, 0x38, 0x94, 0x61, 0x2C, 0x49, 0xEE, 0x00, 0x0B, 0x80, 0x4E, 0xB2, 0xA9, \ - 0xB8, 0x30, 0x6B, 0x50, 0x8F, 0x83, 0x9D, 0x6A, 0x55, 0x30, 0x83, 0x1D, 0x93, 0x44, 0xAF, 0x1C}, \ - \ - {0xEB, 0x6C, 0x52, 0x82, 0x1D, 0x0B, 0xBB, 0xF7, 0xCE, 0x75, 0x94, 0x46, 0x2A, 0xCA, 0x4F, 0xAA, \ - 0xB4, 0x07, 0xDF, 0x86, 0x65, 0x69, 0xFD, 0x07, 0xF4, 0x8C, 0xC0, 0xB5, 0x83, 0xD6, 0x07, 0x1F}, \ -} - -/***************************************************** - * PRIVATE VARIABLES * - *****************************************************/ - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Test encryption or decryption with known test vectors */ -static int testEncdec(bool encrypt); -/* Test that encryption and decryption invert each other */ -static int testRand(void); -static void dumpHex(u8 * buf, unsigned count); - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Self test using known test vectors and random inputs */ -int sflc_sk_selftest(void) -{ - int err; - - /* Test encryption */ - err = testEncdec(true); - if (err) { - pr_err("Error in encryption test: %d\n", err); - return err; - } - - /* Test decryption */ - err = testEncdec(false); - if (err) { - pr_err("Error in decryption test: %d\n", err); - return err; - } - - /* Test with random inputs */ - err = testRand(); - if (err) { - pr_err("Error in random test: %d\n", err); - return err; - } - - pr_info("All good in crypto symkey selftest\n"); - return 0; -} - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Test encryption or decryption with known test vectors */ -static int testEncdec(bool encrypt) -{ - sflc_sk_Context * ctx[2]; - u8 scratchpad[32]; - u8 key[2][32] = KEYS; - u8 iv[2][16] = IVS; - u8 pt[2][32] = PLAINTEXTS; - u8 ct[2][32] = CIPHERTEXTS; - int err; - - int i; - for (i = 0; i < 2; i++) { - memset(scratchpad, 0xa7, 32); - - ctx[i] = sflc_sk_createContext(key[i]); - if (IS_ERR(ctx)) { - err = PTR_ERR(ctx[i]); - pr_err("Could not create sk context; error %d\n", err); - return err; - } - - if (encrypt) { - err = sflc_sk_encrypt(ctx[i], pt[i], scratchpad, 32, iv[i]); - if (err) { - pr_err("Failure during encryption %d; error %d\n", i, err); - sflc_sk_destroyContext(ctx[i]); - return err; - } - if(memcmp(scratchpad, ct[i], 32) != 0) { - pr_err("Mismatch for encryption %d\n", i); - dumpHex(scratchpad, 16); - sflc_sk_destroyContext(ctx[i]); - return -EINVAL; - } - } - else /* decrypt*/ { - err = sflc_sk_decrypt(ctx[i], ct[i], scratchpad, 32, iv[i]); - if (err) { - pr_err("Failure during decryption %d; error %d\n", i, err); - sflc_sk_destroyContext(ctx[i]); - return err; - } - if (memcmp(scratchpad, pt[i], 32) != 0) { - pr_err("Mismatch for decryption %d\n", i); - dumpHex(scratchpad, 32); - sflc_sk_destroyContext(ctx[i]); - return -EINVAL; - } - } - - sflc_sk_destroyContext(ctx[i]); - } - - return 0; -} - -/* Test that encryption and decryption invert each other */ -static int testRand(void) -{ - u8 pt[48]; - u8 scratchpad[48]; - u8 key[32]; - u8 iv[16]; - sflc_sk_Context * ctx; - int err; - - get_random_bytes(key, 32); - ctx = sflc_sk_createContext(key); - if (IS_ERR(ctx)) { - err = PTR_ERR(ctx); - pr_err("Could not create context; error %d\n", err); - return err; - } - memset(iv, 0, 16); - - int i; - for (i = 0; i < 200; i++) { - get_random_bytes(pt, 48); - err = sflc_sk_encrypt(ctx, pt, scratchpad, 48, iv); - if (err) { - pr_err("Could not encrypt; error %d\n", err); - sflc_sk_destroyContext(ctx); - return err; - } - if (memcmp(pt, scratchpad, 48) == 0) { - pr_err("Random iteration %d; pt=scratchpad\n", i); - sflc_sk_destroyContext(ctx); - return -EINVAL; - } - - /* Reset IV */ - iv[15] = 0; - - err = sflc_sk_decrypt(ctx, scratchpad, scratchpad, 48, iv); - if (err) { - pr_err("Could not decrypt; error %d\n", err); - sflc_sk_destroyContext(ctx); - return err; - } - if (memcmp(pt, scratchpad, 48) != 0) { - pr_err("Random iteration %d; mismatch. Dumping plaintext and scratchpad\n", i); - dumpHex(pt, 48); - dumpHex(scratchpad, 48); - sflc_sk_destroyContext(ctx); - return -EINVAL; - } - - /* Reset IV */ - iv[15] = 0; - } - - sflc_sk_destroyContext(ctx); - return 0; -} - -static void dumpHex(u8 * buf, unsigned count) -{ - char * hex; - - hex = kmalloc(6*count + 1, GFP_KERNEL); - if (!hex) { - pr_err("Could not allocate hex dump string\n"); - return; - } - - int i; - for (i = 0; i < count; i++) { - sprintf(hex+6*i, "0x%02X, ", buf[i]); - } - - pr_notice("---- Hex dump ----\n"); - pr_notice("%s", hex); - pr_notice("---- End of hex dump ----\n"); - - kfree(hex); - return; -} diff --git a/dm-sflc/dev_vol.c b/dm-sflc/dev_vol.c new file mode 100644 index 0000000..422831f --- /dev/null +++ b/dm-sflc/dev_vol.c @@ -0,0 +1,185 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "sflc.h" +#include "old/sflc_old.h" + + +/* Create a sflc_device containing the appropriate mode-specific struct */ +struct sflc_device *sflc_dev_create(struct dm_target *ti, int argc, char **argv) +{ + struct sflc_device *sdev; + u32 dev_id; + dev_t devt; + int mode; + int err; + + sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + if (!sdev) { + DMERR("Could not allocate device"); + return ERR_PTR(-ENOMEM); + } + + /* Parse arguments */ + if (sscanf(argv[0], "%d", &mode) != 1) { + err = -EINVAL; + goto bad_parse; + } + sscanf(argv[1], "%u", &dev_id); + err = lookup_bdev(argv[2], &devt); + if (err) { + DMERR("Could not look up block device"); + goto bad_parse; + } + + /* Assign fields */ + sdev->dev_id = dev_id; + sdev->nr_volumes = 0; + sdev->mode = mode; + format_dev_t(sdev->name, devt); + + /* Register with sysfs */ + err = sflc_sysfs_register_device(sdev); + if (err) + goto bad_sysfs; + + /* Instantiate inner device. Sysfs has to be inited by now */ + switch (mode) + { + case SFLC_MODE_LEGACY: + sdev->sfold_dev = sfold_dev_create(ti, argc, argv, &sdev->kobj); + if (IS_ERR(sdev->sfold_dev)) { + err = PTR_ERR(sdev->sfold_dev); + goto bad_inner; + } + break; + default: + DMERR("Invalid Shufflecake mode %d", mode); + err = -EINVAL; + goto bad_mode; + } + + return sdev; + + +bad_mode: +bad_inner: + sflc_sysfs_unregister_device(sdev); +bad_sysfs: +bad_parse: + kfree(sdev); + return ERR_PTR(err); +} + + +void sflc_dev_destroy(struct sflc_device *sdev) +{ + switch (sdev->mode) + { + case SFLC_MODE_LEGACY: + sfold_dev_destroy(sdev->sfold_dev); + break; + default: + DMCRIT("Destroying device with invalid Shufflecake mode %d", sdev->mode); + return; + } + + sflc_sysfs_unregister_device(sdev); + kfree(sdev); +} + +/* Create a sflc_volume containing the appropriate mode-specific struct */ +struct sflc_volume *sflc_vol_create(struct sflc_device *sdev, struct dm_target *ti, + int argc, char **argv) +{ + struct sflc_volume *svol; + u32 vol_idx; + int mode; + int err; + + svol = kzalloc(sizeof(*svol), GFP_KERNEL); + if (!svol) { + DMERR("Could not allocate volume"); + return ERR_PTR(-ENOMEM); + } + + /* Parse arguments */ + if (sscanf(argv[0], "%d", &mode) != 1) { + err = -EINVAL; + goto bad_parse; + } + sscanf(argv[3], "%u", &vol_idx); + + /* Assign fields */ + svol->mode = mode; + sprintf(svol->name, "sflc_%u_%u", sdev->dev_id, vol_idx); + + /* Register with sysfs */ + err = sflc_sysfs_register_volume(svol); + if (err) + goto bad_sysfs; + + /* Instantiate inner volume. Sysfs has to be inited by now */ + switch (mode) + { + case SFLC_MODE_LEGACY: + svol->sfold_vol = sfold_vol_create(ti, sdev->sfold_dev, argc, argv, &svol->kobj); + if (IS_ERR(svol->sfold_vol)) { + err = PTR_ERR(svol->sfold_vol); + goto bad_inner; + } + svol->tt = &sfold_target_type; + break; + default: + DMERR("Invalid Shufflecake mode %d", mode); + err = -EINVAL; + goto bad_mode; + } + + return svol; + + +bad_mode: +bad_inner: + sflc_sysfs_unregister_volume(svol); +bad_sysfs: +bad_parse: + kfree(svol); + return ERR_PTR(err); +} + +void sflc_vol_destroy(struct sflc_volume *svol) +{ + switch (svol->mode) + { + case SFLC_MODE_LEGACY: + sfold_vol_destroy(svol->sfold_vol); + break; + default: + DMCRIT("Destroying volume with invalid Shufflecake mode %d", svol->mode); + return; + } + + sflc_sysfs_unregister_volume(svol); + kfree(svol); +} diff --git a/dm-sflc/crypto/rand/rand.c b/dm-sflc/old/crypto/rand/rand.c similarity index 77% rename from dm-sflc/crypto/rand/rand.c rename to dm-sflc/old/crypto/rand/rand.c index 150a909..4981967 100644 --- a/dm-sflc/crypto/rand/rand.c +++ b/dm-sflc/old/crypto/rand/rand.c @@ -28,55 +28,55 @@ #include #include -#include "rand.h" -#include "log/log.h" +#include "old/crypto/rand/rand.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * *****************************************************/ -#define SFLC_RAND_RNG_NAME "drbg_nopr_sha256" +#define SFOLD_RAND_RNG_NAME "drbg_nopr_sha256" /***************************************************** * PRIVATE VARIABLES * *****************************************************/ -static struct mutex sflc_rand_tfm_lock; -static struct crypto_rng * sflc_rand_tfm = NULL; +static struct mutex sfold_rand_tfm_lock; +static struct crypto_rng * sfold_rand_tfm = NULL; /***************************************************** * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ /* Flexible to accommodate for both required and non-required reseeding */ -static int sflc_rand_reseed(void); +static int sfold_rand_reseed(void); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ /* Init the submodule */ -int sflc_rand_init(void) +int sfold_rand_init(void) { int err; /* Init the lock governing the SFLC RNG */ - mutex_init(&sflc_rand_tfm_lock); + mutex_init(&sfold_rand_tfm_lock); /* Allocate module-wide RNG */ - sflc_rand_tfm = crypto_alloc_rng(SFLC_RAND_RNG_NAME, CRYPTO_ALG_TYPE_RNG, 0); - if (IS_ERR(sflc_rand_tfm)) { - err = PTR_ERR(sflc_rand_tfm); - sflc_rand_tfm = NULL; - pr_err("Could not allocate RNG %s; error %d\n", SFLC_RAND_RNG_NAME, err); + sfold_rand_tfm = crypto_alloc_rng(SFOLD_RAND_RNG_NAME, CRYPTO_ALG_TYPE_RNG, 0); + if (IS_ERR(sfold_rand_tfm)) { + err = PTR_ERR(sfold_rand_tfm); + sfold_rand_tfm = NULL; + pr_err("Could not allocate RNG %s; error %d\n", SFOLD_RAND_RNG_NAME, err); return err; } /* The new RNG comes not seeded, right? */ - err = sflc_rand_reseed(); + err = sfold_rand_reseed(); if (err) { pr_err("Could not seed the RNG; error %d\n", err); - sflc_rand_exit(); + sfold_rand_exit(); return err; } @@ -84,26 +84,26 @@ int sflc_rand_init(void) } /* Get random bytes. Might sleep for re-seeding (not implemented yet), or for contention (mutex). */ -int sflc_rand_getBytes(u8 * buf, unsigned count) +int sfold_rand_getBytes(u8 * buf, unsigned count) { int ret; /* Acquire lock */ - if (mutex_lock_interruptible(&sflc_rand_tfm_lock)) { + if (mutex_lock_interruptible(&sfold_rand_tfm_lock)) { pr_err("Got error while waiting for SFLC RNG\n"); return -EINTR; } - ret = crypto_rng_get_bytes(sflc_rand_tfm, buf, count); + ret = crypto_rng_get_bytes(sfold_rand_tfm, buf, count); /* End of critical region */ - mutex_unlock(&sflc_rand_tfm_lock); + mutex_unlock(&sfold_rand_tfm_lock); return ret; } /* Get a random s32 from 0 (inclusive) to max (exclusive). Returns < 0 if error. */ -s32 sflc_rand_uniform(s32 max) +s32 sfold_rand_uniform(s32 max) { s32 rand; s32 thresh; @@ -120,7 +120,7 @@ s32 sflc_rand_uniform(s32 max) thresh = S32_MAX - (S32_MAX % max); do { /* Sample a random signed integer, then make it positive */ - int err = sflc_rand_getBytes((void *) &rand, sizeof(rand)); + int err = sfold_rand_getBytes((void *) &rand, sizeof(rand)); /* Can't make it positive if it's all 1's */ if (rand == S32_MIN) { continue; @@ -140,11 +140,11 @@ s32 sflc_rand_uniform(s32 max) } /* Tear down the submodule */ -void sflc_rand_exit(void) +void sfold_rand_exit(void) { - if (sflc_rand_tfm) { - crypto_free_rng(sflc_rand_tfm); - sflc_rand_tfm = NULL; + if (sfold_rand_tfm) { + crypto_free_rng(sfold_rand_tfm); + sfold_rand_tfm = NULL; } return; @@ -155,12 +155,12 @@ void sflc_rand_exit(void) *****************************************************/ /* Flexible to accommodate for both required and non-required reseeding */ -static int sflc_rand_reseed(void) +static int sfold_rand_reseed(void) { int err; /* Reseed the RNG */ - err = crypto_rng_reset(sflc_rand_tfm, NULL, crypto_rng_seedsize(sflc_rand_tfm)); + err = crypto_rng_reset(sfold_rand_tfm, NULL, crypto_rng_seedsize(sfold_rand_tfm)); if (err) { pr_err("Could not feed seed to the RNG; error %d\n", err); return err; diff --git a/dm-sflc/crypto/rand/rand.h b/dm-sflc/old/crypto/rand/rand.h similarity index 85% rename from dm-sflc/crypto/rand/rand.h rename to dm-sflc/old/crypto/rand/rand.h index 4d5f8a7..d7de86a 100644 --- a/dm-sflc/crypto/rand/rand.h +++ b/dm-sflc/old/crypto/rand/rand.h @@ -27,8 +27,8 @@ * no need to make it more fine grained. */ -#ifndef _SFLC_CRYPTO_RAND_RAND_H_ -#define _SFLC_CRYPTO_RAND_RAND_H_ +#ifndef _SFOLD_CRYPTO_RAND_RAND_H_ +#define _SFOLD_CRYPTO_RAND_RAND_H_ /***************************************************** * INCLUDE SECTION * @@ -40,20 +40,17 @@ * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* Selftest to see (by eye :D) if generated bytes are actually random */ -int sflc_rand_selftest(void); - /* Init the submodule */ -int sflc_rand_init(void); +int sfold_rand_init(void); /* Get random bytes. Might sleep for re-seeding (not implemented yet), or for contention (mutex). */ -int sflc_rand_getBytes(u8 * buf, unsigned count); +int sfold_rand_getBytes(u8 * buf, unsigned count); /* Get a random s32 from 0 (inclusive) to max (exclusive). Returns < 0 if error. */ -s32 sflc_rand_uniform(s32 max); +s32 sfold_rand_uniform(s32 max); /* Tear down the submodule */ -void sflc_rand_exit(void); +void sfold_rand_exit(void); -#endif /* _SFLC_CRYPTO_RAND_RAND_H_ */ +#endif /* _SFOLD_CRYPTO_RAND_RAND_H_ */ diff --git a/dm-sflc/crypto/symkey/skreq_pool.c b/dm-sflc/old/crypto/symkey/skreq_pool.c similarity index 82% rename from dm-sflc/crypto/symkey/skreq_pool.c rename to dm-sflc/old/crypto/symkey/skreq_pool.c index d77c9e1..a91fbf8 100644 --- a/dm-sflc/crypto/symkey/skreq_pool.c +++ b/dm-sflc/old/crypto/symkey/skreq_pool.c @@ -25,8 +25,8 @@ * INCLUDE SECTION * *****************************************************/ -#include "skreq_pool.h" -#include "log/log.h" +#include "old/crypto/symkey/skreq_pool.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * @@ -37,17 +37,17 @@ *****************************************************/ /* A mempool_alloc_t using skcipher_request_alloc as backend */ -static void * sflc_sk_allocRequest(gfp_t gfp_mask, void * pool_data); +static void * sfold_sk_allocRequest(gfp_t gfp_mask, void * pool_data); /* A mempool_free_t using skcipher_request_free as backend */ -static void sflc_sk_freeRequest(void * element, void * pool_data); +static void sfold_sk_freeRequest(void * element, void * pool_data); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -mempool_t * sflc_sk_createReqPool(int min_nr, sflc_sk_Context * ctx) +mempool_t * sfold_sk_createReqPool(int min_nr, sfold_sk_Context * ctx) { - return mempool_create(min_nr, sflc_sk_allocRequest, sflc_sk_freeRequest, (void *) ctx); + return mempool_create(min_nr, sfold_sk_allocRequest, sfold_sk_freeRequest, (void *) ctx); } /***************************************************** @@ -55,9 +55,9 @@ mempool_t * sflc_sk_createReqPool(int min_nr, sflc_sk_Context * ctx) *****************************************************/ /* A mempool_alloc_t using skcipher_request_alloc as backend */ -static void * sflc_sk_allocRequest(gfp_t gfp_mask, void * pool_data) +static void * sfold_sk_allocRequest(gfp_t gfp_mask, void * pool_data) { - sflc_sk_Context * ctx = pool_data; + sfold_sk_Context * ctx = pool_data; struct skcipher_request * skreq; skreq = skcipher_request_alloc(ctx->tfm, gfp_mask); @@ -70,7 +70,7 @@ static void * sflc_sk_allocRequest(gfp_t gfp_mask, void * pool_data) } /* A mempool_free_t using skcipher_request_free as backend */ -static void sflc_sk_freeRequest(void * element, void * pool_data) +static void sfold_sk_freeRequest(void * element, void * pool_data) { struct skcipher_request * skreq = element; diff --git a/dm-sflc/crypto/symkey/skreq_pool.h b/dm-sflc/old/crypto/symkey/skreq_pool.h similarity index 89% rename from dm-sflc/crypto/symkey/skreq_pool.h rename to dm-sflc/old/crypto/symkey/skreq_pool.h index cb57f53..5c5ebba 100644 --- a/dm-sflc/crypto/symkey/skreq_pool.h +++ b/dm-sflc/old/crypto/symkey/skreq_pool.h @@ -26,8 +26,8 @@ * functions to the mempool interface. */ -#ifndef _SFLC_CRYPTO_SYMKEY_SKREQ_POOL_H_ -#define _SFLC_CRYPTO_SYMKEY_SKREQ_POOL_H_ +#ifndef _SFOLD_CRYPTO_SYMKEY_SKREQ_POOL_H_ +#define _SFOLD_CRYPTO_SYMKEY_SKREQ_POOL_H_ /***************************************************** * INCLUDE SECTION * @@ -35,7 +35,7 @@ #include -#include "symkey.h" +#include "old/crypto/symkey/symkey.h" /***************************************************** * CONSTANTS * @@ -49,7 +49,7 @@ * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -mempool_t * sflc_sk_createReqPool(int min_nr, sflc_sk_Context * ctx); +mempool_t * sfold_sk_createReqPool(int min_nr, sfold_sk_Context * ctx); -#endif /* _SFLC_CRYPTO_SYMKEY_SKREQ_POOL_H_ */ +#endif /* _SFOLD_CRYPTO_SYMKEY_SKREQ_POOL_H_ */ diff --git a/dm-sflc/crypto/symkey/symkey.c b/dm-sflc/old/crypto/symkey/symkey.c similarity index 75% rename from dm-sflc/crypto/symkey/symkey.c rename to dm-sflc/old/crypto/symkey/symkey.c index 2a78085..668e1ec 100644 --- a/dm-sflc/crypto/symkey/symkey.c +++ b/dm-sflc/old/crypto/symkey/symkey.c @@ -27,66 +27,66 @@ #include -#include "symkey.h" -#include "skreq_pool.h" -#include "log/log.h" +#include "old/crypto/symkey/symkey.h" +#include "old/crypto/symkey/skreq_pool.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * *****************************************************/ -#define SFLC_SK_REQ_POOL_SIZE 1024 +#define SFOLD_SK_REQ_POOL_SIZE 1024 -#define SFLC_SK_ENCRYPT 0 -#define SFLC_SK_DECRYPT 1 +#define SFOLD_SK_ENCRYPT 0 +#define SFOLD_SK_DECRYPT 1 /***************************************************** * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -static int sflc_sk_encdec(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv, int op); +static int sfold_sk_encdec(sfold_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv, int op); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ /* Create a new context with the given key. Returns an ERR_PTR() on failure. */ -sflc_sk_Context * sflc_sk_createContext(u8 * key) +sfold_sk_Context * sfold_sk_createContext(u8 * key) { - sflc_sk_Context * ctx; + sfold_sk_Context * ctx; int err; /* Allocate context */ - ctx = kzalloc(sizeof(sflc_sk_Context), GFP_KERNEL); + ctx = kzalloc(sizeof(sfold_sk_Context), GFP_KERNEL); if (!ctx) { - pr_err("Could not allocate %lu bytes for the sflc_sk_Context\n", sizeof(sflc_sk_Context)); + pr_err("Could not allocate %lu bytes for the sfold_sk_Context\n", sizeof(sfold_sk_Context)); return ERR_PTR(-ENOMEM); } /* Allocate crypto transform */ - ctx->tfm = crypto_alloc_skcipher(SFLC_SK_CIPHER_NAME, CRYPTO_ALG_ASYNC, 0); + ctx->tfm = crypto_alloc_skcipher(SFOLD_SK_CIPHER_NAME, CRYPTO_ALG_ASYNC, 0); if (IS_ERR(ctx->tfm)) { err = PTR_ERR(ctx->tfm); ctx->tfm = NULL; pr_err("Could not allocate skcipher handle: error %d\n", err); - sflc_sk_destroyContext(ctx); + sfold_sk_destroyContext(ctx); return ERR_PTR(err); } /* Copy and set key */ - memcpy(ctx->key, key, SFLC_SK_KEY_LEN); - err = crypto_skcipher_setkey(ctx->tfm, ctx->key, SFLC_SK_KEY_LEN); + memcpy(ctx->key, key, SFOLD_SK_KEY_LEN); + err = crypto_skcipher_setkey(ctx->tfm, ctx->key, SFOLD_SK_KEY_LEN); if (err) { pr_err("Could not set key in crypto transform: error %d\n", err); - sflc_sk_destroyContext(ctx); + sfold_sk_destroyContext(ctx); return ERR_PTR(err); } /* Create request memory pool */ - ctx->sk_req_pool = sflc_sk_createReqPool(SFLC_SK_REQ_POOL_SIZE, ctx); + ctx->sk_req_pool = sfold_sk_createReqPool(SFOLD_SK_REQ_POOL_SIZE, ctx); if (!ctx->sk_req_pool) { pr_err("Could not allocate skcipher_request memory pool\n"); - sflc_sk_destroyContext(ctx); + sfold_sk_destroyContext(ctx); return ERR_PTR(-ENOMEM); } @@ -94,7 +94,7 @@ sflc_sk_Context * sflc_sk_createContext(u8 * key) } /* Destroy the given context */ -void sflc_sk_destroyContext(sflc_sk_Context * ctx) +void sfold_sk_destroyContext(sfold_sk_Context * ctx) { if (!ctx) { return; @@ -116,21 +116,21 @@ void sflc_sk_destroyContext(sflc_sk_Context * ctx) } /* Encrypt synchronously. Provide src = dst for in-place operation. */ -int sflc_sk_encrypt(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv) +int sfold_sk_encrypt(sfold_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv) { - return sflc_sk_encdec(ctx, src, dst, len, iv, SFLC_SK_ENCRYPT); + return sfold_sk_encdec(ctx, src, dst, len, iv, SFOLD_SK_ENCRYPT); } -int sflc_sk_decrypt(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv) +int sfold_sk_decrypt(sfold_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv) { - return sflc_sk_encdec(ctx, src, dst, len, iv, SFLC_SK_DECRYPT); + return sfold_sk_encdec(ctx, src, dst, len, iv, SFOLD_SK_DECRYPT); } /***************************************************** * PRIVATE FUNCTIONS DEFINITIONS * *****************************************************/ -static int sflc_sk_encdec(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv, int op) +static int sfold_sk_encdec(sfold_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv, int op) { struct skcipher_request * skreq; struct scatterlist srcsg; @@ -162,7 +162,7 @@ static int sflc_sk_encdec(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned in crypto_req_done, &skreq_wait); /* Do it */ - if (op == SFLC_SK_ENCRYPT) { + if (op == SFOLD_SK_ENCRYPT) { ret = crypto_skcipher_encrypt(skreq); } else { ret = crypto_skcipher_decrypt(skreq); diff --git a/dm-sflc/crypto/symkey/symkey.h b/dm-sflc/old/crypto/symkey/symkey.h similarity index 78% rename from dm-sflc/crypto/symkey/symkey.h rename to dm-sflc/old/crypto/symkey/symkey.h index 1b6d40b..3f4d440 100644 --- a/dm-sflc/crypto/symkey/symkey.h +++ b/dm-sflc/old/crypto/symkey/symkey.h @@ -25,8 +25,8 @@ * A thin wrapper around the kernel's synchronous block cipher API. */ -#ifndef _SFLC_CRYPTO_SYMKEY_SYMKEY_H_ -#define _SFLC_CRYPTO_SYMKEY_SYMKEY_H_ +#ifndef _SFOLD_CRYPTO_SYMKEY_SYMKEY_H_ +#define _SFOLD_CRYPTO_SYMKEY_SYMKEY_H_ /***************************************************** * INCLUDE SECTION * @@ -39,9 +39,9 @@ * CONSTANTS * *****************************************************/ -#define SFLC_SK_CIPHER_NAME "ctr(aes)" -#define SFLC_SK_KEY_LEN 32 -#define SFLC_SK_IV_LEN 16 +#define SFOLD_SK_CIPHER_NAME "ctr(aes)" +#define SFOLD_SK_KEY_LEN 32 +#define SFOLD_SK_IV_LEN 16 /***************************************************** * TYPES * @@ -51,34 +51,31 @@ * There is one of these Context's for each volume. * No need for locking, methods can be called in parallel. */ -typedef struct sflc_sk_context_s +typedef struct sfold_sk_context_s { /* Only one transform for now */ struct crypto_skcipher * tfm; /* 32-byte key */ - u8 key[SFLC_SK_KEY_LEN]; + u8 key[SFOLD_SK_KEY_LEN]; /* Memory pool for skcipher_request's */ mempool_t * sk_req_pool; -} sflc_sk_Context; +} sfold_sk_Context; /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* Self test using known test vectors and random inputs */ -int sflc_sk_selftest(void); - /* Create a new context with the given key. Returns an ERR_PTR() on failure. */ -sflc_sk_Context * sflc_sk_createContext(u8 * key); +sfold_sk_Context * sfold_sk_createContext(u8 * key); /* Destroy the given context */ -void sflc_sk_destroyContext(sflc_sk_Context * ctx); +void sfold_sk_destroyContext(sfold_sk_Context * ctx); /* Encrypt/decrypt synchronously. Provide src = dst for in-place operation. */ -int sflc_sk_encrypt(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv); -int sflc_sk_decrypt(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv); +int sfold_sk_encrypt(sfold_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv); +int sfold_sk_decrypt(sfold_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv); -#endif /* _SFLC_CRYPTO_SYMKEY_SYMKEY_H_ */ +#endif /* _SFOLD_CRYPTO_SYMKEY_SYMKEY_H_ */ diff --git a/dm-sflc/device/device.c b/dm-sflc/old/device/device.c similarity index 53% rename from dm-sflc/device/device.c rename to dm-sflc/old/device/device.c index 4356626..1795575 100644 --- a/dm-sflc/device/device.c +++ b/dm-sflc/old/device/device.c @@ -29,10 +29,10 @@ * INCLUDE SECTION * *****************************************************/ -#include "device.h" -#include "sysfs/sysfs.h" -#include "utils/vector.h" -#include "log/log.h" +#include "old/sflc_old.h" +#include "old/device/device.h" +#include "old/utils/vector.h" +#include "old/log/log.h" #include @@ -44,106 +44,73 @@ * PUBLIC VARIABLES DEFINITIONS * *****************************************************/ -/* The next available device ID */ -size_t sflc_dev_nextId; - -LIST_HEAD(sflc_dev_list); -DEFINE_SEMAPHORE(sflc_dev_mutex); - - -/***************************************************** - * PRIVATE VARIABLES * - *****************************************************/ - -/* Array tracking occupation of device IDs */ -static bool *sflc_dev_occupiedIds; - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Acquire device ID, returns false if not possible */ -static bool sflc_dev_acquireId(size_t id); - -/* Release device ID */ -static void sflc_dev_releaseId(size_t id); /* Initialises and pre-shuffles the PSI array */ -static int sflc_dev_initAndShufflePsiArray(u32 *psi_array, u32 len); +static int sfold_dev_initAndShufflePsiArray(u32 *psi_array, u32 len); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -/* Inits global variables */ -int sflc_dev_init(void) +/** + * Creates Device and adds it to the list. Returns an ERR_PTR() if unsuccessful. + * Arguments: + * argv[0]: Shufflecake mode: legacy/lite + * argv[1]: Shufflecake-unique device ID + * argv[2]: path to underlying physical device + * argv[3]: volume index within the device + * argv[4]: number of 1 MB slices in the underlying device + * argv[5]: 32-byte encryption key (hex-encoded) + */ +sfold_Device *sfold_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj) { - /* Allocate occupation array */ - sflc_dev_occupiedIds = kzalloc(SFLC_DEV_MAX_DEVICES_TOT, GFP_KERNEL); - if (!sflc_dev_occupiedIds) { - pr_err("Could not allocate array to track deviceID occupation"); - return -ENOMEM; - } - - /* First available ID is 0 */ - sflc_dev_nextId = 0; - - return 0; -} - -/* Tears down global variables */ -void sflc_dev_exit(void) -{ - kfree(sflc_dev_occupiedIds); -} - -/* Creates Device and adds it to the list. Returns an ERR_PTR() if unsuccessful. */ -sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 tot_slices) -{ - sflc_Device * dev; + sfold_Device * dev; + u32 tot_slices; + u32 dev_id; int err; int i; - pr_debug("Called to create sflc_Device on %s\n", real_dev_path); - /* Allocate device */ - dev = kzalloc(sizeof(sflc_Device), GFP_KERNEL); + dev = kzalloc(sizeof(sfold_Device), GFP_KERNEL); if (!dev) { - pr_err("Could not allocate %lu bytes for sflc_Device\n", sizeof(sflc_Device)); + pr_err("Could not allocate %lu bytes for sfold_Device\n", sizeof(sfold_Device)); err = -ENOMEM; goto err_alloc_dev; } + /* Parse args */ + sscanf(argv[1], "%u", &dev_id); + if (sscanf(argv[4], "%u", &tot_slices) != 1) { + pr_err("Could not decode tot_slices\n"); + err = -EINVAL; + goto err_parse; + } + /* Init list node here, so it's always safe to list_del() */ INIT_LIST_HEAD(&dev->list_node); /* Set device ID */ - dev->dev_id = sflc_dev_nextId; - if (!sflc_dev_acquireId(sflc_dev_nextId)) { - pr_err("Could not create Device: max number of open devices reached"); - err = -EINVAL; - goto err_dev_id; - } + dev->dev_id = dev_id; /* Set backing real device */ - err = dm_get_device(ti, real_dev_path, dm_table_get_mode(ti->table), &dev->bdev); + err = dm_get_device(ti, argv[2], dm_table_get_mode(ti->table), &dev->bdev); if (err) { pr_err("Could not dm_get_device: error %d\n", err); goto err_dm_get_dev; } + dev->ti = ti; /* And its path */ - dev->bdev_path = kmalloc(strlen(real_dev_path) + 1, GFP_KERNEL); + dev->bdev_path = kmalloc(strlen(argv[2]) + 1, GFP_KERNEL); if (!dev->bdev_path) { - pr_err("Could not allocate %lu bytes for dev->real_dev_path\n", strlen(real_dev_path) + 1); + pr_err("Could not allocate %lu bytes for dev->real_dev_path\n", strlen(argv[2]) + 1); err = -ENOMEM; goto err_alloc_real_dev_path; } - strcpy(dev->bdev_path, real_dev_path); + strcpy(dev->bdev_path, argv[2]); /* Init volumes */ - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; ++i) { + for (i = 0; i < SFOLD_DEV_MAX_VOLUMES; ++i) { dev->vol[i] = NULL; } dev->vol_cnt = 0; @@ -152,10 +119,10 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t dev->tot_slices = tot_slices; dev->free_slices = tot_slices; /* Compute header info (like in userland tool) */ - u32 nr_pmbs_per_vol = DIV_ROUND_UP(tot_slices, SFLC_VOL_HEADER_MAPPINGS_PER_BLOCK); - dev->vol_header_nr_iv_blocks = DIV_ROUND_UP(nr_pmbs_per_vol, SFLC_VOL_LOG_SLICE_SIZE); + u32 nr_pmbs_per_vol = DIV_ROUND_UP(tot_slices, SFOLD_VOL_HEADER_MAPPINGS_PER_BLOCK); + dev->vol_header_nr_iv_blocks = DIV_ROUND_UP(nr_pmbs_per_vol, SFOLD_VOL_LOG_SLICE_SIZE); dev->vol_header_size = 1 + nr_pmbs_per_vol + dev->vol_header_nr_iv_blocks; - dev->dev_header_size = 1 + (SFLC_DEV_MAX_VOLUMES * dev->vol_header_size); + dev->dev_header_size = 1 + (SFOLD_DEV_MAX_VOLUMES * dev->vol_header_size); /* Init slices lock */ mutex_init(&dev->slices_lock); @@ -167,7 +134,7 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t goto err_alloc_rmap; } /* Initialise it */ - memset(dev->rmap, SFLC_DEV_RMAP_INVALID_VOL, dev->tot_slices * sizeof(u8)); + memset(dev->rmap, SFOLD_DEV_RMAP_INVALID_VOL, dev->tot_slices * sizeof(u8)); /* Allocate PSI array */ dev->shuffled_psi_array = vmalloc(dev->tot_slices * sizeof(u32)); if (!dev->shuffled_psi_array) { @@ -176,7 +143,7 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t goto err_alloc_psi_array; } /* Initialise it and pre-shuffle it */ - err = sflc_dev_initAndShufflePsiArray(dev->shuffled_psi_array, dev->tot_slices); + err = sfold_dev_initAndShufflePsiArray(dev->shuffled_psi_array, dev->tot_slices); if (err) { pr_err("Could not init-and-shuffle PSI array: error %d", err); goto err_initshuffle_psi_array; @@ -189,7 +156,7 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t /* Init IV cache waitqueue */ init_waitqueue_head(&dev->iv_cache_waitqueue); /* Allocate IV cache */ - dev->iv_cache = kzalloc(dev->tot_slices * sizeof(sflc_dev_IvCacheEntry *), GFP_KERNEL); + dev->iv_cache = kzalloc(dev->tot_slices * sizeof(sfold_dev_IvCacheEntry *), GFP_KERNEL); if (!dev->iv_cache) { pr_err("Could not allocate IV cache\n"); err = -ENOMEM; @@ -200,17 +167,14 @@ sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 t /* Init list head */ INIT_LIST_HEAD(&dev->iv_lru_list); - /* Create kobject */ - dev->kobj = sflc_sysfs_devCreateAndAdd(dev); - if (IS_ERR(dev->kobj)) { - err = PTR_ERR(dev->kobj); - pr_err("Could not create kobject; error %d\n", err); + /* Add to sysfs */ + dev->kobj_parent = kobj; + err = sfold_sysfs_add_device(dev); + if (err) { + pr_err("Could not add device to sysfs; error %d\n", err); goto err_sysfs; } - /* Add to device list */ - list_add_tail(&dev->list_node, &sflc_dev_list); - return dev; @@ -226,30 +190,15 @@ err_alloc_rmap: err_alloc_real_dev_path: dm_put_device(ti, dev->bdev); err_dm_get_dev: - sflc_dev_releaseId(dev->dev_id); -err_dev_id: +err_parse: kfree(dev); err_alloc_dev: return ERR_PTR(err); } -/* Returns NULL if not found */ -sflc_Device * sflc_dev_lookupByPath(char * real_dev_path) -{ - sflc_Device * dev; - - /* Sweep the list of devices */ - list_for_each_entry(dev, &sflc_dev_list, list_node) { - if (strcmp(real_dev_path, dev->bdev_path) == 0) { - return dev; - } - } - - return NULL; -} /* Returns false if still busy (not all volumes have been removed). Frees the Device. */ -bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev) +bool sfold_dev_destroy(sfold_Device * dev) { /* Check if we actually have to put this device */ if (!dev) { @@ -261,13 +210,13 @@ bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev) } /* Flush all IVs */ - sflc_dev_flushIvs(dev); + sfold_dev_flushIvs(dev); /* List */ list_del(&dev->list_node); /* Sysfs */ - sflc_sysfs_putDev(dev->kobj); + sfold_sysfs_remove_device(dev); /* IV cache */ kfree(dev->iv_cache); @@ -279,12 +228,9 @@ bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev) vfree(dev->rmap); /* Backing device */ - dm_put_device(ti, dev->bdev); + dm_put_device(dev->ti, dev->bdev); kfree(dev->bdev_path); - /* Release device ID */ - sflc_dev_releaseId(dev->dev_id); - /* Free the device itself */ kfree(dev); @@ -292,57 +238,8 @@ bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev) } -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Acquire device ID, returns false if not possible */ -static bool sflc_dev_acquireId(size_t id) -{ - /* Sanity check */ - if (id >= SFLC_DEV_MAX_DEVICES_TOT) { - return false; - } - /* Check occupation */ - if (sflc_dev_occupiedIds[id]) { - return false; - } - - /* Mark as occupied */ - sflc_dev_occupiedIds[id] = true; - - /* Update the nextId if necessary */ - if (id == sflc_dev_nextId) { - /* Jump to the next unoccupied ID */ - for (; id < SFLC_DEV_MAX_DEVICES_TOT && sflc_dev_occupiedIds[id]; id++); - sflc_dev_nextId = id; - } - - return true; -} - -/* Release volume ID */ -static void sflc_dev_releaseId(size_t id) -{ - /* Sanity check */ - if (id >= SFLC_DEV_MAX_DEVICES_TOT) { - return; - } - - /* Mark as unoccupied */ - sflc_dev_occupiedIds[id] = false; - - /* Update the nextId if necessary */ - if (id < sflc_dev_nextId) { - sflc_dev_nextId = id; - } - - return; -} - - /* Initialises and pre-shuffles the PSI array */ -static int sflc_dev_initAndShufflePsiArray(u32 *psi_array, u32 len) +static int sfold_dev_initAndShufflePsiArray(u32 *psi_array, u32 len) { u32 i; @@ -352,6 +249,6 @@ static int sflc_dev_initAndShufflePsiArray(u32 *psi_array, u32 len) } /* Permute */ - return sflc_vec_u32shuffle(psi_array, len); + return sfold_vec_u32shuffle(psi_array, len); } diff --git a/dm-sflc/device/device.h b/dm-sflc/old/device/device.h similarity index 71% rename from dm-sflc/device/device.h rename to dm-sflc/old/device/device.h index cc8b0a0..f893772 100644 --- a/dm-sflc/device/device.h +++ b/dm-sflc/old/device/device.h @@ -30,8 +30,8 @@ * are stored in increasing degree of "secrecy"). */ -#ifndef _SFLC_DEVICE_DEVICE_H_ -#define _SFLC_DEVICE_DEVICE_H_ +#ifndef _SFOLD_DEVICE_DEVICE_H_ +#define _SFOLD_DEVICE_DEVICE_H_ /***************************************************** @@ -40,8 +40,8 @@ /* Necessary since device.h, volume.h, and sysfs.h all include each other */ -typedef struct sflc_device_s sflc_Device; -typedef struct sflc_dev_iv_cache_entry_s sflc_dev_IvCacheEntry; +typedef struct sfold_device_s sfold_Device; +typedef struct sfold_dev_iv_cache_entry_s sfold_dev_IvCacheEntry; /***************************************************** @@ -50,9 +50,9 @@ typedef struct sflc_dev_iv_cache_entry_s sflc_dev_IvCacheEntry; #include -#include "volume/volume.h" -#include "crypto/symkey/symkey.h" -#include "sysfs/sysfs.h" +#include "old/sflc_old.h" +#include "old/volume/volume.h" +#include "old/crypto/symkey/symkey.h" /***************************************************** @@ -60,30 +60,30 @@ typedef struct sflc_dev_iv_cache_entry_s sflc_dev_IvCacheEntry; *****************************************************/ /* We need 4096-byte sectors to amortise the space overhead of the IVs */ -#define SFLC_DEV_SECTOR_SIZE 4096 +#define SFOLD_DEV_SECTOR_SIZE 4096 /* A SFLC sector encompasses 8 kernel sectors */ -#define SFLC_DEV_SECTOR_SCALE (SFLC_DEV_SECTOR_SIZE / SECTOR_SIZE) +#define SFOLD_DEV_SECTOR_SCALE (SFOLD_DEV_SECTOR_SIZE / SECTOR_SIZE) /* An IV block holds IVs for 256 data blocks */ -#define SFLC_DEV_SECTOR_TO_IV_RATIO (SFLC_DEV_SECTOR_SIZE / SFLC_SK_IV_LEN) +#define SFOLD_DEV_SECTOR_TO_IV_RATIO (SFOLD_DEV_SECTOR_SIZE / SFOLD_SK_IV_LEN) /* Max number of volumes linked to a single device */ -#define SFLC_DEV_MAX_VOLUMES 15 +#define SFOLD_DEV_MAX_VOLUMES 15 /* A physical slice contains the 256 encrypted data blocks and the IV block */ -#define SFLC_DEV_PHYS_SLICE_SIZE (SFLC_VOL_LOG_SLICE_SIZE + (SFLC_VOL_LOG_SLICE_SIZE / SFLC_DEV_SECTOR_TO_IV_RATIO)) +#define SFOLD_DEV_PHYS_SLICE_SIZE (SFOLD_VOL_LOG_SLICE_SIZE + (SFOLD_VOL_LOG_SLICE_SIZE / SFOLD_DEV_SECTOR_TO_IV_RATIO)) /* Value marking a PSI as unassigned */ -#define SFLC_DEV_RMAP_INVALID_VOL 0xFFU +#define SFOLD_DEV_RMAP_INVALID_VOL 0xFFU /* Maximum number of open devices in total across shufflecake */ -#define SFLC_DEV_MAX_DEVICES_TOT 1024 +#define SFOLD_DEV_MAX_DEVICES_TOT 1024 /***************************************************** * TYPES * *****************************************************/ -struct sflc_dev_iv_cache_entry_s +struct sfold_dev_iv_cache_entry_s { /* The PSI it refers to */ u32 psi; @@ -99,16 +99,18 @@ struct sflc_dev_iv_cache_entry_s struct list_head lru_node; }; -struct sflc_device_s +struct sfold_device_s { /* Underlying block device */ struct dm_dev * bdev; char * bdev_path; + /* Target instance that owns the bdev reference */ + struct dm_target *ti; /* Shufflecake-unique numeric ID of this device */ - size_t dev_id; + u32 dev_id; /* All volumes linked to this device */ - sflc_Volume * vol[SFLC_DEV_MAX_VOLUMES]; + sfold_Volume * vol[SFOLD_DEV_MAX_VOLUMES]; int vol_cnt; /* Reverse slice map, associating PSIs to volume indices */ @@ -128,82 +130,57 @@ struct sflc_device_s u32 vol_header_size; u32 dev_header_size; + /* Parent sysfs directory */ + struct kobject *kobj_parent; + /* LRU cache of IV blocks */ struct mutex iv_cache_lock; wait_queue_head_t iv_cache_waitqueue; - sflc_dev_IvCacheEntry ** iv_cache; + sfold_dev_IvCacheEntry ** iv_cache; u32 iv_cache_nr_entries; struct list_head iv_lru_list; - /* Sysfs stuff */ - sflc_sysfs_Device * kobj; - /* We keep all devices in a list */ struct list_head list_node; }; -/***************************************************** - * PUBLIC VARIABLES DECLARATIONS * - *****************************************************/ - -/* The next available device ID */ -extern size_t sflc_dev_nextId; - -/* List of all devices */ -extern struct list_head sflc_dev_list; -/* Big, coarse-grained lock for all modifying operations on any device or the device list */ -extern struct semaphore sflc_dev_mutex; - - /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ - -/* Inits global variables */ -int sflc_dev_init(void); -/* Tears down global variables */ -void sflc_dev_exit(void); - /* * None of these functions acquire the big device lock: it must be held * by the caller. */ /* Creates Device and adds it to the list. Returns an ERR_PTR() if unsuccessful. */ -sflc_Device * sflc_dev_create(struct dm_target * ti, char * real_dev_path, u32 tot_slices); - -/* Returns NULL if not found */ -sflc_Device * sflc_dev_lookupByPath(char * real_dev_path); +sfold_Device * sfold_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj); /* Returns false if still busy (not all volumes have been removed) Frees the Device. */ -bool sflc_dev_destroy(struct dm_target * ti, sflc_Device * dev); +bool sfold_dev_destroy(sfold_Device * dev); /* Returns false if volume index was already occupied. */ -bool sflc_dev_addVolume(sflc_Device * dev, sflc_Volume * vol, int vol_idx); - -/* Looks at all volumes in all devices. Returns NULL if not found */ -sflc_Volume * sflc_dev_lookupVolumeByName(char * vol_name); +bool sfold_dev_addVolume(sfold_Device * dev, sfold_Volume * vol, int vol_idx); /* Does not put the volume. Returns false if was already NULL. */ -bool sflc_dev_removeVolume(sflc_Device * dev, int vol_idx); +bool sfold_dev_removeVolume(sfold_Device * dev, int vol_idx); /* Synchronously reads/writes one 4096-byte sector from/to the underlying device to/from the provided page */ -int sflc_dev_rwSector(sflc_Device * dev, struct page * page, sector_t sector, int rw); +int sfold_dev_rwSector(sfold_Device * dev, struct page * page, sector_t sector, int rw); /* The caller needs to hold slices_lock to call these functions */ /* Sets the PSI as owned by the given volume (also decreases free_slices). * Returns < 0 if already taken. */ -int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx); +int sfold_dev_markPsiTaken(sfold_Device * dev, u32 psi, u8 vol_idx); /* Returns a random free physical slice, or < 0 if error */ -s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev); +s32 sfold_dev_getNextRandomFreePsi(sfold_Device * dev); /* These functions provide concurrent-safe access to the entries of the IV cache. @@ -214,13 +191,13 @@ s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev); When the refcount reaches 0, the IV block is flushed. */ /* Get a pointer to the specified IV block. Increases the refcount and possibly the dirtyness (if WRITE). */ -u8 * sflc_dev_getIvBlockRef(sflc_Device * dev, u32 psi, int rw); +u8 * sfold_dev_getIvBlockRef(sfold_Device * dev, u32 psi, int rw); /* Signal end of usage of an IV block. Decreases the refcount. */ -int sflc_dev_putIvBlockRef(sflc_Device * dev, u32 psi); +int sfold_dev_putIvBlockRef(sfold_Device * dev, u32 psi); /* Flush all dirty IV blocks */ -void sflc_dev_flushIvs(sflc_Device * dev); +void sfold_dev_flushIvs(sfold_Device * dev); -#endif /* _SFLC_DEVICE_DEVICE_H_ */ +#endif /* _SFOLD_DEVICE_DEVICE_H_ */ diff --git a/dm-sflc/device/iv.c b/dm-sflc/old/device/iv.c similarity index 82% rename from dm-sflc/device/iv.c rename to dm-sflc/old/device/iv.c index ad1b3b5..c2c0fb1 100644 --- a/dm-sflc/device/iv.c +++ b/dm-sflc/old/device/iv.c @@ -25,29 +25,30 @@ * INCLUDE SECTION * *****************************************************/ -#include "device.h" -#include "utils/pools.h" -#include "log/log.h" + +#include "old/device/device.h" +#include "old/utils/pools.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * *****************************************************/ /* Capacity of IV cache */ -#define SFLC_DEV_IV_CACHE_CAPACITY 1024 +#define SFOLD_DEV_IV_CACHE_CAPACITY 1024 /***************************************************** * MACROS * *****************************************************/ -#define sflc_dev_psiToIvBlockSector(dev, psi) (dev->dev_header_size + (sector_t)(psi) * SFLC_DEV_PHYS_SLICE_SIZE) +#define sfold_dev_psiToIvBlockSector(dev, psi) (dev->dev_header_size + (sector_t)(psi) * SFOLD_DEV_PHYS_SLICE_SIZE) /***************************************************** * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -static sflc_dev_IvCacheEntry * sflc_dev_newIvCacheEntry(sflc_Device * dev, u32 psi); -static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry * entry); +static sfold_dev_IvCacheEntry * sfold_dev_newIvCacheEntry(sfold_Device * dev, u32 psi); +static int sfold_dev_destroyIvCacheEntry(sfold_Device * dev, sfold_dev_IvCacheEntry * entry); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * @@ -55,9 +56,9 @@ static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry /* Get a read/write pointer to the specified IV block. Increases the refcount. Returns an ERR_PTR() if error. */ -u8 * sflc_dev_getIvBlockRef(sflc_Device * dev, u32 psi, int rw) +u8 * sfold_dev_getIvBlockRef(sfold_Device * dev, u32 psi, int rw) { - sflc_dev_IvCacheEntry * entry; + sfold_dev_IvCacheEntry * entry; int err; /* Lock + waitqueue pattern */ @@ -70,13 +71,13 @@ u8 * sflc_dev_getIvBlockRef(sflc_Device * dev, u32 psi, int rw) } /* Check for either of two conditions in order to go through */ - while (dev->iv_cache[psi] == NULL && dev->iv_cache_nr_entries >= SFLC_DEV_IV_CACHE_CAPACITY) { + while (dev->iv_cache[psi] == NULL && dev->iv_cache_nr_entries >= SFOLD_DEV_IV_CACHE_CAPACITY) { /* We can't go through, yield the lock */ mutex_unlock(&dev->iv_cache_lock); /* Sleep in the waitqueue (same conditions) */ if (wait_event_interruptible(dev->iv_cache_waitqueue, dev->iv_cache[psi] != NULL || - dev->iv_cache_nr_entries < SFLC_DEV_IV_CACHE_CAPACITY)) { + dev->iv_cache_nr_entries < SFOLD_DEV_IV_CACHE_CAPACITY)) { err = -EINTR; pr_err("Interrupted while waiting in waitqueue\n"); goto err_wait_queue; @@ -98,7 +99,7 @@ u8 * sflc_dev_getIvBlockRef(sflc_Device * dev, u32 psi, int rw) entry = dev->iv_cache[psi]; if (!entry) { /* Create it */ - entry = sflc_dev_newIvCacheEntry(dev, psi); + entry = sfold_dev_newIvCacheEntry(dev, psi); if (IS_ERR(entry)) { err = PTR_ERR(entry); pr_err("Could not create new cache entry; error %d\n", err); @@ -138,9 +139,9 @@ err_lock_cache: } /* Signal end of usage of an IV block. Decreases the refcount. */ -int sflc_dev_putIvBlockRef(sflc_Device * dev, u32 psi) +int sfold_dev_putIvBlockRef(sfold_Device * dev, u32 psi) { - sflc_dev_IvCacheEntry * entry; + sfold_dev_IvCacheEntry * entry; int err; /* No condition needed besides mutual exclusion: just grab the lock (no waitqueue) */ @@ -161,12 +162,12 @@ int sflc_dev_putIvBlockRef(sflc_Device * dev, u32 psi) list_add(&entry->lru_node, &dev->iv_lru_list); /* If cache is not full, we can return now */ - if (dev->iv_cache_nr_entries < SFLC_DEV_IV_CACHE_CAPACITY) { + if (dev->iv_cache_nr_entries < SFOLD_DEV_IV_CACHE_CAPACITY) { goto out; } /* Otherwise, let's look for the least recent unreffed entry, and evict it */ - sflc_dev_IvCacheEntry * evicted; + sfold_dev_IvCacheEntry * evicted; bool found = false; list_for_each_entry_reverse(evicted, &dev->iv_lru_list, lru_node) { if (evicted->refcnt == 0) { @@ -187,7 +188,7 @@ int sflc_dev_putIvBlockRef(sflc_Device * dev, u32 psi) /* Pull it out of the LRU list */ __list_del_entry(&evicted->lru_node); /* Destroy it (free and flush to disk) */ - err = sflc_dev_destroyIvCacheEntry(dev, evicted); + err = sfold_dev_destroyIvCacheEntry(dev, evicted); if (err) { pr_err("Could not evict cache entry for PSI %u; error %d\n", evicted->psi, err); goto err_destroy_entry; @@ -215,9 +216,9 @@ err_lock_cache: } /* Flush all dirty IV blocks */ -void sflc_dev_flushIvs(sflc_Device * dev) +void sfold_dev_flushIvs(sfold_Device * dev) { - sflc_dev_IvCacheEntry * entry, * _next; + sfold_dev_IvCacheEntry * entry, * _next; int err; /* Iterate over all entries */ @@ -226,7 +227,7 @@ void sflc_dev_flushIvs(sflc_Device * dev) __list_del_entry(&entry->lru_node); /* Destroy it */ - err = sflc_dev_destroyIvCacheEntry(dev, entry); + err = sfold_dev_destroyIvCacheEntry(dev, entry); if (err) { pr_err("Could not destroy IV cache entry for PSI %u; error %d\n", entry->psi, err); } @@ -237,16 +238,16 @@ void sflc_dev_flushIvs(sflc_Device * dev) * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -static sflc_dev_IvCacheEntry * sflc_dev_newIvCacheEntry(sflc_Device * dev, u32 psi) +static sfold_dev_IvCacheEntry * sfold_dev_newIvCacheEntry(sfold_Device * dev, u32 psi) { - sflc_dev_IvCacheEntry * entry; + sfold_dev_IvCacheEntry * entry; int err; sector_t sector; /* Allocate and init structure */ /* Allocate structure */ - entry = kmem_cache_alloc(sflc_pools_ivSlab, GFP_NOIO); + entry = kmem_cache_alloc(sfold_pools_ivSlab, GFP_NOIO); if (!entry) { pr_err("Could not allocate IvCacheEntry structure\n"); err = -ENOMEM; @@ -256,7 +257,7 @@ static sflc_dev_IvCacheEntry * sflc_dev_newIvCacheEntry(sflc_Device * dev, u32 p /* Set PSI */ entry->psi = psi; /* Allocate page */ - entry->iv_page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO); + entry->iv_page = mempool_alloc(sfold_pools_pagePool, GFP_NOIO); if (!entry->iv_page) { pr_err("Could not allocate IV page\n"); err = -ENOMEM; @@ -276,10 +277,10 @@ static sflc_dev_IvCacheEntry * sflc_dev_newIvCacheEntry(sflc_Device * dev, u32 p /* Read from disk */ /* Position on disk */ - sector = sflc_dev_psiToIvBlockSector(dev, psi); + sector = sfold_dev_psiToIvBlockSector(dev, psi); /* Read */ - err = sflc_dev_rwSector(dev, entry->iv_page, sector, READ); + err = sfold_dev_rwSector(dev, entry->iv_page, sector, READ); if (err) { pr_err("Could not read IV block from disk; error %d\n", err); goto err_read; @@ -290,14 +291,14 @@ static sflc_dev_IvCacheEntry * sflc_dev_newIvCacheEntry(sflc_Device * dev, u32 p err_read: kunmap(entry->iv_page); - mempool_free(entry->iv_page, sflc_pools_pagePool); + mempool_free(entry->iv_page, sfold_pools_pagePool); err_alloc_page: - kmem_cache_free(sflc_pools_ivSlab, entry); + kmem_cache_free(sfold_pools_ivSlab, entry); err_alloc_entry: return ERR_PTR(err); } -static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry * entry) +static int sfold_dev_destroyIvCacheEntry(sfold_Device * dev, sfold_dev_IvCacheEntry * entry) { int err; sector_t sector; @@ -305,11 +306,11 @@ static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry /* Write to disk */ /* Position on disk */ - sector = sflc_dev_psiToIvBlockSector(dev, entry->psi); + sector = sfold_dev_psiToIvBlockSector(dev, entry->psi); /* Write (if necessary) */ if (entry->dirtyness) { - err = sflc_dev_rwSector(dev, entry->iv_page, sector, WRITE); + err = sfold_dev_rwSector(dev, entry->iv_page, sector, WRITE); if (err) { pr_err("Could not write IV block to disk; error %d\n", err); return err; @@ -322,10 +323,10 @@ static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry /* Kunmap page */ kunmap(entry->iv_page); /* Free it */ - mempool_free(entry->iv_page, sflc_pools_pagePool); + mempool_free(entry->iv_page, sfold_pools_pagePool); /* Free structure */ - kmem_cache_free(sflc_pools_ivSlab, entry); + kmem_cache_free(sfold_pools_ivSlab, entry); return 0; } diff --git a/dm-sflc/device/rawio.c b/dm-sflc/old/device/rawio.c similarity index 89% rename from dm-sflc/device/rawio.c rename to dm-sflc/old/device/rawio.c index 91cc682..ec70147 100644 --- a/dm-sflc/device/rawio.c +++ b/dm-sflc/old/device/rawio.c @@ -25,9 +25,9 @@ * INCLUDE SECTION * *****************************************************/ -#include "device.h" -#include "utils/pools.h" -#include "log/log.h" +#include "old/device/device.h" +#include "old/utils/pools.h" +#include "old/log/log.h" #include #include @@ -46,7 +46,7 @@ /* Synchronously reads/writes one 4096-byte sector from/to the underlying device to/from the provided page */ -int sflc_dev_rwSector(sflc_Device * dev, struct page * page, sector_t sector, int rw) +int sfold_dev_rwSector(sfold_Device * dev, struct page * page, sector_t sector, int rw) { struct bio *bio; blk_opf_t opf; @@ -57,16 +57,16 @@ int sflc_dev_rwSector(sflc_Device * dev, struct page * page, sector_t sector, in opf |= REQ_SYNC; /* Allocate bio */ - bio = bio_alloc_bioset(dev->bdev->bdev, 1, opf, GFP_NOIO, &sflc_pools_bioset); + bio = bio_alloc_bioset(dev->bdev->bdev, 1, opf, GFP_NOIO, &sfold_pools_bioset); if (!bio) { pr_err("Could not allocate bio\n"); return -ENOMEM; } /* Set sector */ - bio->bi_iter.bi_sector = sector * SFLC_DEV_SECTOR_SCALE; + bio->bi_iter.bi_sector = sector * SFOLD_DEV_SECTOR_SCALE; /* Add page */ - if (!bio_add_page(bio, page, SFLC_DEV_SECTOR_SIZE, 0)) { + if (!bio_add_page(bio, page, SFOLD_DEV_SECTOR_SIZE, 0)) { pr_err("Catastrophe: could not add page to bio! WTF?\n"); err = EINVAL; goto out; diff --git a/dm-sflc/device/rmap.c b/dm-sflc/old/device/rmap.c similarity index 89% rename from dm-sflc/device/rmap.c rename to dm-sflc/old/device/rmap.c index e309211..d196462 100644 --- a/dm-sflc/device/rmap.c +++ b/dm-sflc/old/device/rmap.c @@ -29,9 +29,9 @@ * INCLUDE SECTION * *****************************************************/ -#include "device.h" -#include "crypto/rand/rand.h" -#include "log/log.h" +#include "old/device/device.h" +#include "old/crypto/rand/rand.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * @@ -43,7 +43,7 @@ /* Sets the PSI as owned by the given volume (also decreases free_slices). * Returns < 0 if already taken. */ -int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx) +int sfold_dev_markPsiTaken(sfold_Device * dev, u32 psi, u8 vol_idx) { u8 prev_vol_idx; @@ -55,7 +55,7 @@ int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx) /* Check that it's free */ prev_vol_idx = dev->rmap[psi]; - if (prev_vol_idx != SFLC_DEV_RMAP_INVALID_VOL) { + if (prev_vol_idx != SFOLD_DEV_RMAP_INVALID_VOL) { pr_err("Requested to set ownership for already-owned PSI\n"); return -EINVAL; } @@ -69,7 +69,7 @@ int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx) /* Returns a random free physical slice, or < 0 if error */ -s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev) +s32 sfold_dev_getNextRandomFreePsi(sfold_Device * dev) { u32 psi; @@ -89,7 +89,7 @@ s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev) pr_err("Double catastrophe! No free PSIs on the device, and didn't catch it before!\n"); return -ENOSPC; } - } while (dev->rmap[psi] != SFLC_DEV_RMAP_INVALID_VOL); + } while (dev->rmap[psi] != SFOLD_DEV_RMAP_INVALID_VOL); return psi; } diff --git a/dm-sflc/device/volumes.c b/dm-sflc/old/device/volumes.c similarity index 70% rename from dm-sflc/device/volumes.c rename to dm-sflc/old/device/volumes.c index b6ec553..7b12ab2 100644 --- a/dm-sflc/device/volumes.c +++ b/dm-sflc/old/device/volumes.c @@ -29,8 +29,8 @@ * INCLUDE SECTION * *****************************************************/ -#include "device.h" -#include "log/log.h" +#include "old/device/device.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * @@ -41,22 +41,13 @@ *****************************************************/ /* Returns false if volume index was already occupied. */ -bool sflc_dev_addVolume(sflc_Device * dev, sflc_Volume * vol, int vol_idx) +bool sfold_dev_addVolume(sfold_Device * dev, sfold_Volume * vol, int vol_idx) { - int err; - if (dev->vol[vol_idx]) { pr_err("Something's wrong, asked to set volume number %d, already occupied\n", vol_idx); return false; } - /* Update sysfs */ - err = sflc_sysfs_addVolumeToDevice(dev->kobj, vol->kvol); - if (err) { - pr_err("Could not add volume symlink in sysfs device subdir; error %d\n", err); - return false; - } - /* Update fields */ dev->vol[vol_idx] = vol; dev->vol_cnt += 1; @@ -64,39 +55,15 @@ bool sflc_dev_addVolume(sflc_Device * dev, sflc_Volume * vol, int vol_idx) return true; } -/* Looks at all volumes in all devices. Returns NULL if not found */ -sflc_Volume * sflc_dev_lookupVolumeByName(char * vol_name) -{ - sflc_Device * dev; - sflc_Volume * vol; - - /* Sweep all devices */ - list_for_each_entry(dev, &sflc_dev_list, list_node) { - /* Sweep all volumes */ - int i; - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; ++i) { - vol = dev->vol[i]; - if (vol && (strcmp(vol_name, vol->vol_name) == 0)) { - return vol; - } - } - } - - return NULL; -} /* Does not put the volume. Returns false if was already NULL. */ -bool sflc_dev_removeVolume(sflc_Device * dev, int vol_idx) +bool sfold_dev_removeVolume(sfold_Device * dev, int vol_idx) { if (!dev->vol[vol_idx]) { pr_err("Something's wrong, asked to unset volume number %d, already NULL\n", vol_idx); return false; } - - /* Remove sysfs entry */ - if (dev->vol[vol_idx]->kvol) { - sflc_sysfs_removeVolumeFromDevice(dev->kobj, dev->vol[vol_idx]->kvol); - } + /* Update fields */ dev->vol[vol_idx] = NULL; diff --git a/dm-sflc/log/log.h b/dm-sflc/old/log/log.h similarity index 95% rename from dm-sflc/log/log.h rename to dm-sflc/old/log/log.h index 7ef7729..8386d98 100644 --- a/dm-sflc/log/log.h +++ b/dm-sflc/old/log/log.h @@ -25,8 +25,8 @@ * Logging format */ -#ifndef _SFLC_LOG_LOG_H_ -#define _SFLC_LOG_LOG_H_ +#ifndef _SFOLD_LOG_LOG_H_ +#define _SFOLD_LOG_LOG_H_ /***************************************************** * INCLUDE SECTION * @@ -41,4 +41,4 @@ #undef pr_fmt #define pr_fmt(fmt) "[%s] %s in %s:%d: " fmt, KBUILD_MODNAME, __func__, __FILE__, __LINE__ -#endif /* _SFLC_LOG_LOG_H_ */ +#endif /* _SFOLD_LOG_LOG_H_ */ diff --git a/dm-sflc/module.c b/dm-sflc/old/sflc_old.c similarity index 52% rename from dm-sflc/module.c rename to dm-sflc/old/sflc_old.c index 230e60c..4f1a839 100644 --- a/dm-sflc/module.c +++ b/dm-sflc/old/sflc_old.c @@ -28,124 +28,60 @@ #include #include -#include "sysfs/sysfs.h" -#include "target/target.h" -#include "crypto/symkey/symkey.h" -#include "crypto/rand/rand.h" -#include "utils/pools.h" -#include "utils/workqueues.h" -#include "log/log.h" +#include "old/sflc_old.h" +#include "old/crypto/symkey/symkey.h" +#include "old/crypto/rand/rand.h" +#include "old/utils/pools.h" +#include "old/utils/workqueues.h" +#include "old/log/log.h" -/***************************************************** - * MODULE FUNCTION PROTOTYPES * - *****************************************************/ - -static int sflc_init(void); -static void sflc_exit(void); /***************************************************** * MODULE FUNCTIONS DEFINITIONS * *****************************************************/ /* Module entry point, called just once, at module-load time */ -static int sflc_init(void) +int sfold_init(void) { int ret; - ret = sflc_dev_init(); - if (ret) { - pr_err("Could not init device module; error %d\n", ret); - goto err_dev_init; - } - - ret = sflc_rand_init(); + ret = sfold_rand_init(); if (ret) { pr_err("Could not init rand; error %d\n", ret); goto err_rand_init; } - /* Run crypto symkey self test */ - ret = sflc_sk_selftest(); - if (ret) { - pr_err("Error in crypto symkey self test: %d\n", ret); - goto err_sk; - } - /* Run crypto rand self test */ - ret = sflc_rand_selftest(); - if (ret) { - pr_err("Error in crypto rand self test: %d\n", ret); - goto err_rand_selftest; - } - - /* Create the first sysfs entries */ - ret = sflc_sysfs_init(); - if (ret) { - pr_err("Could not init sysfs; error %d\n", ret); - goto err_sysfs; - } - /* Init the memory pools */ - ret = sflc_pools_init(); + ret = sfold_pools_init(); if (ret) { pr_err("Could not init memory pools; error %d\n", ret); goto err_pools; } /* Init the workqueues */ - ret = sflc_queues_init(); + ret = sfold_queues_init(); if (ret) { pr_err("Could not init workqueues; error %d\n", ret); goto err_queues; } - /* Register the DM callbacks */ - ret = dm_register_target(&sflc_target); - if (ret < 0) { - pr_err("dm_register failed: %d", ret); - goto err_dm; - } - - pr_info("Shufflecake loaded"); return 0; -err_dm: - sflc_queues_exit(); err_queues: - sflc_pools_exit(); + sfold_pools_exit(); err_pools: - sflc_sysfs_exit(); -err_sysfs: -err_rand_selftest: -err_sk: - sflc_rand_exit(); + sfold_rand_exit(); err_rand_init: - sflc_dev_exit(); -err_dev_init: return ret; } /* Module exit point, called just once, at module-unload time */ -static void sflc_exit(void) +void sfold_exit(void) { - dm_unregister_target(&sflc_target); - sflc_queues_exit(); - sflc_pools_exit(); - sflc_sysfs_exit(); - sflc_rand_exit(); - sflc_dev_exit(); + sfold_queues_exit(); + sfold_pools_exit(); + sfold_rand_exit(); - pr_info("Shufflecake unloaded"); return; } - -/* Declare them as such to the kernel */ -module_init(sflc_init); -module_exit(sflc_exit); - -/***************************************************** - * MODULE INFO * - *****************************************************/ - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Toninov"); diff --git a/dm-sflc/target/target.h b/dm-sflc/old/sflc_old.h similarity index 69% rename from dm-sflc/target/target.h rename to dm-sflc/old/sflc_old.h index 43eb64e..7f86748 100644 --- a/dm-sflc/target/target.h +++ b/dm-sflc/old/sflc_old.h @@ -20,25 +20,27 @@ * GNU General Public License along with this program. * If not, see . */ - -/* - * Methods of our DM target - */ -#ifndef _SFLC_TARGET_TARGET_H_ -#define _SFLC_TARGET_TARGET_H_ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - -/***************************************************** - * PUBLIC VARIABLES DECLARATIONS * - *****************************************************/ - -extern struct target_type sflc_target; +#ifndef _SFOLD_SFOLD_H +#define _SFOLD_SFOLD_H -#endif /* _SFLC_TARGET_TARGET_H_ */ +// For the definition of sfold_Device and its functions +#include "old/device/device.h" +// For the definition of sfold_Volume and its functions +#include "old/volume/volume.h" + + +extern struct target_type sfold_target_type; + + +int sfold_init(void); +void sfold_exit(void); + +int sfold_sysfs_add_device(sfold_Device *dev); +void sfold_sysfs_remove_device(sfold_Device *dev); +int sfold_sysfs_add_volume(sfold_Volume *vol); +void sfold_sysfs_remove_volume(sfold_Volume *vol); + + +#endif /* _SFOLD_SFOLD_H */ diff --git a/dm-sflc/old/sysfs.c b/dm-sflc/old/sysfs.c new file mode 100644 index 0000000..5445d8f --- /dev/null +++ b/dm-sflc/old/sysfs.c @@ -0,0 +1,142 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include + +#include "old/sflc_old.h" +#include "old/log/log.h" + +// Only to import the definitions of structs sflc_volume and sflc_device +#include "sflc.h" + + +/* + *---------------------------- + * Devices + *---------------------------- + */ + +/* Show the total number of slices in a device */ +static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_device *top_dev; + sfold_Device * dev; + ssize_t ret; + + top_dev = container_of(kobj, struct sflc_device, kobj); + dev = top_dev->sfold_dev; + + /* Write the tot_slices */ + ret = sysfs_emit(buf, "%u\n", dev->tot_slices); + + return ret; +} + +/* Show the number of free slices in a device */ +static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_device *top_dev; + sfold_Device * dev; + ssize_t ret; + + top_dev = container_of(kobj, struct sflc_device, kobj); + dev = top_dev->sfold_dev; + + /* Write the free_slices */ + if (mutex_lock_interruptible(&dev->slices_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", dev->free_slices); + mutex_unlock(&dev->slices_lock); + + return ret; +} + +static struct kobj_attribute tot_slices_kattr = __ATTR_RO(tot_slices); +static struct kobj_attribute free_slices_kattr = __ATTR_RO(free_slices); +static struct attribute *sfold_device_attrs[] = { + &tot_slices_kattr.attr, + &free_slices_kattr.attr, + NULL +}; +static const struct attribute_group sfold_device_attr_group = { + .attrs = sfold_device_attrs, +}; + +int sfold_sysfs_add_device(sfold_Device *dev) +{ + return sysfs_create_group(dev->kobj_parent, &sfold_device_attr_group); +} + +void sfold_sysfs_remove_device(sfold_Device *dev) +{ + sysfs_remove_group(dev->kobj_parent, &sfold_device_attr_group); +} + + +/* + *---------------------------- + * Volumes + *---------------------------- + */ + +/* Show the number of mapped slices in a volume */ +static ssize_t mapped_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_volume *top_vol; + sfold_Volume * vol; + ssize_t ret; + + top_vol = container_of(kobj, struct sflc_volume, kobj); + vol = top_vol->sfold_vol; + + /* Write the free_slices */ + if (mutex_lock_interruptible(&vol->fmap_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", vol->mapped_slices); + mutex_unlock(&vol->fmap_lock); + + return ret; +} + +static struct kobj_attribute mapped_slices_kattr = __ATTR_RO(mapped_slices); +static struct attribute *sfold_volume_attrs[] = { + &mapped_slices_kattr.attr, + NULL +}; +static const struct attribute_group sfold_volume_attr_group = { + .attrs = sfold_volume_attrs, +}; + +int sfold_sysfs_add_volume(sfold_Volume *vol) +{ + return sysfs_create_group(vol->kobj_parent, &sfold_volume_attr_group); +} + +void sfold_sysfs_remove_volume(sfold_Volume *vol) +{ + sysfs_remove_group(vol->kobj_parent, &sfold_volume_attr_group); +} diff --git a/dm-sflc/old/target.c b/dm-sflc/old/target.c new file mode 100644 index 0000000..4ceb71d --- /dev/null +++ b/dm-sflc/old/target.c @@ -0,0 +1,150 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* + * Methods of our DM target + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include "old/device/device.h" +#include "old/volume/volume.h" +#include "old/utils/bio.h" +#include "old/utils/string.h" +#include "old/log/log.h" + +// Only to import the definition of struct sflc_volume +#include "sflc.h" + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +static int sfold_tgt_map(struct dm_target *ti, struct bio *bio); +static void sfold_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits); +static int sfold_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn, + void *data); + +/***************************************************** + * PUBLIC VARIABLES DEFINITIONS * + *****************************************************/ + +struct target_type sfold_target_type = { + .map = sfold_tgt_map, + .io_hints = sfold_tgt_ioHints, + .iterate_devices = sfold_tgt_iterateDevices, +}; + +/***************************************************** + * PRIVATE FUNCTIONS DEFINITIONS * + *****************************************************/ + + +/* Callback for every bio submitted to our virtual block device */ +static int sfold_tgt_map(struct dm_target *ti, struct bio *bio) +{ + int err; + struct sflc_volume *top_vol = ti->private; + sfold_Volume *vol = top_vol->sfold_vol; + + /* If no data, just quickly remap the sector and the block device (no crypto) */ + /* TODO: this is dangerous for deniability, will need more filtering */ + if (unlikely(!bio_has_data(bio))) { + pr_debug("No-data bio: bio_op = %d", bio_op(bio)); + err = sfold_vol_remapBioFast(vol, bio); + if (err) { + pr_err("Could not remap bio; error %d\n", err); + return DM_MAPIO_KILL; + } + return DM_MAPIO_REMAPPED; + } + + /* At this point, the bio has data. Do a few sanity checks */ + /* TODO: I think we can get rid of all of them */ + + /* Check that it is properly aligned and it doesn't cross vector boundaries */ + if (unlikely(!sfold_bio_isAligned(bio))) { + pr_err("Unaligned bio!\n"); + return DM_MAPIO_KILL; + } + /* If it contains more than one SFLC sector, complain with the DM layer and continue */ + if (unlikely(bio->bi_iter.bi_size > SFOLD_DEV_SECTOR_SIZE)) { + pr_notice("Large bio of size %u\n", bio->bi_iter.bi_size); + dm_accept_partial_bio(bio, SFOLD_DEV_SECTOR_SCALE); + } + /* Check that it contains exactly one SFLC sector */ + if (unlikely(bio->bi_iter.bi_size != SFOLD_DEV_SECTOR_SIZE)) { + pr_err("Wrong length (%u) of bio\n", bio->bi_iter.bi_size); + return DM_MAPIO_KILL; + } + + /* Now it is safe, process it */ + err = sfold_vol_processBio(vol, bio); + if (err) { + pr_err("Could not enqueue bio\n"); + return DM_MAPIO_KILL; + } + + return DM_MAPIO_SUBMITTED; +} + +/* Callback executed to inform the DM about our 4096-byte sector size */ +static void sfold_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits) +{ + struct sflc_volume *top_vol = ti->private; + sfold_Volume *vol = top_vol->sfold_vol; + + pr_info("Called io_hints on volume \"%s\"\n", vol->vol_name); + + limits->logical_block_size = SFOLD_DEV_SECTOR_SIZE; + limits->physical_block_size = SFOLD_DEV_SECTOR_SIZE; + + limits->io_min = SFOLD_DEV_SECTOR_SIZE; + limits->io_opt = SFOLD_DEV_SECTOR_SIZE; + + return; +} + +/* Callback needed for God knows what, otherwise io_hints never gets called */ +static int sfold_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn, + void *data) +{ + struct sflc_volume *top_vol = ti->private; + sfold_Volume *vol = top_vol->sfold_vol; + sfold_Device * dev = vol->dev; + + pr_debug("Called iterate_devices on volume \"%s\"\n", vol->vol_name); + + if (!fn) { + return -EINVAL; + } + return fn(ti, vol->dev->bdev, 0, + (dev->dev_header_size + dev->tot_slices * SFOLD_DEV_PHYS_SLICE_SIZE) * SFOLD_DEV_SECTOR_SCALE, + data); +} diff --git a/dm-sflc/utils/bio.c b/dm-sflc/old/utils/bio.c similarity index 88% rename from dm-sflc/utils/bio.c rename to dm-sflc/old/utils/bio.c index 7591c52..6607f89 100644 --- a/dm-sflc/utils/bio.c +++ b/dm-sflc/old/utils/bio.c @@ -29,8 +29,8 @@ * INCLUDE SECTION * *****************************************************/ -#include "bio.h" -#include "log/log.h" +#include "old/utils/bio.h" +#include "old/log/log.h" /***************************************************** @@ -41,7 +41,7 @@ * Checks whether each of the bio's segments contains a whole * number of 4096-byte sectors. */ -bool sflc_bio_isAligned(struct bio * bio) +bool sfold_bio_isAligned(struct bio * bio) { bool ret = true; @@ -51,12 +51,12 @@ bool sflc_bio_isAligned(struct bio * bio) return false; } /* Unlikely because we tell the DM layer about our sector size */ - if (unlikely(bio->bi_iter.bi_size % SFLC_DEV_SECTOR_SIZE != 0)) { + if (unlikely(bio->bi_iter.bi_size % SFOLD_DEV_SECTOR_SIZE != 0)) { pr_err("Abnormal bi_size = %u\n", bio->bi_iter.bi_size); return false; } /* Unlikely because we tell the DM layer about our sector size */ - if (unlikely(bio->bi_iter.bi_sector % SFLC_DEV_SECTOR_SCALE != 0)) { + if (unlikely(bio->bi_iter.bi_sector % SFOLD_DEV_SECTOR_SCALE != 0)) { pr_err("Abnormal bi_sector = %llu\n", bio->bi_iter.bi_sector); return false; } @@ -64,7 +64,7 @@ bool sflc_bio_isAligned(struct bio * bio) struct bio_vec bvl; struct bvec_iter iter; bio_for_each_segment(bvl, bio, iter) { - if ((bvl.bv_len == 0) || (bvl.bv_len % SFLC_DEV_SECTOR_SIZE != 0)) { + if ((bvl.bv_len == 0) || (bvl.bv_len % SFOLD_DEV_SECTOR_SIZE != 0)) { pr_err("Abnormal vector: bv_len = %u\n", bvl.bv_len); ret = false; } diff --git a/dm-sflc/utils/bio.h b/dm-sflc/old/utils/bio.h similarity index 91% rename from dm-sflc/utils/bio.h rename to dm-sflc/old/utils/bio.h index d7bf7b2..51917e6 100644 --- a/dm-sflc/utils/bio.h +++ b/dm-sflc/old/utils/bio.h @@ -25,14 +25,14 @@ * A collection of utility bio functions */ -#ifndef _SFLC_UTILS_BIO_H_ -#define _SFLC_UTILS_BIO_H_ +#ifndef _SFOLD_UTILS_BIO_H_ +#define _SFOLD_UTILS_BIO_H_ /***************************************************** * INCLUDE SECTION * *****************************************************/ -#include "device/device.h" +#include "old/device/device.h" /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * @@ -42,7 +42,7 @@ * Checks whether each of the bio's segments contains a whole * number of 4096-byte sectors. */ -bool sflc_bio_isAligned(struct bio * bio); +bool sfold_bio_isAligned(struct bio * bio); -#endif /* _SFLC_UTILS_BIO_H_ */ +#endif /* _SFOLD_UTILS_BIO_H_ */ diff --git a/dm-sflc/utils/pools.c b/dm-sflc/old/utils/pools.c similarity index 56% rename from dm-sflc/utils/pools.c rename to dm-sflc/old/utils/pools.c index 9e9af0b..5e67faf 100644 --- a/dm-sflc/utils/pools.c +++ b/dm-sflc/old/utils/pools.c @@ -29,100 +29,100 @@ * INCLUDE SECTION * *****************************************************/ -#include "pools.h" -#include "log/log.h" +#include "old/utils/pools.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * *****************************************************/ /* Pool sizes */ -#define SFLC_POOLS_BIOSET_POOL_SIZE 1024 -#define SFLC_POOLS_PAGE_POOL_SIZE 1024 -#define SFLC_POOLS_WRITE_WORK_POOL_SIZE 1024 -#define SFLC_POOLS_DECRYPT_WORK_POOL_SIZE 1024 +#define SFOLD_POOLS_BIOSET_POOL_SIZE 1024 +#define SFOLD_POOLS_PAGE_POOL_SIZE 1024 +#define SFOLD_POOLS_WRITE_WORK_POOL_SIZE 1024 +#define SFOLD_POOLS_DECRYPT_WORK_POOL_SIZE 1024 /* Slab cache names */ -#define SFLC_POOLS_WRITE_WORK_SLAB_NAME "sflc_write_work_slab" -#define SFLC_POOLS_DECRYPT_WORK_SLAB_NAME "sflc_decrypt_work_slab" -#define SFLC_POOLS_IV_SLAB_NAME "sflc_iv_slab" +#define SFOLD_POOLS_WRITE_WORK_SLAB_NAME "sfold_write_work_slab" +#define SFOLD_POOLS_DECRYPT_WORK_SLAB_NAME "sfold_decrypt_work_slab" +#define SFOLD_POOLS_IV_SLAB_NAME "sfold_iv_slab" /***************************************************** * PUBLIC VARIABLES DEFINITIONS * *****************************************************/ -struct bio_set sflc_pools_bioset; -mempool_t * sflc_pools_pagePool; -mempool_t * sflc_pools_writeWorkPool; -mempool_t * sflc_pools_decryptWorkPool; -struct kmem_cache * sflc_pools_ivSlab; +struct bio_set sfold_pools_bioset; +mempool_t * sfold_pools_pagePool; +mempool_t * sfold_pools_writeWorkPool; +mempool_t * sfold_pools_decryptWorkPool; +struct kmem_cache * sfold_pools_ivSlab; /***************************************************** * PRIVATE VARIABLES * *****************************************************/ -static struct kmem_cache * sflc_pools_writeWorkSlab; -static struct kmem_cache * sflc_pools_decryptWorkSlab; +static struct kmem_cache * sfold_pools_writeWorkSlab; +static struct kmem_cache * sfold_pools_decryptWorkSlab; /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -int sflc_pools_init(void) +int sfold_pools_init(void) { int err; /* Memory pools: bioset */ - err = bioset_init(&sflc_pools_bioset, SFLC_POOLS_BIOSET_POOL_SIZE, 0, BIOSET_NEED_BVECS); + err = bioset_init(&sfold_pools_bioset, SFOLD_POOLS_BIOSET_POOL_SIZE, 0, BIOSET_NEED_BVECS); if (err) { pr_err("Could not init bioset: error %d\n", err); goto err_bioset; } /* Memory pools: page_pool */ - sflc_pools_pagePool = mempool_create_page_pool(SFLC_POOLS_PAGE_POOL_SIZE, 0); - if (!sflc_pools_pagePool) { + sfold_pools_pagePool = mempool_create_page_pool(SFOLD_POOLS_PAGE_POOL_SIZE, 0); + if (!sfold_pools_pagePool) { pr_err("Could not create page pool\n"); err = -ENOMEM; goto err_pagepool; } /* Memory pools: writeWork slab cache */ - sflc_pools_writeWorkSlab = kmem_cache_create(SFLC_POOLS_WRITE_WORK_SLAB_NAME, sizeof(sflc_vol_WriteWork), 0, SLAB_POISON | SLAB_RED_ZONE, NULL); - if (IS_ERR(sflc_pools_writeWorkSlab)) { - err = PTR_ERR(sflc_pools_writeWorkSlab); + sfold_pools_writeWorkSlab = kmem_cache_create(SFOLD_POOLS_WRITE_WORK_SLAB_NAME, sizeof(sfold_vol_WriteWork), 0, SLAB_POISON | SLAB_RED_ZONE, NULL); + if (IS_ERR(sfold_pools_writeWorkSlab)) { + err = PTR_ERR(sfold_pools_writeWorkSlab); pr_err("Could not create writeWork slab cache; error %d\n", err); goto err_create_write_work_slab; } /* Memory pools: writeWork pool */ - sflc_pools_writeWorkPool = mempool_create_slab_pool(SFLC_POOLS_WRITE_WORK_POOL_SIZE, sflc_pools_writeWorkSlab); - if (!sflc_pools_writeWorkPool) { + sfold_pools_writeWorkPool = mempool_create_slab_pool(SFOLD_POOLS_WRITE_WORK_POOL_SIZE, sfold_pools_writeWorkSlab); + if (!sfold_pools_writeWorkPool) { pr_err("Could not create writeWork pool\n"); err = -ENOMEM; goto err_write_work_pool; } /* Memory pools: decryptWork slab cache */ - sflc_pools_decryptWorkSlab = kmem_cache_create(SFLC_POOLS_DECRYPT_WORK_SLAB_NAME, sizeof(sflc_vol_DecryptWork), 0, SLAB_POISON | SLAB_RED_ZONE, NULL); - if (IS_ERR(sflc_pools_decryptWorkSlab)) { - err = PTR_ERR(sflc_pools_decryptWorkSlab); + sfold_pools_decryptWorkSlab = kmem_cache_create(SFOLD_POOLS_DECRYPT_WORK_SLAB_NAME, sizeof(sfold_vol_DecryptWork), 0, SLAB_POISON | SLAB_RED_ZONE, NULL); + if (IS_ERR(sfold_pools_decryptWorkSlab)) { + err = PTR_ERR(sfold_pools_decryptWorkSlab); pr_err("Could not create decryptWork slab cache; error %d\n", err); goto err_create_decrypt_work_slab; } /* Memory pools: decryptWork pool */ - sflc_pools_decryptWorkPool = mempool_create_slab_pool(SFLC_POOLS_DECRYPT_WORK_POOL_SIZE, sflc_pools_decryptWorkSlab); - if (!sflc_pools_decryptWorkPool) { + sfold_pools_decryptWorkPool = mempool_create_slab_pool(SFOLD_POOLS_DECRYPT_WORK_POOL_SIZE, sfold_pools_decryptWorkSlab); + if (!sfold_pools_decryptWorkPool) { pr_err("Could not create decryptWork pool\n"); err = -ENOMEM; goto err_decrypt_work_pool; } /* Memory pools: IV slab cache */ - sflc_pools_ivSlab = kmem_cache_create(SFLC_POOLS_IV_SLAB_NAME, sizeof(sflc_dev_IvCacheEntry), 0, SLAB_POISON | SLAB_RED_ZONE, NULL); - if (IS_ERR(sflc_pools_ivSlab)) { - err = PTR_ERR(sflc_pools_ivSlab); + sfold_pools_ivSlab = kmem_cache_create(SFOLD_POOLS_IV_SLAB_NAME, sizeof(sfold_dev_IvCacheEntry), 0, SLAB_POISON | SLAB_RED_ZONE, NULL); + if (IS_ERR(sfold_pools_ivSlab)) { + err = PTR_ERR(sfold_pools_ivSlab); pr_err("Could not create IV slab cache; error %d\n", err); goto err_create_iv_slab; } @@ -131,28 +131,28 @@ int sflc_pools_init(void) err_create_iv_slab: - mempool_destroy(sflc_pools_decryptWorkPool); + mempool_destroy(sfold_pools_decryptWorkPool); err_decrypt_work_pool: - kmem_cache_destroy(sflc_pools_decryptWorkSlab); + kmem_cache_destroy(sfold_pools_decryptWorkSlab); err_create_decrypt_work_slab: - mempool_destroy(sflc_pools_writeWorkPool); + mempool_destroy(sfold_pools_writeWorkPool); err_write_work_pool: - kmem_cache_destroy(sflc_pools_writeWorkSlab); + kmem_cache_destroy(sfold_pools_writeWorkSlab); err_create_write_work_slab: - mempool_destroy(sflc_pools_pagePool); + mempool_destroy(sfold_pools_pagePool); err_pagepool: - bioset_exit(&sflc_pools_bioset); + bioset_exit(&sfold_pools_bioset); err_bioset: return err; } -void sflc_pools_exit(void) +void sfold_pools_exit(void) { - kmem_cache_destroy(sflc_pools_ivSlab); - mempool_destroy(sflc_pools_decryptWorkPool); - kmem_cache_destroy(sflc_pools_decryptWorkSlab); - mempool_destroy(sflc_pools_writeWorkPool); - kmem_cache_destroy(sflc_pools_writeWorkSlab); - mempool_destroy(sflc_pools_pagePool); - bioset_exit(&sflc_pools_bioset); + kmem_cache_destroy(sfold_pools_ivSlab); + mempool_destroy(sfold_pools_decryptWorkPool); + kmem_cache_destroy(sfold_pools_decryptWorkSlab); + mempool_destroy(sfold_pools_writeWorkPool); + kmem_cache_destroy(sfold_pools_writeWorkSlab); + mempool_destroy(sfold_pools_pagePool); + bioset_exit(&sfold_pools_bioset); } diff --git a/dm-sflc/utils/pools.h b/dm-sflc/old/utils/pools.h similarity index 81% rename from dm-sflc/utils/pools.h rename to dm-sflc/old/utils/pools.h index e0a1261..b87d6c6 100644 --- a/dm-sflc/utils/pools.h +++ b/dm-sflc/old/utils/pools.h @@ -25,31 +25,31 @@ * A set of memory pools */ -#ifndef _SFLC_UTILS_POOLS_H_ -#define _SFLC_UTILS_POOLS_H_ +#ifndef _SFOLD_UTILS_POOLS_H_ +#define _SFOLD_UTILS_POOLS_H_ /***************************************************** * INCLUDE SECTION * *****************************************************/ -#include "device/device.h" +#include "old/device/device.h" /***************************************************** * PUBLIC VARIABLES DECLARATIONS * *****************************************************/ -extern struct bio_set sflc_pools_bioset; -extern mempool_t * sflc_pools_pagePool; -extern mempool_t * sflc_pools_writeWorkPool; -extern mempool_t * sflc_pools_decryptWorkPool; -extern struct kmem_cache * sflc_pools_ivSlab; +extern struct bio_set sfold_pools_bioset; +extern mempool_t * sfold_pools_pagePool; +extern mempool_t * sfold_pools_writeWorkPool; +extern mempool_t * sfold_pools_decryptWorkPool; +extern struct kmem_cache * sfold_pools_ivSlab; /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -int sflc_pools_init(void); -void sflc_pools_exit(void); +int sfold_pools_init(void); +void sfold_pools_exit(void); -#endif /* _SFLC_UTILS_POOLS_H_ */ +#endif /* _SFOLD_UTILS_POOLS_H_ */ diff --git a/dm-sflc/utils/string.c b/dm-sflc/old/utils/string.c similarity index 92% rename from dm-sflc/utils/string.c rename to dm-sflc/old/utils/string.c index 0199dae..8d533c6 100644 --- a/dm-sflc/utils/string.c +++ b/dm-sflc/old/utils/string.c @@ -31,15 +31,15 @@ #include -#include "string.h" -#include "log/log.h" +#include "old/utils/string.h" +#include "old/log/log.h" /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -int sflc_str_hexDecode(char * hex, u8 * bin) +int sfold_str_hexDecode(char * hex, u8 * bin) { char buf[3]; unsigned len; @@ -64,7 +64,7 @@ int sflc_str_hexDecode(char * hex, u8 * bin) } -void sflc_str_replaceAll(char * str, char old, char new) +void sfold_str_replaceAll(char * str, char old, char new) { int i; diff --git a/dm-sflc/utils/string.h b/dm-sflc/old/utils/string.h similarity index 88% rename from dm-sflc/utils/string.h rename to dm-sflc/old/utils/string.h index 8ac29df..98e0565 100644 --- a/dm-sflc/utils/string.h +++ b/dm-sflc/old/utils/string.h @@ -25,8 +25,8 @@ * A collection of utility string functions */ -#ifndef _SFLC_UTILS_STRING_H_ -#define _SFLC_UTILS_STRING_H_ +#ifndef _SFOLD_UTILS_STRING_H_ +#define _SFOLD_UTILS_STRING_H_ /***************************************************** * INCLUDE SECTION * @@ -38,8 +38,8 @@ * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -int sflc_str_hexDecode(char * hex, u8 * bin); -void sflc_str_replaceAll(char * str, char old, char new); +int sfold_str_hexDecode(char * hex, u8 * bin); +void sfold_str_replaceAll(char * str, char old, char new); -#endif /* _SFLC_UTILS_STRING_H_ */ +#endif /* _SFOLD_UTILS_STRING_H_ */ diff --git a/dm-sflc/utils/vector.c b/dm-sflc/old/utils/vector.c similarity index 92% rename from dm-sflc/utils/vector.c rename to dm-sflc/old/utils/vector.c index c18691b..4c73814 100644 --- a/dm-sflc/utils/vector.c +++ b/dm-sflc/old/utils/vector.c @@ -29,9 +29,9 @@ * INCLUDE SECTION * *****************************************************/ -#include "vector.h" -#include "crypto/rand/rand.h" -#include "log/log.h" +#include "old/utils/vector.h" +#include "old/crypto/rand/rand.h" +#include "old/log/log.h" /***************************************************** @@ -39,13 +39,13 @@ *****************************************************/ /* Shuffle a vector of u32's with the Fisher-Yates algorithm */ -int sflc_vec_u32shuffle(u32 *v, u32 len) +int sfold_vec_u32shuffle(u32 *v, u32 len) { u32 i; for (i = len-1; i >= 1; i--) { /* Sample a random index from 0 to i (inclusive) */ - s32 j = sflc_rand_uniform(i+1); + s32 j = sfold_rand_uniform(i+1); if (j < 0) { pr_err("Could not sample j; error %d", j); return j; diff --git a/dm-sflc/utils/vector.h b/dm-sflc/old/utils/vector.h similarity index 92% rename from dm-sflc/utils/vector.h rename to dm-sflc/old/utils/vector.h index 4edc7ff..ae75ca0 100644 --- a/dm-sflc/utils/vector.h +++ b/dm-sflc/old/utils/vector.h @@ -25,8 +25,8 @@ * A collection of utility vector functions */ -#ifndef _SFLC_UTILS_VECTOR_H_ -#define _SFLC_UTILS_VECTOR_H_ +#ifndef _SFOLD_UTILS_VECTOR_H_ +#define _SFOLD_UTILS_VECTOR_H_ /***************************************************** * INCLUDE SECTION * @@ -39,7 +39,7 @@ *****************************************************/ /* Shuffle a vector of u32's */ -int sflc_vec_u32shuffle(u32 *v, u32 len); +int sfold_vec_u32shuffle(u32 *v, u32 len); -#endif /* _SFLC_UTILS_VECTOR_H_ */ +#endif /* _SFOLD_UTILS_VECTOR_H_ */ diff --git a/dm-sflc/utils/workqueues.c b/dm-sflc/old/utils/workqueues.c similarity index 76% rename from dm-sflc/utils/workqueues.c rename to dm-sflc/old/utils/workqueues.c index 15697b1..942b765 100644 --- a/dm-sflc/utils/workqueues.c +++ b/dm-sflc/old/utils/workqueues.c @@ -28,42 +28,42 @@ * INCLUDE SECTION * *****************************************************/ -#include "workqueues.h" -#include "log/log.h" +#include "old/utils/workqueues.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * *****************************************************/ -#define SFLC_QUEUES_WRITE_WQ_NAME "sflc_write_workqueue" -#define SFLC_QUEUES_DECRYPT_WQ_NAME "sflc_decrypt_workqueue" +#define SFOLD_QUEUES_WRITE_WQ_NAME "sfold_write_workqueue" +#define SFOLD_QUEUES_DECRYPT_WQ_NAME "sfold_decrypt_workqueue" /***************************************************** * PUBLIC VARIABLES DEFINITIONS * *****************************************************/ -struct workqueue_struct * sflc_queues_writeQueue; -struct workqueue_struct * sflc_queues_decryptQueue; +struct workqueue_struct * sfold_queues_writeQueue; +struct workqueue_struct * sfold_queues_decryptQueue; /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -int sflc_queues_init(void) +int sfold_queues_init(void) { int err; /* Write workqueue */ - sflc_queues_writeQueue = create_workqueue(SFLC_QUEUES_WRITE_WQ_NAME); - if (!sflc_queues_writeQueue) { + sfold_queues_writeQueue = create_workqueue(SFOLD_QUEUES_WRITE_WQ_NAME); + if (!sfold_queues_writeQueue) { pr_err("Could not create write workqueue\n"); err = -ENOMEM; goto err_write_queue; } /* Decrypt workqueue */ - sflc_queues_decryptQueue = create_workqueue(SFLC_QUEUES_DECRYPT_WQ_NAME); - if (!sflc_queues_decryptQueue) { + sfold_queues_decryptQueue = create_workqueue(SFOLD_QUEUES_DECRYPT_WQ_NAME); + if (!sfold_queues_decryptQueue) { pr_err("Could not create decrypt workqueue\n"); err = -ENOMEM; goto err_decrypt_queue; @@ -73,13 +73,13 @@ int sflc_queues_init(void) err_decrypt_queue: - destroy_workqueue(sflc_queues_writeQueue); + destroy_workqueue(sfold_queues_writeQueue); err_write_queue: return err; } -void sflc_queues_exit(void) +void sfold_queues_exit(void) { - destroy_workqueue(sflc_queues_decryptQueue); - destroy_workqueue(sflc_queues_writeQueue); + destroy_workqueue(sfold_queues_decryptQueue); + destroy_workqueue(sfold_queues_writeQueue); } diff --git a/dm-sflc/utils/workqueues.h b/dm-sflc/old/utils/workqueues.h similarity index 86% rename from dm-sflc/utils/workqueues.h rename to dm-sflc/old/utils/workqueues.h index 38fb031..3026a6d 100644 --- a/dm-sflc/utils/workqueues.h +++ b/dm-sflc/old/utils/workqueues.h @@ -25,8 +25,8 @@ * A set of workqueues */ -#ifndef _SFLC_UTILS_QUEUES_H_ -#define _SFLC_UTILS_QUEUES_H_ +#ifndef _SFOLD_UTILS_QUEUES_H_ +#define _SFOLD_UTILS_QUEUES_H_ /***************************************************** * INCLUDE SECTION * @@ -38,15 +38,15 @@ * PUBLIC VARIABLES DECLARATIONS * *****************************************************/ -extern struct workqueue_struct * sflc_queues_writeQueue; -extern struct workqueue_struct * sflc_queues_decryptQueue; +extern struct workqueue_struct * sfold_queues_writeQueue; +extern struct workqueue_struct * sfold_queues_decryptQueue; /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -int sflc_queues_init(void); -void sflc_queues_exit(void); +int sfold_queues_init(void); +void sfold_queues_exit(void); -#endif /* _SFLC_UTILS_QUEUES_H_ */ +#endif /* _SFOLD_UTILS_QUEUES_H_ */ diff --git a/dm-sflc/volume/fmap.c b/dm-sflc/old/volume/fmap.c similarity index 81% rename from dm-sflc/volume/fmap.c rename to dm-sflc/old/volume/fmap.c index 980173a..63b837b 100644 --- a/dm-sflc/volume/fmap.c +++ b/dm-sflc/old/volume/fmap.c @@ -29,10 +29,10 @@ * INCLUDE SECTION * *****************************************************/ -#include "volume.h" -#include "crypto/rand/rand.h" -#include "utils/pools.h" -#include "log/log.h" +#include "old/volume/volume.h" +#include "old/crypto/rand/rand.h" +#include "old/utils/pools.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * @@ -42,7 +42,7 @@ * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op); +static s32 sfold_vol_mapSlice(sfold_Volume * vol, u32 lsi, int op); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * @@ -50,28 +50,28 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op); /* Maps a logical 512-byte sector to a physical 512-byte sector. Returns < 0 if error. * Specifically, if op == READ, and the logical slice is unmapped, -ENXIO is returned. */ -s64 sflc_vol_remapSector(sflc_Volume * vol, sector_t log_sector, int op, u32 * psi_out, u32 * off_in_slice_out) +s64 sfold_vol_remapSector(sfold_Volume * vol, sector_t log_sector, int op, u32 * psi_out, u32 * off_in_slice_out) { u32 lsi; u32 off_in_slice; s32 psi; sector_t phys_sector; - sflc_Device *dev = vol->dev; + sfold_Device *dev = vol->dev; /* Start by scaling down to a Shufflecake sector */ - log_sector /= SFLC_DEV_SECTOR_SCALE; + log_sector /= SFOLD_DEV_SECTOR_SCALE; /* Get the logical slice index it belongs to */ - lsi = log_sector / SFLC_VOL_LOG_SLICE_SIZE; + lsi = log_sector / SFOLD_VOL_LOG_SLICE_SIZE; /* Get which block it is within the slice */ - off_in_slice = log_sector % SFLC_VOL_LOG_SLICE_SIZE; + off_in_slice = log_sector % SFOLD_VOL_LOG_SLICE_SIZE; /* Output the off_in_slice */ if (off_in_slice_out) { *off_in_slice_out = off_in_slice; } /* Map it to a physical slice */ - psi = sflc_vol_mapSlice(vol, lsi, op); + psi = sfold_vol_mapSlice(vol, lsi, op); /* -ENXIO is a special case */ if (psi == -ENXIO) { pr_debug("mapSlice returned -ENXIO: stupid READ\n"); @@ -88,20 +88,20 @@ s64 sflc_vol_remapSector(sflc_Volume * vol, sector_t log_sector, int op, u32 * p } /* Get the physical sector (the first of every slice contains the IVs) */ - phys_sector = ((sector_t)psi * SFLC_DEV_PHYS_SLICE_SIZE) + 1 + off_in_slice; + phys_sector = ((sector_t)psi * SFOLD_DEV_PHYS_SLICE_SIZE) + 1 + off_in_slice; /* Add the device header */ phys_sector += dev->dev_header_size; /* Scale it back up to a kernel sector */ - phys_sector *= SFLC_DEV_SECTOR_SCALE; + phys_sector *= SFOLD_DEV_SECTOR_SCALE; return phys_sector; } /* Loads (and decrypts) the position map from the volume's header */ -int sflc_vol_loadFmap(sflc_Volume * vol) +int sfold_vol_loadFmap(sfold_Volume * vol) { - sflc_Device * dev = vol->dev; + sfold_Device * dev = vol->dev; sector_t sector; struct page * iv_page; u8 * iv_ptr; @@ -111,12 +111,12 @@ int sflc_vol_loadFmap(sflc_Volume * vol) int err; /* Allocate pages */ - iv_page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO); + iv_page = mempool_alloc(sfold_pools_pagePool, GFP_NOIO); if (!iv_page) { pr_err("Could not allocate IV page\n"); return -ENOMEM; } - data_page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO); + data_page = mempool_alloc(sfold_pools_pagePool, GFP_NOIO); if (!data_page) { pr_err("Could not allocate data page\n"); return -ENOMEM; @@ -145,7 +145,7 @@ int sflc_vol_loadFmap(sflc_Volume * vol) int i; for (i = 0; i < dev->vol_header_nr_iv_blocks && lsi < dev->tot_slices; i++) { /* Load the IV block */ - err = sflc_dev_rwSector(dev, iv_page, sector, READ); + err = sfold_dev_rwSector(dev, iv_page, sector, READ); if (err) { pr_err("Could not read IV block i=%d at sector %llu; error %d\n", i, sector, err); goto out; @@ -154,9 +154,9 @@ int sflc_vol_loadFmap(sflc_Volume * vol) /* Loop over the 256 data blocks */ int j; - for (j = 0; j < SFLC_DEV_SECTOR_TO_IV_RATIO && lsi < dev->tot_slices; j++) { + for (j = 0; j < SFOLD_DEV_SECTOR_TO_IV_RATIO && lsi < dev->tot_slices; j++) { /* Load the data block */ - err = sflc_dev_rwSector(dev, data_page, sector, READ); + err = sfold_dev_rwSector(dev, data_page, sector, READ); if (err) { pr_err("Could not read data block i=%d, j=%d at sector %llu; error %d\n", i, j, sector, err); goto out; @@ -164,7 +164,7 @@ int sflc_vol_loadFmap(sflc_Volume * vol) sector += 1; /* Decrypt it in place */ - err = sflc_sk_decrypt(vol->skctx, data_ptr, data_ptr, SFLC_DEV_SECTOR_SIZE, (iv_ptr + j*SFLC_SK_IV_LEN)); + err = sfold_sk_decrypt(vol->skctx, data_ptr, data_ptr, SFOLD_DEV_SECTOR_SIZE, (iv_ptr + j*SFOLD_SK_IV_LEN)); if (err) { pr_err("Could not decrypt data block i=%d, j=%d at sector %llu; error %d\n", i, j, sector, err); goto out; @@ -172,7 +172,7 @@ int sflc_vol_loadFmap(sflc_Volume * vol) /* Loop over the 1024 fmap entries in this data block */ int k; - for (k = 0; k < SFLC_VOL_HEADER_MAPPINGS_PER_BLOCK && lsi < dev->tot_slices; k++) { + for (k = 0; k < SFOLD_VOL_HEADER_MAPPINGS_PER_BLOCK && lsi < dev->tot_slices; k++) { /* An entry is just a single big-endian PSI, the LSI is implicitly the index of this entry */ __be32 * be_psi = (void *) (data_ptr + (k * sizeof(__be32))); @@ -181,8 +181,8 @@ int sflc_vol_loadFmap(sflc_Volume * vol) /* Add mapping to the volume's fmap */ vol->fmap[lsi] = psi; /* Also add it to the device's rmap and to the count, if LSI is actually mapped */ - if (psi != SFLC_VOL_FMAP_INVALID_PSI) { - sflc_dev_markPsiTaken(dev, psi, vol->vol_idx); + if (psi != SFOLD_VOL_FMAP_INVALID_PSI) { + sfold_dev_markPsiTaken(dev, psi, vol->vol_idx); vol->mapped_slices += 1; } @@ -202,16 +202,16 @@ out: kunmap(iv_page); kunmap(data_page); /* Free them */ - mempool_free(iv_page, sflc_pools_pagePool); - mempool_free(data_page, sflc_pools_pagePool); + mempool_free(iv_page, sfold_pools_pagePool); + mempool_free(data_page, sfold_pools_pagePool); return err; } /* Stores (and encrypts) the position map to the volume's header */ -int sflc_vol_storeFmap(sflc_Volume * vol) +int sfold_vol_storeFmap(sfold_Volume * vol) { - sflc_Device * dev = vol->dev; + sfold_Device * dev = vol->dev; sector_t sector; struct page * iv_page; u8 * iv_ptr; @@ -221,12 +221,12 @@ int sflc_vol_storeFmap(sflc_Volume * vol) int err; /* Allocate pages */ - iv_page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO); + iv_page = mempool_alloc(sfold_pools_pagePool, GFP_NOIO); if (!iv_page) { pr_err("Could not allocate IV page\n"); return -ENOMEM; } - data_page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO); + data_page = mempool_alloc(sfold_pools_pagePool, GFP_NOIO); if (!data_page) { pr_err("Could not allocate data page\n"); return -ENOMEM; @@ -255,13 +255,13 @@ int sflc_vol_storeFmap(sflc_Volume * vol) int i; for (i = 0; i < dev->vol_header_nr_iv_blocks && lsi < dev->tot_slices; i++) { /* Fill the IV block with random bytes */ - err = sflc_rand_getBytes(iv_ptr, SFLC_DEV_SECTOR_SIZE); + err = sfold_rand_getBytes(iv_ptr, SFOLD_DEV_SECTOR_SIZE); if (err) { pr_err("Could not sample random IV for block i=%d at sector %llu; error %d\n", i, sector, err); goto out; } /* Store it on the disk (before it gets changed by the encryption) */ - err = sflc_dev_rwSector(dev, iv_page, sector, WRITE); + err = sfold_dev_rwSector(dev, iv_page, sector, WRITE); if (err) { pr_err("Could not read IV block i=%d at sector %llu; error %d\n", i, sector, err); goto out; @@ -270,10 +270,10 @@ int sflc_vol_storeFmap(sflc_Volume * vol) /* Loop over the 256 data blocks */ int j; - for (j = 0; j < SFLC_DEV_SECTOR_TO_IV_RATIO && lsi < dev->tot_slices; j++) { + for (j = 0; j < SFOLD_DEV_SECTOR_TO_IV_RATIO && lsi < dev->tot_slices; j++) { /* Loop over the 1024 fmap entries that fit in this data block */ int k; - for (k = 0; k < SFLC_VOL_HEADER_MAPPINGS_PER_BLOCK && lsi < dev->tot_slices; k++) { + for (k = 0; k < SFOLD_VOL_HEADER_MAPPINGS_PER_BLOCK && lsi < dev->tot_slices; k++) { /* Get the PSI for the current LSI */ u32 psi = vol->fmap[lsi]; /* Write it into the block as big-endian */ @@ -285,14 +285,14 @@ int sflc_vol_storeFmap(sflc_Volume * vol) } /* Encrypt it in place */ - err = sflc_sk_encrypt(vol->skctx, data_ptr, data_ptr, SFLC_DEV_SECTOR_SIZE, (iv_ptr + j*SFLC_SK_IV_LEN)); + err = sfold_sk_encrypt(vol->skctx, data_ptr, data_ptr, SFOLD_DEV_SECTOR_SIZE, (iv_ptr + j*SFOLD_SK_IV_LEN)); if (err) { pr_err("Could not encrypt data block i=%d, j=%d at sector %llu; error %d\n", i, j, sector, err); goto out; } /* Store the data block */ - err = sflc_dev_rwSector(dev, data_page, sector, WRITE); + err = sfold_dev_rwSector(dev, data_page, sector, WRITE); if (err) { pr_err("Could not write data block i=%d, j=%d at sector %llu; error %d\n", i, j, sector, err); goto out; @@ -311,8 +311,8 @@ out: kunmap(iv_page); kunmap(data_page); /* Free them */ - mempool_free(iv_page, sflc_pools_pagePool); - mempool_free(data_page, sflc_pools_pagePool); + mempool_free(iv_page, sfold_pools_pagePool); + mempool_free(data_page, sfold_pools_pagePool); return err; } @@ -321,10 +321,10 @@ out: * PRIVATE FUNCTIONS DEFINITIONS * *****************************************************/ -static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op) +static s32 sfold_vol_mapSlice(sfold_Volume * vol, u32 lsi, int op) { s32 psi; - sflc_Device * dev = vol->dev; + sfold_Device * dev = vol->dev; /* Lock the volume's forward map */ if (mutex_lock_interruptible(&vol->fmap_lock)) { @@ -333,7 +333,7 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op) } /* If slice is already mapped, just return the mapping */ - if (vol->fmap[lsi] != SFLC_VOL_FMAP_INVALID_PSI) { + if (vol->fmap[lsi] != SFOLD_VOL_FMAP_INVALID_PSI) { mutex_unlock(&vol->fmap_lock); return vol->fmap[lsi]; } @@ -354,7 +354,7 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op) } /* Get a free physical slice */ - psi = sflc_dev_getNextRandomFreePsi(dev); + psi = sfold_dev_getNextRandomFreePsi(dev); if (psi < 0) { pr_err("Could not get a random free physical slice; error %d\n", psi); mutex_unlock(&dev->slices_lock); @@ -366,7 +366,7 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op) vol->fmap[lsi] = psi; vol->mapped_slices += 1; /* And in the device's rmap */ - sflc_dev_markPsiTaken(dev, psi, vol->vol_idx); + sfold_dev_markPsiTaken(dev, psi, vol->vol_idx); /* Unlock both maps */ mutex_unlock(&dev->slices_lock); diff --git a/dm-sflc/volume/io.c b/dm-sflc/old/volume/io.c similarity index 83% rename from dm-sflc/volume/io.c rename to dm-sflc/old/volume/io.c index 71ecc9c..6296834 100644 --- a/dm-sflc/volume/io.c +++ b/dm-sflc/old/volume/io.c @@ -29,10 +29,10 @@ * INCLUDE SECTION * *****************************************************/ -#include "volume.h" -#include "utils/pools.h" -#include "utils/workqueues.h" -#include "log/log.h" +#include "old/volume/volume.h" +#include "old/utils/pools.h" +#include "old/utils/workqueues.h" +#include "old/log/log.h" /***************************************************** * CONSTANTS * @@ -47,7 +47,7 @@ *****************************************************/ /* Remaps the underlying block device and the sector number */ -int sflc_vol_remapBioFast(sflc_Volume * vol, struct bio * bio) +int sfold_vol_remapBioFast(sfold_Volume * vol, struct bio * bio) { s64 phys_sector; int err; @@ -56,7 +56,7 @@ int sflc_vol_remapBioFast(sflc_Volume * vol, struct bio * bio) bio_set_dev(bio, vol->dev->bdev->bdev); /* Remap the starting sector (we don't care about PSI and off_in_slice). Also no slice allocation */ - phys_sector = sflc_vol_remapSector(vol, bio->bi_iter.bi_sector, READ, NULL, NULL); + phys_sector = sfold_vol_remapSector(vol, bio->bi_iter.bi_sector, READ, NULL, NULL); if (phys_sector < 0) { err = (int) phys_sector; pr_err("Could not remap sector; error %d\n", err); @@ -68,18 +68,18 @@ int sflc_vol_remapBioFast(sflc_Volume * vol, struct bio * bio) } /* Submits the bio to the device's workqueue */ -int sflc_vol_processBio(sflc_Volume * vol, struct bio * bio) +int sfold_vol_processBio(sfold_Volume * vol, struct bio * bio) { - sflc_vol_WriteWork * write_work; + sfold_vol_WriteWork * write_work; /* If it is a READ, no need to pass it through a workqueue */ if (bio_data_dir(bio) == READ) { - sflc_vol_doRead(vol, bio); + sfold_vol_doRead(vol, bio); return 0; } /* Allocate writeWork structure */ - write_work = mempool_alloc(sflc_pools_writeWorkPool, GFP_NOIO); + write_work = mempool_alloc(sfold_pools_writeWorkPool, GFP_NOIO); if (!write_work) { pr_err("Failed allocation of work structure\n"); return -ENOMEM; @@ -88,10 +88,10 @@ int sflc_vol_processBio(sflc_Volume * vol, struct bio * bio) /* Set fields */ write_work->vol = vol; write_work->orig_bio = bio; - INIT_WORK(&write_work->work, sflc_vol_doWrite); + INIT_WORK(&write_work->work, sfold_vol_doWrite); /* Enqueue */ - queue_work(sflc_queues_writeQueue, &write_work->work); + queue_work(sfold_queues_writeQueue, &write_work->work); return 0; } diff --git a/dm-sflc/volume/read.c b/dm-sflc/old/volume/read.c similarity index 72% rename from dm-sflc/volume/read.c rename to dm-sflc/old/volume/read.c index 2d64784..30e2927 100644 --- a/dm-sflc/volume/read.c +++ b/dm-sflc/old/volume/read.c @@ -32,10 +32,10 @@ * INCLUDE SECTION * *****************************************************/ -#include "volume.h" -#include "utils/pools.h" -#include "utils/workqueues.h" -#include "log/log.h" +#include "old/volume/volume.h" +#include "old/utils/pools.h" +#include "old/utils/workqueues.h" +#include "old/log/log.h" #include @@ -47,28 +47,28 @@ * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -static void sflc_vol_fillBioWithZeros(struct bio * orig_bio); -static void sflc_vol_readEndIo(struct bio * phys_bio); -static void sflc_vol_readEndIoBottomHalf(struct work_struct * work); -static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice); -static int sflc_vol_fetchIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice); +static void sfold_vol_fillBioWithZeros(struct bio * orig_bio); +static void sfold_vol_readEndIo(struct bio * phys_bio); +static void sfold_vol_readEndIoBottomHalf(struct work_struct * work); +static int sfold_vol_decryptBio(sfold_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice); +static int sfold_vol_fetchIv(sfold_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice); /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -/* Executed in context from sflc_tgt_map() */ -void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio) +/* Executed in context from sfold_tgt_map() */ +void sfold_vol_doRead(sfold_Volume * vol, struct bio * bio) { - sflc_Device * dev = vol->dev; + sfold_Device * dev = vol->dev; struct bio * orig_bio = bio; struct bio * phys_bio; s64 phys_sector; - sflc_vol_DecryptWork * dec_work; + sfold_vol_DecryptWork * dec_work; blk_status_t status; /* Allocate decryptWork structure */ - dec_work = mempool_alloc(sflc_pools_decryptWorkPool, GFP_NOIO); + dec_work = mempool_alloc(sfold_pools_decryptWorkPool, GFP_NOIO); if (!dec_work) { pr_err("Could not allocate decryptWork structure\n"); status = BLK_STS_IOERR; @@ -83,7 +83,7 @@ void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio) we can decrypt in place. */ /* Shallow copy */ - phys_bio = bio_alloc_clone(dev->bdev->bdev, orig_bio, GFP_NOIO, &sflc_pools_bioset); + phys_bio = bio_alloc_clone(dev->bdev->bdev, orig_bio, GFP_NOIO, &sfold_pools_bioset); if (!phys_bio) { pr_err("Could not clone original bio\n"); status = BLK_STS_IOERR; @@ -91,11 +91,11 @@ void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio) } /* Remap sector */ - phys_sector = sflc_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, READ, &dec_work->psi, &dec_work->off_in_slice); + phys_sector = sfold_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, READ, &dec_work->psi, &dec_work->off_in_slice); /* If -ENXIO, special case: stupid READ */ if (phys_sector == -ENXIO) { pr_debug("Stupid READ. Returning all zeros\n"); - sflc_vol_fillBioWithZeros(orig_bio); + sfold_vol_fillBioWithZeros(orig_bio); status = BLK_STS_OK; goto err_stupid_read; } @@ -113,7 +113,7 @@ void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio) dec_work->orig_bio = orig_bio; dec_work->phys_bio = phys_bio; /* Set fields for the endio */ - phys_bio->bi_end_io = sflc_vol_readEndIo; + phys_bio->bi_end_io = sfold_vol_readEndIo; phys_bio->bi_private = dec_work; /* Only submit the physical bio */ @@ -127,7 +127,7 @@ err_stupid_read: bio_put(phys_bio); err_clone_orig_bio: bio_put(orig_bio); - mempool_free(dec_work, sflc_pools_decryptWorkPool); + mempool_free(dec_work, sfold_pools_decryptWorkPool); err_alloc_dec_work: orig_bio->bi_status = status; @@ -139,42 +139,42 @@ err_alloc_dec_work: * PRIVATE FUNCTIONS DEFINITIONS * *****************************************************/ -static void sflc_vol_fillBioWithZeros(struct bio * orig_bio) +static void sfold_vol_fillBioWithZeros(struct bio * orig_bio) { struct bio_vec bvl = bio_iovec(orig_bio); void * sector_ptr = kmap(bvl.bv_page) + bvl.bv_offset; - memset(sector_ptr, 0, SFLC_DEV_SECTOR_SIZE); - bio_advance(orig_bio, SFLC_DEV_SECTOR_SIZE); + memset(sector_ptr, 0, SFOLD_DEV_SECTOR_SIZE); + bio_advance(orig_bio, SFOLD_DEV_SECTOR_SIZE); kunmap(bvl.bv_page); return; } /* Pushes all the decryption work to a workqueue bottom half */ -static void sflc_vol_readEndIo(struct bio * phys_bio) +static void sfold_vol_readEndIo(struct bio * phys_bio) { - sflc_vol_DecryptWork * dec_work = phys_bio->bi_private; + sfold_vol_DecryptWork * dec_work = phys_bio->bi_private; /* Init work structure */ - INIT_WORK(&dec_work->work, sflc_vol_readEndIoBottomHalf); + INIT_WORK(&dec_work->work, sfold_vol_readEndIoBottomHalf); /* Enqueue it */ - queue_work(sflc_queues_decryptQueue, &dec_work->work); + queue_work(sfold_queues_decryptQueue, &dec_work->work); return; } -static void sflc_vol_readEndIoBottomHalf(struct work_struct * work) +static void sfold_vol_readEndIoBottomHalf(struct work_struct * work) { - sflc_vol_DecryptWork * dec_work = container_of(work, sflc_vol_DecryptWork, work); - sflc_Volume * vol = dec_work->vol; + sfold_vol_DecryptWork * dec_work = container_of(work, sfold_vol_DecryptWork, work); + sfold_Volume * vol = dec_work->vol; struct bio * orig_bio = dec_work->orig_bio; struct bio * phys_bio = dec_work->phys_bio; blk_status_t status = phys_bio->bi_status; int err; /* Decrypt the physical bio and advance the original bio */ - err = sflc_vol_decryptBio(vol, orig_bio, dec_work->psi, dec_work->off_in_slice); + err = sfold_vol_decryptBio(vol, orig_bio, dec_work->psi, dec_work->off_in_slice); if (err) { pr_err("Could not decrypt bio; error %d\n", err); status = BLK_STS_IOERR; @@ -189,19 +189,19 @@ static void sflc_vol_readEndIoBottomHalf(struct work_struct * work) /* Free the physical bio */ bio_put(phys_bio); /* Free the work item */ - mempool_free(dec_work, sflc_pools_decryptWorkPool); + mempool_free(dec_work, sfold_pools_decryptWorkPool); return; } /* Decrypts the content of the physical bio, and at the same time it advances the original bio */ -static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice) +static int sfold_vol_decryptBio(sfold_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice) { - u8 iv[SFLC_SK_IV_LEN]; + u8 iv[SFOLD_SK_IV_LEN]; int err; /* Fetch IV */ - err = sflc_vol_fetchIv(vol, iv, psi, off_in_slice); + err = sfold_vol_fetchIv(vol, iv, psi, off_in_slice); if (err) { pr_err("Could not fetch IV; error %d\n", err); return err; @@ -210,7 +210,7 @@ static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi /* Decrypt sector in place */ struct bio_vec bvl = bio_iovec(orig_bio); void * sector_ptr = kmap(bvl.bv_page) + bvl.bv_offset; - err = sflc_sk_decrypt(vol->skctx, sector_ptr, sector_ptr, SFLC_DEV_SECTOR_SIZE, iv); + err = sfold_sk_decrypt(vol->skctx, sector_ptr, sector_ptr, SFOLD_DEV_SECTOR_SIZE, iv); kunmap(bvl.bv_page); if (err) { pr_err("Error while decrypting sector: %d\n", err); @@ -218,19 +218,19 @@ static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi } /* Advance original bio by one sector */ - bio_advance(orig_bio, SFLC_DEV_SECTOR_SIZE); + bio_advance(orig_bio, SFOLD_DEV_SECTOR_SIZE); return 0; } -static int sflc_vol_fetchIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice) +static int sfold_vol_fetchIv(sfold_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice) { - sflc_Device * dev = vol->dev; + sfold_Device * dev = vol->dev; u8 * iv_block; int err; /* Acquire a reference to the whole relevant IV block */ - iv_block = sflc_dev_getIvBlockRef(dev, psi, READ); + iv_block = sfold_dev_getIvBlockRef(dev, psi, READ); if (IS_ERR(iv_block)) { err = PTR_ERR(iv_block); pr_err("Could not acquire reference to IV block; error %ld\n", PTR_ERR(iv_block)); @@ -238,10 +238,10 @@ static int sflc_vol_fetchIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slic } /* Copy the relevant portion */ - memcpy(iv, iv_block + (off_in_slice * SFLC_SK_IV_LEN), SFLC_SK_IV_LEN); + memcpy(iv, iv_block + (off_in_slice * SFOLD_SK_IV_LEN), SFOLD_SK_IV_LEN); /* Release reference to the IV block */ - err = sflc_dev_putIvBlockRef(dev, psi); + err = sfold_dev_putIvBlockRef(dev, psi); if (err) { pr_err("Could not release reference to IV block; error %d\n", err); goto err_put_iv_block_ref; diff --git a/dm-sflc/volume/volume.c b/dm-sflc/old/volume/volume.c similarity index 57% rename from dm-sflc/volume/volume.c rename to dm-sflc/old/volume/volume.c index ec4dedc..e8b97b6 100644 --- a/dm-sflc/volume/volume.c +++ b/dm-sflc/old/volume/volume.c @@ -29,8 +29,9 @@ * INCLUDE SECTION * *****************************************************/ -#include "volume.h" -#include "log/log.h" +#include "old/volume/volume.h" +#include "old/utils/string.h" +#include "old/log/log.h" #include @@ -39,35 +40,64 @@ * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -/* Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful */ -sflc_Volume * sflc_vol_create(struct dm_target *ti, sflc_Device *dev, int vol_idx, u8 * enckey) +/** + * Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful + * Arguments: + * argv[0]: Shufflecake mode: legacy/lite + * argv[1]: Shufflecake-unique device ID + * argv[2]: path to underlying physical device + * argv[3]: volume index within the device + * argv[4]: number of 1 MB slices in the underlying device + * argv[5]: 32-byte encryption key (hex-encoded) + */ +sfold_Volume * sfold_vol_create(struct dm_target * ti, sfold_Device* dev, + int argc, char **argv, struct kobject *kobj) { - sflc_Volume * vol; + sfold_Volume * vol; + int vol_idx; + u8 enckey[SFOLD_SK_KEY_LEN]; int err; - pr_debug("Called to create sflc_Volume #%d on Device %s\n", vol_idx, dev->bdev_path); - /* Allocate volume */ - vol = kzalloc(sizeof(sflc_Volume), GFP_KERNEL); + vol = kzalloc(sizeof(sfold_Volume), GFP_KERNEL); if (!vol) { - pr_err("Could not allocate %lu bytes for sflc_Volume\n", sizeof(sflc_Volume)); + pr_err("Could not allocate %lu bytes for sfold_Volume\n", sizeof(sfold_Volume)); err = -ENOMEM; goto err_alloc_vol; } + /* Parse args */ + if (sscanf(argv[3], "%u", &vol_idx) != 1) { + pr_err("Could not decode tot_slices\n"); + err = -EINVAL; + goto err_parse; + } + /* Decode the encryption key */ + if (strlen(argv[5]) != 2 * SFOLD_SK_KEY_LEN) { + pr_err("Hexadecimal key (length %lu): %s\n", strlen(argv[5]), argv[5]); + err = -EINVAL; + goto err_parse; + } + err = sfold_str_hexDecode(argv[5], enckey); + if (err) { + pr_err("Could not decode hexadecimal encryption key"); + err = -EINVAL; + goto err_parse; + } + /* Set volume name */ - sprintf(vol->vol_name, "sflc_%lu_%d", dev->dev_id, vol_idx); + sprintf(vol->vol_name, "sflc_%u_%d", dev->dev_id, vol_idx); /* Sysfs stuff */ - vol->kvol = sflc_sysfs_volCreateAndAdd(vol); - if (IS_ERR(vol->kvol)) { - err = PTR_ERR(vol->kvol); - pr_err("Could not create sysfs entry; error %d\n", err); + vol->kobj_parent = kobj; + err = sfold_sysfs_add_volume(vol); + if (err) { + pr_err("Could not add volume to sysfs; error %d\n", err); goto err_sysfs; } /* Backing device */ - if (!sflc_dev_addVolume(dev, vol, vol_idx)) { + if (!sfold_dev_addVolume(dev, vol, vol_idx)) { pr_err("Could not add volume to device\n"); err = -EINVAL; goto err_add_to_dev; @@ -76,7 +106,7 @@ sflc_Volume * sflc_vol_create(struct dm_target *ti, sflc_Device *dev, int vol_id vol->vol_idx = vol_idx; /* Crypto */ - vol->skctx = sflc_sk_createContext(enckey); + vol->skctx = sfold_sk_createContext(enckey); if (IS_ERR(vol->skctx)) { err = PTR_ERR(vol->skctx); pr_err("Could not create crypto context\n"); @@ -97,38 +127,52 @@ sflc_Volume * sflc_vol_create(struct dm_target *ti, sflc_Device *dev, int vol_id /* Initialise fmap */ pr_notice("Volume opening for volume %s: loading fmap from header\n", vol->vol_name); - err = sflc_vol_loadFmap(vol); + err = sfold_vol_loadFmap(vol); if (err) { pr_err("Could not load position map; error %d\n", err); goto err_load_fmap; } pr_debug("Successfully loaded position map for volume %s\n", vol->vol_name); + + /* Tell DM we want one SFLC sector at a time */ + ti->max_io_len = SFOLD_DEV_SECTOR_SCALE; + /* Enable REQ_OP_FLUSH bios */ + ti->num_flush_bios = 1; + /* Disable REQ_OP_WRITE_ZEROES and REQ_OP_SECURE_ERASE (can't be passed through as + they would break deniability, and they would be too complicated to handle individually) */ + ti->num_secure_erase_bios = 0; + ti->num_write_zeroes_bios = 0; + /* Momentarily disable REQ_OP_DISCARD_BIOS + TODO: will need to support them to release slice mappings */ + ti->num_discard_bios = 0; + return vol; err_load_fmap: vfree(vol->fmap); err_alloc_fmap: - sflc_sk_destroyContext(vol->skctx); + sfold_sk_destroyContext(vol->skctx); err_create_skctx: - sflc_dev_removeVolume(vol->dev, vol->vol_idx); + sfold_dev_removeVolume(vol->dev, vol->vol_idx); err_add_to_dev: - sflc_sysfs_putVol(vol->kvol); + sfold_sysfs_remove_volume(vol); err_sysfs: +err_parse: kfree(vol); err_alloc_vol: return ERR_PTR(err); } /* Removes the volume from the device and frees it. */ -void sflc_vol_destroy(struct dm_target * ti, sflc_Volume * vol) +void sfold_vol_destroy(sfold_Volume * vol) { int err; /* Store fmap */ pr_notice("Going to store position map of volume %s\n", vol->vol_name); - err = sflc_vol_storeFmap(vol); + err = sfold_vol_storeFmap(vol); if (err) { pr_err("Could not store position map; error %d\n", err); } @@ -137,13 +181,13 @@ void sflc_vol_destroy(struct dm_target * ti, sflc_Volume * vol) vfree(vol->fmap); /* Skctx */ - sflc_sk_destroyContext(vol->skctx); + sfold_sk_destroyContext(vol->skctx); /* Remove from device */ - sflc_dev_removeVolume(vol->dev, vol->vol_idx); + sfold_dev_removeVolume(vol->dev, vol->vol_idx); /* Destroy sysfs entries */ - sflc_sysfs_putVol(vol->kvol); + sfold_sysfs_remove_volume(vol); /* Free volume structure */ kfree(vol); diff --git a/dm-sflc/volume/volume.h b/dm-sflc/old/volume/volume.h similarity index 70% rename from dm-sflc/volume/volume.h rename to dm-sflc/old/volume/volume.h index 401cd97..38faf40 100644 --- a/dm-sflc/volume/volume.h +++ b/dm-sflc/old/volume/volume.h @@ -26,8 +26,8 @@ * a "real" device represented by a device. */ -#ifndef _SFLC_VOLUME_VOLUME_H_ -#define _SFLC_VOLUME_VOLUME_H_ +#ifndef _SFOLD_VOLUME_VOLUME_H_ +#define _SFOLD_VOLUME_VOLUME_H_ /***************************************************** @@ -36,9 +36,9 @@ /* Necessary since device.h, volume.h, and sysfs.h all include each other */ -typedef struct sflc_vol_write_work_s sflc_vol_WriteWork; -typedef struct sflc_vol_decrypt_work_s sflc_vol_DecryptWork; -typedef struct sflc_volume_s sflc_Volume; +typedef struct sfold_vol_write_work_s sfold_vol_WriteWork; +typedef struct sfold_vol_decrypt_work_s sfold_vol_DecryptWork; +typedef struct sfold_volume_s sfold_Volume; /***************************************************** @@ -47,9 +47,9 @@ typedef struct sflc_volume_s sflc_Volume; #include -#include "device/device.h" -#include "crypto/symkey/symkey.h" -#include "sysfs/sysfs.h" +#include "old/sflc_old.h" +#include "old/device/device.h" +#include "old/crypto/symkey/symkey.h" /***************************************************** @@ -57,26 +57,26 @@ typedef struct sflc_volume_s sflc_Volume; *****************************************************/ /* A single header data block contains 1024 fmap mappings */ -#define SFLC_VOL_HEADER_MAPPINGS_PER_BLOCK (SFLC_DEV_SECTOR_SIZE / sizeof(u32)) +#define SFOLD_VOL_HEADER_MAPPINGS_PER_BLOCK (SFOLD_DEV_SECTOR_SIZE / sizeof(u32)) /* We split the volume's logical addressing space into 1 MB slices */ -#define SFLC_VOL_LOG_SLICE_SIZE 256 // In 4096-byte sectors +#define SFOLD_VOL_LOG_SLICE_SIZE 256 // In 4096-byte sectors /* Value marking an LSI as unassigned */ -#define SFLC_VOL_FMAP_INVALID_PSI 0xFFFFFFFFU +#define SFOLD_VOL_FMAP_INVALID_PSI 0xFFFFFFFFU /* The volume name is "sflc--" */ -#define SFLC_VOL_NAME_MAX_LEN 12 +#define SFOLD_VOL_NAME_MAX_LEN 12 /***************************************************** * TYPES * *****************************************************/ -struct sflc_vol_write_work_s +struct sfold_vol_write_work_s { /* Essential information */ - sflc_Volume * vol; + sfold_Volume * vol; struct bio * orig_bio; /* Write requests need to allocate own page */ @@ -86,10 +86,10 @@ struct sflc_vol_write_work_s struct work_struct work; }; -struct sflc_vol_decrypt_work_s +struct sfold_vol_decrypt_work_s { /* Essential information */ - sflc_Volume * vol; + sfold_Volume * vol; struct bio * orig_bio; struct bio * phys_bio; @@ -101,15 +101,15 @@ struct sflc_vol_decrypt_work_s struct work_struct work; }; -struct sflc_volume_s +struct sfold_volume_s { - /* Name of the volume, sflc--*/ - char vol_name[SFLC_VOL_NAME_MAX_LEN + 1]; + /* Name of the volume, sflc__*/ + char vol_name[SFOLD_VOL_NAME_MAX_LEN + 1]; /* Backing device */ - sflc_Device * dev; + sfold_Device * dev; /* Index of this volume within the device's volume array */ - int vol_idx; + u32 vol_idx; /* Forward position map */ struct mutex fmap_lock; @@ -117,11 +117,11 @@ struct sflc_volume_s /* Stats on the fmap */ u32 mapped_slices; - /* Sysfs stuff */ - sflc_sysfs_Volume * kvol; + /* Parent sysfs directory */ + struct kobject *kobj_parent; /* Crypto */ - sflc_sk_Context * skctx; + sfold_sk_Context * skctx; }; @@ -130,27 +130,28 @@ struct sflc_volume_s *****************************************************/ /* Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful */ -sflc_Volume * sflc_vol_create(struct dm_target * ti, sflc_Device* dev, int vol_idx, u8 * enckey); +sfold_Volume * sfold_vol_create(struct dm_target * ti, sfold_Device* dev, + int argc, char **argv, struct kobject *kobj); /* Removes the volume from the device and frees it. */ -void sflc_vol_destroy(struct dm_target * ti, sflc_Volume * vol); +void sfold_vol_destroy(sfold_Volume * vol); /* Remaps the underlying block device and the sector number */ -int sflc_vol_remapBioFast(sflc_Volume * vol, struct bio * bio); +int sfold_vol_remapBioFast(sfold_Volume * vol, struct bio * bio); /* Processes the bio in the normal indirection+crypto way */ -int sflc_vol_processBio(sflc_Volume * vol, struct bio * bio); +int sfold_vol_processBio(sfold_Volume * vol, struct bio * bio); /* Executed in top half */ -void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio); +void sfold_vol_doRead(sfold_Volume * vol, struct bio * bio); /* Executed in bottom half */ -void sflc_vol_doWrite(struct work_struct * work); +void sfold_vol_doWrite(struct work_struct * work); /* Maps a logical 512-byte sector to a physical 512-byte sector. Returns < 0 if error. * Specifically, if op == READ, and the logical slice is unmapped, -ENXIO is returned. */ -s64 sflc_vol_remapSector(sflc_Volume * vol, sector_t log_sector, int op, u32 * psi_out, u32 * off_in_slice_out); +s64 sfold_vol_remapSector(sfold_Volume * vol, sector_t log_sector, int op, u32 * psi_out, u32 * off_in_slice_out); /* Loads (and decrypts) the position map from the volume's header */ -int sflc_vol_loadFmap(sflc_Volume * vol); +int sfold_vol_loadFmap(sfold_Volume * vol); /* Stores (and encrypts) the position map to the volume's header */ -int sflc_vol_storeFmap(sflc_Volume * vol); +int sfold_vol_storeFmap(sfold_Volume * vol); -#endif /* _SFLC_VOLUME_VOLUME_H_ */ +#endif /* _SFOLD_VOLUME_VOLUME_H_ */ diff --git a/dm-sflc/volume/write.c b/dm-sflc/old/volume/write.c similarity index 77% rename from dm-sflc/volume/write.c rename to dm-sflc/old/volume/write.c index 007783a..bbf113c 100644 --- a/dm-sflc/volume/write.c +++ b/dm-sflc/old/volume/write.c @@ -32,10 +32,10 @@ * INCLUDE SECTION * *****************************************************/ -#include "volume.h" -#include "crypto/rand/rand.h" -#include "utils/pools.h" -#include "log/log.h" +#include "old/volume/volume.h" +#include "old/crypto/rand/rand.h" +#include "old/utils/pools.h" +#include "old/log/log.h" #include @@ -47,9 +47,9 @@ * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice); -static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice); -static void sflc_vol_writeEndIo(struct bio * phys_bio); +static int sfold_vol_encryptOrigBio(sfold_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice); +static int sfold_vol_sampleAndWriteIv(sfold_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice); +static void sfold_vol_writeEndIo(struct bio * phys_bio); /***************************************************** * PRIVATE VARIABLES * @@ -60,11 +60,11 @@ static void sflc_vol_writeEndIo(struct bio * phys_bio); *****************************************************/ /* Executed in workqueue bottom half */ -void sflc_vol_doWrite(struct work_struct * work) +void sfold_vol_doWrite(struct work_struct * work) { - sflc_vol_WriteWork * write_work = container_of(work, sflc_vol_WriteWork, work); - sflc_Volume * vol = write_work->vol; - sflc_Device * dev = vol->dev; + sfold_vol_WriteWork * write_work = container_of(work, sfold_vol_WriteWork, work); + sfold_Volume * vol = write_work->vol; + sfold_Device * dev = vol->dev; struct bio * orig_bio = write_work->orig_bio; struct bio * phys_bio; s64 phys_sector; @@ -80,14 +80,14 @@ void sflc_vol_doWrite(struct work_struct * work) non-owned bio's. So we need our own. */ /* Allocate an empty bio */ - phys_bio = bio_alloc_bioset(dev->bdev->bdev, bio_segments(orig_bio), orig_bio->bi_opf, GFP_NOIO, &sflc_pools_bioset); + phys_bio = bio_alloc_bioset(dev->bdev->bdev, bio_segments(orig_bio), orig_bio->bi_opf, GFP_NOIO, &sfold_pools_bioset); if (!phys_bio) { pr_err("Could not allocate bio\n"); goto err_alloc_phys_bio; } /* Remap sector */ - phys_sector = sflc_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, WRITE, &psi, &off_in_slice); + phys_sector = sfold_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, WRITE, &psi, &off_in_slice); if (phys_sector < 0) { pr_err("Could not remap sector for physical bio; error %d\n", (int) phys_sector); goto err_remap_sector; @@ -95,11 +95,11 @@ void sflc_vol_doWrite(struct work_struct * work) phys_bio->bi_iter.bi_sector = phys_sector; /* Set fields for the endio */ - phys_bio->bi_end_io = sflc_vol_writeEndIo; + phys_bio->bi_end_io = sfold_vol_writeEndIo; phys_bio->bi_private = write_work; /* Encrypt the original bio into the physical bio (newly-allocated pages) */ - int err = sflc_vol_encryptOrigBio(vol, orig_bio, phys_bio, psi, off_in_slice); + int err = sfold_vol_encryptOrigBio(vol, orig_bio, phys_bio, psi, off_in_slice); if (err) { pr_err("Could not encrypt original bio; error %d\n", err); goto err_encrypt_orig_bio; @@ -127,14 +127,14 @@ err_alloc_phys_bio: *****************************************************/ /* Encrypts the contents of the original bio into newly-allocated pages for the physical bio */ -static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice) +static int sfold_vol_encryptOrigBio(sfold_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice) { - sflc_vol_WriteWork * write_work = phys_bio->bi_private; - u8 iv[SFLC_SK_IV_LEN]; + sfold_vol_WriteWork * write_work = phys_bio->bi_private; + u8 iv[SFOLD_SK_IV_LEN]; int err; /* Allocate new page for the physical bio */ - write_work->page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO); + write_work->page = mempool_alloc(sfold_pools_pagePool, GFP_NOIO); if (!write_work->page) { pr_err("Could not allocate page\n"); err = -ENOMEM; @@ -142,14 +142,14 @@ static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, str } /* Add it to physical bio */ - if (!bio_add_page(phys_bio, write_work->page, SFLC_DEV_SECTOR_SIZE, 0)) { + if (!bio_add_page(phys_bio, write_work->page, SFOLD_DEV_SECTOR_SIZE, 0)) { pr_err("Catastrophe. Could not add page to copy bio. WTF?\n"); err = -EIO; goto err_bio_add_page; } /* Sample a random IV and write it in the IV block */ - err = sflc_vol_sampleAndWriteIv(vol, iv, psi, off_in_slice); + err = sfold_vol_sampleAndWriteIv(vol, iv, psi, off_in_slice); if (err) { pr_err("Could not sample and write IV; error %d\n", err); err = -EIO; @@ -160,7 +160,7 @@ static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, str struct bio_vec bvl = bio_iovec(orig_bio); void * enc_sector_ptr = kmap(write_work->page); void * plain_sector_ptr = kmap(bvl.bv_page) + bvl.bv_offset; - err = sflc_sk_encrypt(vol->skctx, plain_sector_ptr, enc_sector_ptr, SFLC_DEV_SECTOR_SIZE, iv); + err = sfold_sk_encrypt(vol->skctx, plain_sector_ptr, enc_sector_ptr, SFOLD_DEV_SECTOR_SIZE, iv); kunmap(bvl.bv_page); kunmap(write_work->page); if (err) { @@ -174,21 +174,21 @@ static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, str err_encrypt: err_sample_and_write_iv: err_bio_add_page: - mempool_free(write_work->page, sflc_pools_pagePool); + mempool_free(write_work->page, sfold_pools_pagePool); err_alloc_page: return err; } /* Allocates the io_work's IV (will need to be freed afterwards), fills it with random bytes, and writes it into the IV block pointed by the io_work's PSI and off_in_slice. */ -static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice) +static int sfold_vol_sampleAndWriteIv(sfold_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice) { - sflc_Device * dev = vol->dev; + sfold_Device * dev = vol->dev; u8 * iv_block; int err; /* Sample IV */ - err = sflc_rand_getBytes(iv, SFLC_SK_IV_LEN); + err = sfold_rand_getBytes(iv, SFOLD_SK_IV_LEN); if (err) { pr_err("Could not sample IV; error %d\n", err); err = -EIO; @@ -196,7 +196,7 @@ static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 of } /* Acquire a reference to the whole relevant IV block */ - iv_block = sflc_dev_getIvBlockRef(dev, psi, WRITE); + iv_block = sfold_dev_getIvBlockRef(dev, psi, WRITE); if (IS_ERR(iv_block)) { err = PTR_ERR(iv_block); pr_err("Could not acquire reference to IV block; error %d\n", err); @@ -204,10 +204,10 @@ static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 of } /* Copy it into the relevant portion of the block */ - memcpy(iv_block + (off_in_slice * SFLC_SK_IV_LEN), iv, SFLC_SK_IV_LEN); + memcpy(iv_block + (off_in_slice * SFOLD_SK_IV_LEN), iv, SFOLD_SK_IV_LEN); /* Release reference to the IV block */ - err = sflc_dev_putIvBlockRef(dev, psi); + err = sfold_dev_putIvBlockRef(dev, psi); if (err) { pr_err("Could not release reference to IV block; error %d\n", err); goto err_put_iv_block_ref; @@ -222,9 +222,9 @@ err_sample_iv: return err; } -static void sflc_vol_writeEndIo(struct bio * phys_bio) +static void sfold_vol_writeEndIo(struct bio * phys_bio) { - sflc_vol_WriteWork * write_work = phys_bio->bi_private; + sfold_vol_WriteWork * write_work = phys_bio->bi_private; struct bio * orig_bio = write_work->orig_bio; unsigned completed_bytes; @@ -245,8 +245,8 @@ static void sflc_vol_writeEndIo(struct bio * phys_bio) if (unlikely(page_ref_count(write_work->page) != 1)) { pr_err("WTF: page_ref_count = %d\n", page_ref_count(write_work->page)); } - mempool_free(write_work->page, sflc_pools_pagePool); - mempool_free(write_work, sflc_pools_writeWorkPool); + mempool_free(write_work->page, sfold_pools_pagePool); + mempool_free(write_work, sfold_pools_writeWorkPool); return; } diff --git a/dm-sflc/sflc.c b/dm-sflc/sflc.c new file mode 100644 index 0000000..0938fb0 --- /dev/null +++ b/dm-sflc/sflc.c @@ -0,0 +1,270 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include + +#include "sflc.h" +#include "old/sflc_old.h" + + +// Global variables +DEFINE_MUTEX(sflc_alldevs_lock); +struct sflc_device **sflc_alldevs = NULL; +u32 sflc_free_devid = 0; /* The lowest free devID */ + + +/* Add a device to the global array, and advance next_dev_id */ +static int sflc_add_device_global(u32 dev_id, struct sflc_device *sdev) +{ + int i; + + if (mutex_lock_interruptible(&sflc_alldevs_lock)) + return -ERESTARTSYS; + + /* Check for dev_id conflict, possible because a read() to next_dev_id + * in sysfs can return the same value to two processes */ + if (sflc_alldevs[dev_id]) { + mutex_unlock(&sflc_alldevs_lock); + DMERR("A device with this ID already exists. Retry"); + return -EINVAL; + } + // Add to the global array, and advance free_devid + sflc_alldevs[dev_id] = sdev; + for (i = sflc_free_devid; i < SFLC_MAX_DEVS && sflc_alldevs[i]; i++); + sflc_free_devid = i; + + mutex_unlock(&sflc_alldevs_lock); + + return 0; +} + +/* Remove a device from the global array, and update next_dev_id */ +static void sflc_remove_device_global(u32 dev_id) +{ + if (mutex_lock_interruptible(&sflc_alldevs_lock)) + return; + sflc_alldevs[dev_id] = NULL; + if (dev_id < sflc_free_devid) + sflc_free_devid = dev_id; + mutex_unlock(&sflc_alldevs_lock); +} + + +/* + * Create volume and, if not existent, the underlying device. + * Arguments: + * argv[0]: Shufflecake mode: legacy/lite + * argv[1]: Shufflecake-unique device ID + * argv[2]: path to underlying physical device + * argv[3]: volume index within the device + * argv[4:]: mode-specific parameters + */ +static int sflc_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + u32 dev_id; + u32 vol_idx; + struct sflc_device *sdev; + struct sflc_volume *svol; + int err; + + /* Parse arguments */ + if (argc < 4) { + ti->error = "Invalid argument count"; + return -EINVAL; + } + if (sscanf(argv[1], "%u", &dev_id) != 1) { + ti->error = "Could not decode device ID"; + return -EINVAL; + } + if (sscanf(argv[3], "%u", &vol_idx) != 1) { + ti->error = "Could not decode volume index"; + return -EINVAL; + } + /* Sanity checks */ + if (dev_id >= SFLC_MAX_DEVS) { + ti->error = "Device ID out of bounds"; + return -EINVAL; + } + if (vol_idx >= SFLC_DEV_MAX_VOLUMES) { + ti->error = "Volume index out of bounds"; + return -EINVAL; + } + + /* Create device, if this is the first volume, otherwise retrieve it */ + if (vol_idx == 0) { + sdev = sflc_dev_create(ti, argc, argv); + if (IS_ERR(sdev)) { + ti->error = "Could not instantiate device"; + return PTR_ERR(sdev); + } + /* Insert in global array */ + err = sflc_add_device_global(dev_id, sdev); + if (err) { + ti->error = "Could not add device to global array"; + goto bad_dev_global; + } + } else { + if (mutex_lock_interruptible(&sflc_alldevs_lock)) + return -ERESTARTSYS; + sdev = sflc_alldevs[dev_id]; + mutex_unlock(&sflc_alldevs_lock); + + if (!sdev) { + ti->error = "Could not find device with specified ID"; + return -EINVAL; + } + } + + /* Create volume */ + svol = sflc_vol_create(sdev, ti, argc, argv); + if (IS_ERR(svol)) { + ti->error = "Could not instantiate volume"; + err = PTR_ERR(svol); + goto bad_vol_create; + } + /* We expect ->ctr() calls to be strictly sequential, so we don't need locking */ + sdev->nr_volumes++; + + ti->private = svol; + + return 0; + + +bad_vol_create: + if (vol_idx == 0) { + sflc_remove_device_global(dev_id); +bad_dev_global: + sflc_dev_destroy(sdev); + } + return err; +} + + +/* Destroy volume and, if needed, the underlying device */ +static void sflc_dtr(struct dm_target *ti) +{ + struct sflc_volume *svol = ti->private; + struct sflc_device *sdev = svol->sdev; + + sflc_vol_destroy(svol); + /* We expect ->dtr() calls to be strictly sequential, so we don't need locking */ + sdev->nr_volumes--; + + if (sdev->nr_volumes == 0) { + sflc_remove_device_global(sdev->dev_id); + sflc_dev_destroy(sdev); + } + + return; +} + + +static int sflc_map(struct dm_target *ti, struct bio *bio) +{ + struct sflc_volume *svol = ti->private; + return svol->tt->map(ti, bio); +} + +static void sflc_io_hints(struct dm_target *ti, struct queue_limits *limits) +{ + struct sflc_volume *svol = ti->private; + svol->tt->io_hints(ti, limits); + return; +} + +static int sflc_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) +{ + struct sflc_volume *svol = ti->private; + return svol->tt->iterate_devices(ti, fn, data); +} + + +/* + *---------------------------- + * Kernel module + *---------------------------- + */ + +static struct target_type sflc_target_type = { + .name = SFLC_TARGET_NAME, + .version = {SFLC_VER_MAJOR, SFLC_VER_MINOR, SFLC_VER_REVISION}, + .module = THIS_MODULE, + .ctr = sflc_ctr, + .dtr = sflc_dtr, + .map = sflc_map, + .io_hints = sflc_io_hints, + .iterate_devices = sflc_iterate_devices, +}; + + +/* Module entry point */ +static int sflc_init(void) +{ + int ret; + + /* Create the first sysfs entries */ + ret = sflc_sysfs_init(); + if (ret) + goto err_sysfs; + + /* Init the legacy module */ + ret = sfold_init(); + if (ret) + goto err_sfold; + + /* Register the DM callbacks */ + ret = dm_register_target(&sflc_target_type); + if (ret < 0) + goto err_dm; + + DMINFO("loaded"); + return 0; + + +err_dm: + sfold_exit(); +err_sfold: + sflc_sysfs_exit(); +err_sysfs: + return ret; +} + + +/* Module exit point */ +static void sflc_exit(void) +{ + dm_unregister_target(&sflc_target_type); + sfold_exit(); + sflc_sysfs_exit(); + + DMINFO("unloaded"); + return; +} + + +module_init(sflc_init); +module_exit(sflc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Toninov"); diff --git a/dm-sflc/sflc.h b/dm-sflc/sflc.h new file mode 100644 index 0000000..6248f74 --- /dev/null +++ b/dm-sflc/sflc.h @@ -0,0 +1,117 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _SFLC_H +#define _SFLC_H + + +#include + +#include "sflc_constants.h" +#include "old/sflc_old.h" + + +/* + *---------------------------- + * Structs + *---------------------------- + */ + +struct sflc_device +{ + /* Shufflecake-unique device ID */ + u32 dev_id; + /* : */ + char name[16]; + /* Number of volumes */ + u32 nr_volumes; + + /* Mode-specific device struct */ + int mode; + union { + sfold_Device *sfold_dev; + }; + + /* Sysfs */ + struct kobject kobj; + struct completion kobj_released; +}; + +struct sflc_volume +{ + /* Backing device */ + struct sflc_device *sdev; + /* Volume name: sflc__ */ + char name[32]; + + /* Mode-specific volume struct */ + int mode; + union { + sfold_Volume *sfold_vol; + }; + /* Pointers to concrete, mode-specific callbacks */ + struct target_type *tt; + + /* Sysfs */ + struct kobject kobj; + struct completion kobj_released; +}; + + +/* + *---------------------------- + * Global variables + *---------------------------- + */ + +extern struct mutex sflc_alldevs_lock; +extern struct sflc_device **sflc_alldevs; +/* Next free device id */ +extern u32 sflc_free_devid; /* The lowest free devID */ + + +/* + *---------------------------- + * Functions + *---------------------------- + */ + +/* Device */ +struct sflc_device *sflc_dev_create(struct dm_target *ti, int argc, char **argv); +void sflc_dev_destroy(struct sflc_device *sdev); + +/* Volume */ +struct sflc_volume *sflc_vol_create(struct sflc_device *sdev, struct dm_target *ti, + int argc, char **argv); +void sflc_vol_destroy(struct sflc_volume *svol); + +/* Sysfs */ +int sflc_sysfs_init(void); +void sflc_sysfs_exit(void); +int sflc_sysfs_register_device(struct sflc_device *sdev); +void sflc_sysfs_unregister_device(struct sflc_device *sdev); +int sflc_sysfs_register_volume(struct sflc_volume *svol); +void sflc_sysfs_unregister_volume(struct sflc_volume *svol); + + +#endif /* _SFLC_H */ diff --git a/dm-sflc/sflc_constants.h b/dm-sflc/sflc_constants.h index 5b4668a..c978796 100644 --- a/dm-sflc/sflc_constants.h +++ b/dm-sflc/sflc_constants.h @@ -21,15 +21,18 @@ * If not, see . */ -/***************************************************** - * PLACEHOLDER * - *****************************************************/ +/* Here we gather Shufflecake-wide constants, independent of the mode (legacy/lite) */ -/* This is just a placeholder for defining constants and parameters that must be the same across shufflecake components (kernel module, userland tool, etc) such as block size, slice size etc */ +#ifndef _SFLC_CONSTANTS_H_ +#define _SFLC_CONSTANTS_H_ + + +#define SFLC_TARGET_NAME "shufflecake" +#define DM_MSG_PREFIX "sflc" #define SFLC_VER_MAJOR 0 -#define SFLC_VER_MINOR 4 +#define SFLC_VER_MINOR 5 #define SFLC_VER_REVISION 0 #define SFLC_VER_SPECIAL "rc1" @@ -39,3 +42,20 @@ #define SFLC_VERSION STRINGIFY(SFLC_VER_MAJOR)"."STRINGIFY(SFLC_VER_MINOR)"."STRINGIFY(SFLC_VER_REVISION)""SFLC_VER_SPECIAL +/* Each device can be formatted and used with a mode of choice, irrespective of the other devices */ +#define SFLC_MODE_LEGACY 0 +#define SFLC_MODE_LITE 1 + + +/* Max number of volumes per device */ +#define SFLC_DEV_MAX_VOLUMES 15 +/* Max number of open devices at any given time */ +#define SFLC_MAX_DEVS 1024 + + +/* Sysfs entries under /sys/module/dm_sflc/ */ +#define SFLC_SYSFS_BDEVS "bdevs" +#define SFLC_SYSFS_DEVID "next_dev_id" + + +#endif /* _SFLC_CONSTANTS_H_ */ diff --git a/dm-sflc/sysfs.c b/dm-sflc/sysfs.c new file mode 100644 index 0000000..acea092 --- /dev/null +++ b/dm-sflc/sysfs.c @@ -0,0 +1,206 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "sflc.h" + +/* + *---------------------------- + * Top-level entries + *---------------------------- + */ + +static ssize_t next_dev_id_show(struct module_attribute *mattr, struct module_kobject *mkobj, char *buf) +{ + ssize_t ret; + + if (mutex_lock_interruptible(&sflc_alldevs_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", sflc_free_devid); + mutex_unlock(&sflc_alldevs_lock); + + return ret; +} + +static struct kset *bdevs_kset; +static struct module_attribute devid_mattr = __ATTR_RO(next_dev_id); + +int sflc_sysfs_init() +{ + int err; + + bdevs_kset = kset_create_and_add(SFLC_SYSFS_BDEVS, NULL, &THIS_MODULE->mkobj.kobj); + if (!bdevs_kset) { + err = -ENOMEM; + DMERR("Could not create %s kset", SFLC_SYSFS_BDEVS); + goto bad_bdevs; + } + + err = sysfs_create_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); + if (err) { + DMERR("Could not create %s file", SFLC_SYSFS_DEVID); + goto bad_devid; + } + + return 0; + + +bad_devid: + kset_unregister(bdevs_kset); +bad_bdevs: + return err; +} + +void sflc_sysfs_exit() +{ + sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); + kset_unregister(bdevs_kset); +} + + +/* + *---------------------------- + * Device entries + *---------------------------- + */ + +static ssize_t dev_id_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_device *sdev = container_of(kobj, struct sflc_device, kobj); + + return sysfs_emit(buf, "%u\n", sdev->dev_id); +} + +static ssize_t volumes_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_device *sdev = container_of(kobj, struct sflc_device, kobj); + + return sysfs_emit(buf, "%u\n", sdev->nr_volumes); +} + + +static struct kobj_attribute dev_id_kattr = __ATTR_RO(dev_id); +static struct kobj_attribute volumes_kattr = __ATTR_RO(volumes); +static struct attribute *sflc_device_default_attrs[] = { + &dev_id_kattr.attr, + &volumes_kattr.attr, + NULL +}; +ATTRIBUTE_GROUPS(sflc_device_default); + +static void sflc_device_kobj_release(struct kobject *kobj) +{ + struct sflc_device *sdev = container_of(kobj, struct sflc_device, kobj); + complete(&sdev->kobj_released); +} + +static struct kobj_type sflc_device_ktype = { + .release = sflc_device_kobj_release, + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = sflc_device_default_groups +}; + +int sflc_sysfs_register_device(struct sflc_device *sdev) +{ + int err; + + /* Completion */ + init_completion(&sdev->kobj_released); + + /* Register directory :/ under bdevs/ */ + sdev->kobj.kset = bdevs_kset; + err = kobject_init_and_add(&sdev->kobj, &sflc_device_ktype, NULL, + "%s", sdev->name); + if (err) + goto bad; + /* Emit uevent */ + kobject_uevent(&sdev->kobj, KOBJ_ADD); + + return 0; + + +bad: + kobject_put(&sdev->kobj); + wait_for_completion(&sdev->kobj_released); + return err; +} + +void sflc_sysfs_unregister_device(struct sflc_device *sdev) +{ + kobject_put(&sdev->kobj); + wait_for_completion(&sdev->kobj_released); +} + + +/* + *---------------------------- + * Volume entries + *---------------------------- + */ + +static struct attribute *sflc_volume_default_attrs[] = { + NULL +}; +ATTRIBUTE_GROUPS(sflc_volume_default); + +static void sflc_volume_kobj_release(struct kobject *kobj) +{ + struct sflc_volume *svol = container_of(kobj, struct sflc_volume, kobj); + + complete(&svol->kobj_released); +} + +static struct kobj_type sflc_volume_ktype = { + .release = sflc_volume_kobj_release, + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = sflc_volume_default_groups +}; + +int sflc_sysfs_register_volume(struct sflc_volume *svol) +{ + int err; + + /* Completion */ + init_completion(&svol->kobj_released); + + /* Register directory name>/ under device directory */ + err = kobject_init_and_add(&svol->kobj, &sflc_volume_ktype, &svol->sdev->kobj, + "%s", svol->name); + if (err) + goto bad; + /* Emit uevent */ + kobject_uevent(&svol->kobj, KOBJ_ADD); + + return 0; + + +bad: + kobject_put(&svol->kobj); + wait_for_completion(&svol->kobj_released); + return err; +} + +void sflc_sysfs_unregister_volume(struct sflc_volume *svol) +{ + kobject_put(&svol->kobj); + wait_for_completion(&svol->kobj_released); +} diff --git a/dm-sflc/sysfs/devices.c b/dm-sflc/sysfs/devices.c deleted file mode 100644 index 7729145..0000000 --- a/dm-sflc/sysfs/devices.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include "sysfs.h" -#include "utils/string.h" -#include "log/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define SFLC_SYSFS_DEV_VOLUMES_ATTR_NAME "volumes" -#define SFLC_SYSFS_DEV_TOT_SLICES_ATTR_NAME "tot_slices" -#define SFLC_SYSFS_DEV_FREE_SLICES_ATTR_NAME "free_slices" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Functions that will go in the sysfs_ops */ -static ssize_t sflc_sysfs_devShow(struct kobject * kobj, struct attribute * attr, char * buf); -static ssize_t sflc_sysfs_devStore(struct kobject * kobj, struct attribute * attr, const char * buf, size_t len); - -/* Concrete file showers */ -static ssize_t sflc_sysfs_showDeviceVolumes(struct kobject * kobj, struct attribute * attr, char * buf); -static ssize_t sflc_sysfs_showDeviceTotSlices(struct kobject * kobj, struct attribute * attr, char * buf); -static ssize_t sflc_sysfs_showDeviceFreeSlices(struct kobject * kobj, struct attribute * attr, char * buf); - -/* Release function for the sysfs_Device */ -static void sflc_sysfs_releaseDev(struct kobject * kobj); - - -/***************************************************** - * PRIVATE VARIABLES DEFINITIONS * - *****************************************************/ - -/* The attribute representing the volumes file */ -static const struct attribute sflc_sysfs_devVolumesAttr = { - .name = SFLC_SYSFS_DEV_VOLUMES_ATTR_NAME, - .mode = 0444 -}; - -/* The attribute representing the tot_slices file */ -static const struct attribute sflc_sysfs_devTotSlicesAttr = { - .name = SFLC_SYSFS_DEV_TOT_SLICES_ATTR_NAME, - .mode = 0444 -}; - -/* The attribute representing the free_slices file */ -static const struct attribute sflc_sysfs_devFreeSlicesAttr = { - .name = SFLC_SYSFS_DEV_FREE_SLICES_ATTR_NAME, - .mode = 0444 -}; - -/* The sysfs_ops struct encapsulating the access methods */ -static const struct sysfs_ops sflc_sysfs_devSysfsOps = { - .show = sflc_sysfs_devShow, - .store = sflc_sysfs_devStore -}; - -/* The type for our sysfs_Device */ -static struct kobj_type sflc_sysfs_devType = { - .release = sflc_sysfs_releaseDev, - .sysfs_ops = &sflc_sysfs_devSysfsOps, -}; - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Creates and registers a sysfs_Device instance. Return ERR_PTR() on error. */ -sflc_sysfs_Device * sflc_sysfs_devCreateAndAdd(sflc_Device * pdev) -{ - sflc_sysfs_Device * dev; - int err; - - /* Allocate outer structure */ - dev = kzalloc(sizeof(sflc_sysfs_Device), GFP_KERNEL); - if (!dev) { - err = -ENOMEM; - pr_err("Could not allocate sysfs_Device\n"); - goto err_dev_alloc; - } - - /* Set device */ - dev->pdev = pdev; - - /* Allocate inner string */ - dev->dirname = kzalloc(strlen(pdev->bdev_path) + 1, GFP_KERNEL); - if (!dev->dirname) { - err = -ENOMEM; - pr_err("Could not allocate dirname\n"); - goto err_dirname_alloc; - } - - /* Copy it and substitute slashes with underscores */ - strcpy(dev->dirname, pdev->bdev_path); - sflc_str_replaceAll(dev->dirname, '/', '_'); - - /* Init and add kobject */ - err = kobject_init_and_add(&dev->kobj, &sflc_sysfs_devType, - sflc_sysfs_bdevs, dev->dirname); - if (err) { - pr_err("Could not init and add internal kobject; error %d\n", err); - goto err_kobj_init_add; - } - - /* Create the volumes file */ - err = sysfs_create_file(&dev->kobj, &sflc_sysfs_devVolumesAttr); - if (err) { - pr_err("Could not add volumes file; error %d\n", err); - goto err_vol_file; - } - /* Create the tot_slices file */ - err = sysfs_create_file(&dev->kobj, &sflc_sysfs_devTotSlicesAttr); - if (err) { - pr_err("Could not add tot_slices file; error %d\n", err); - goto err_tot_slices_file; - } - /* Create the volumes file */ - err = sysfs_create_file(&dev->kobj, &sflc_sysfs_devFreeSlicesAttr); - if (err) { - pr_err("Could not add free_slices file; error %d\n", err); - goto err_free_slices_file; - } - - return dev; - - -err_free_slices_file: -err_tot_slices_file: -err_vol_file: - kobject_put(&dev->kobj); -err_kobj_init_add: - kfree(dev->dirname); -err_dirname_alloc: - kfree(dev); -err_dev_alloc: - return ERR_PTR(err); -} - -/* Releases a reference to a sysfs_Device instance */ -void sflc_sysfs_putDev(sflc_sysfs_Device * dev) -{ - kobject_put(&dev->kobj); -} - -/* Creates a symlink inside the device's directory (under /sys/modules/dm_sflc/bdevs/) - * pointing to the volume's directory (under /sys/devices/sflc/) */ -int sflc_sysfs_addVolumeToDevice(sflc_sysfs_Device * dev, sflc_sysfs_Volume * vol) -{ - return sysfs_create_link(&dev->kobj, &vol->kdev.kobj, vol->kdev.kobj.name); -} - -/* Removes the symlink created before */ -void sflc_sysfs_removeVolumeFromDevice(sflc_sysfs_Device * dev, sflc_sysfs_Volume * vol) -{ - sysfs_remove_link(&dev->kobj, vol->kdev.kobj.name); -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Dispatch to the right shower */ -static ssize_t sflc_sysfs_devShow(struct kobject * kobj, struct attribute * attr, char * buf) -{ - /* Dispatch based on name */ - if (strcmp(attr->name, SFLC_SYSFS_DEV_VOLUMES_ATTR_NAME) == 0) { - return sflc_sysfs_showDeviceVolumes(kobj, attr, buf); - } - if (strcmp(attr->name, SFLC_SYSFS_DEV_TOT_SLICES_ATTR_NAME) == 0) { - return sflc_sysfs_showDeviceTotSlices(kobj, attr, buf); - } - if (strcmp(attr->name, SFLC_SYSFS_DEV_FREE_SLICES_ATTR_NAME) == 0) { - return sflc_sysfs_showDeviceFreeSlices(kobj, attr, buf); - } - - /* Else, error */ - pr_err("Error, unknown attribute %s\n", attr->name); - return -EIO; -} - -/* Do nothing */ -static ssize_t sflc_sysfs_devStore(struct kobject * kobj, struct attribute * attr, const char * buf, size_t len) -{ - return -EIO; -} - -/* Show the list of mounted volumes */ -static ssize_t sflc_sysfs_showDeviceVolumes(struct kobject * kobj, struct attribute * attr, char * buf) -{ - sflc_sysfs_Device * dev; - sflc_Device * pdev; - ssize_t ret; - - /* Cast to a sysfs_Device */ - dev = container_of(kobj, sflc_sysfs_Device, kobj); - /* Get the device */ - pdev = dev->pdev; - - /* File contents */ - ret = 0; - ssize_t written; - /* Write the volume count */ - written = sprintf(buf, "%d", pdev->vol_cnt); - ret += written; - buf += written; - /* And all the volume names, space-separated */ - int i; - for (i = 0; i < pdev->vol_cnt; i++) { - written = sprintf(buf, " %s", pdev->vol[i]->vol_name); - ret += written; - buf += written; - } - /* Add newline */ - written = sprintf(buf, "\n"); - ret += written; - buf += written; - - return ret; -} - -/* Show the number of slices */ -static ssize_t sflc_sysfs_showDeviceTotSlices(struct kobject * kobj, struct attribute * attr, char * buf) -{ - sflc_sysfs_Device * dev; - sflc_Device * pdev; - ssize_t ret; - - /* Cast to a DeviceKobject */ - dev = container_of(kobj, sflc_sysfs_Device, kobj); - /* Get the device */ - pdev = dev->pdev; - - /* Write the tot_slices */ - ret = sprintf(buf, "%u\n", pdev->tot_slices); - - return ret; -} - -/* Show the number of free slices */ -static ssize_t sflc_sysfs_showDeviceFreeSlices(struct kobject * kobj, struct attribute * attr, char * buf) -{ - sflc_sysfs_Device * dev; - sflc_Device * pdev; - ssize_t ret; - - /* Cast to a DeviceKobject */ - dev = container_of(kobj, sflc_sysfs_Device, kobj); - /* Get the device */ - pdev = dev->pdev; - - /* Write the free_slices */ - ret = sprintf(buf, "%u\n", pdev->free_slices); - - return ret; -} - -/* Release function for the DeviceKobject */ -static void sflc_sysfs_releaseDev(struct kobject * kobj) -{ - sflc_sysfs_Device * dev; - - /* Cast to a DeviceKobject */ - dev = container_of(kobj, sflc_sysfs_Device, kobj); - - /* Free everything */ - kfree(dev->dirname); - kfree(dev); - - return; -} diff --git a/dm-sflc/sysfs/sysfs.c b/dm-sflc/sysfs/sysfs.c deleted file mode 100644 index a5854c4..0000000 --- a/dm-sflc/sysfs/sysfs.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - -#include "sysfs.h" -#include "log/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define SFLC_SYSFS_BDEVS_ENTRY_NAME "bdevs" -#define SFLC_SYSFS_ROOT_DEVICE_NAME "sflc" -#define SFLC_SYSFS_NEXT_DEV_ID_ATTR_NAME next_dev_id - - -/***************************************************** - * PUBLIC VARIABLES DEFINITIONS * - *****************************************************/ - -/* Kobject associated to the /sys/module/dm_sflc/bdevs entry */ -struct kobject * sflc_sysfs_bdevs; - -/* Root device that will be every volume's parent */ -struct device * sflc_sysfs_root; - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static ssize_t sflc_sysfs_showNextDevId(struct device *kdev, struct device_attribute *attr, char *buf); - - -/***************************************************** - * PRIVATE VARIABLES DEFINITIONS * - *****************************************************/ - -/* Attribute showing the next device ID */ -static const struct device_attribute sflc_sysfs_nextDevIdAttr = __ATTR( - SFLC_SYSFS_NEXT_DEV_ID_ATTR_NAME, - 0444, - sflc_sysfs_showNextDevId, - NULL -); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Called on module load */ -int sflc_sysfs_init(void) -{ - int err; - - /* Create the bdevs entry under /sys/module/dm_sflc */ - sflc_sysfs_bdevs = kobject_create_and_add(SFLC_SYSFS_BDEVS_ENTRY_NAME, &THIS_MODULE->mkobj.kobj); - if (!sflc_sysfs_bdevs) { - err = -ENOMEM; - pr_err("Could not create bdevs kobject\n"); - goto err_realdevs; - } - - /* Create the root sflc device */ - sflc_sysfs_root = root_device_register(SFLC_SYSFS_ROOT_DEVICE_NAME); - if (IS_ERR(sflc_sysfs_root)) { - err = PTR_ERR(sflc_sysfs_root); - pr_err("Could not register sflc root device; error %d\n", err); - goto err_rootdev; - } - - /* Add next_dev_id attribute to it */ - err = device_create_file(sflc_sysfs_root, &sflc_sysfs_nextDevIdAttr); - if (err) { - pr_err("Could not create mapped_slices device file; error %d\n", err); - goto err_dev_create_file; - } - - return 0; - -err_dev_create_file: - root_device_unregister(sflc_sysfs_root); -err_rootdev: - kobject_put(sflc_sysfs_bdevs); -err_realdevs: - return err; -} - -/* Called on module unload */ -void sflc_sysfs_exit(void) -{ - root_device_unregister(sflc_sysfs_root); - kobject_put(sflc_sysfs_bdevs); -} - - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -static ssize_t sflc_sysfs_showNextDevId(struct device *kdev, struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", sflc_dev_nextId); -} - diff --git a/dm-sflc/sysfs/sysfs.h b/dm-sflc/sysfs/sysfs.h deleted file mode 100644 index 62fc014..0000000 --- a/dm-sflc/sysfs/sysfs.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Sysfs functions - */ - -#ifndef _SFLC_SYSFS_SYSFS_H_ -#define _SFLC_SYSFS_SYSFS_H_ - - -/***************************************************** - * TYPES FORWARD DECLARATIONS * - *****************************************************/ - -/* Necessary since device.h, volume.h, and sysfs.h all include each other */ - -typedef struct sflc_sysfs_device_s sflc_sysfs_Device; -typedef struct sflc_sysfs_volume_s sflc_sysfs_Volume; - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "device/device.h" -#include "volume/volume.h" - - -/***************************************************** - * TYPES * - *****************************************************/ - -/* This embeds a struct kobject */ -struct sflc_sysfs_device_s -{ - /* The Device it represents */ - sflc_Device * pdev; - /* The name of this device's subdirectoy under realdevs */ - char * dirname; - - /* The embedded kobject */ - struct kobject kobj; -}; - -/* This embeds a struct device */ -struct sflc_sysfs_volume_s -{ - /* The Volume it represents */ - sflc_Volume * pvol; - - /* The embedded device */ - struct device kdev; -}; - - -/***************************************************** - * PUBLIC VARIABLES DECLARATIONS * - *****************************************************/ - -/* Kobject associated to the /sys/module/dm_sflc/bdevs entry */ -extern struct kobject * sflc_sysfs_bdevs; - -/* Root device (/sys/devices/sflc) that will be every volume's parent. - A bit overkill to have a sflc root device, but it does the trick. */ -extern struct device * sflc_sysfs_root; - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Called on module load/unload */ -int sflc_sysfs_init(void); -void sflc_sysfs_exit(void); - - -/* Device-related functions */ - -/* Creates and registers a sysfs_Device instance. Returns ERR_PTR() on error. */ -sflc_sysfs_Device * sflc_sysfs_devCreateAndAdd(sflc_Device * pdev); - -/* Releases a reference to a sysfs_Device instance */ -void sflc_sysfs_putDev(sflc_sysfs_Device * dev); - -/* Creates a symlink inside the device's subdirectory pointing to the volume's subdirectory */ -int sflc_sysfs_addVolumeToDevice(sflc_sysfs_Device * dev, sflc_sysfs_Volume * vol); - -/* Removes the symlink created before */ -void sflc_sysfs_removeVolumeFromDevice(sflc_sysfs_Device * dev, sflc_sysfs_Volume * vol); - - -/* Volume-related functions */ - -/* Creates and registers a sysfs_Volume instance. Returns ERR_PTR() on error. */ -sflc_sysfs_Volume * sflc_sysfs_volCreateAndAdd(sflc_Volume * pvol); - -/* Releases a reference to a sysfs_Volume instance */ -void sflc_sysfs_putVol(sflc_sysfs_Volume * vol); - - -#endif /* _SFLC_SYSFS_SYSFS_H_ */ diff --git a/dm-sflc/sysfs/volumes.c b/dm-sflc/sysfs/volumes.c deleted file mode 100644 index 2ca2e7f..0000000 --- a/dm-sflc/sysfs/volumes.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include "sysfs.h" -#include "utils/string.h" -#include "log/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define SFLC_SYSFS_VOL_NR_SLICES_ATTR_NAME mapped_slices - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static void sflc_sysfs_volRelease(struct device * kdev); -static ssize_t sflc_sysfs_showVolNrSlices(struct device * dev, struct device_attribute * attr, char * buf); - - -/***************************************************** - * PRIVATE VARIABLES DEFINITIONS * - *****************************************************/ - -/* Attribute showing the number of slices utilised by the volume */ -static const struct device_attribute sflc_sysfs_volNrSlicesAttr = __ATTR( - SFLC_SYSFS_VOL_NR_SLICES_ATTR_NAME, - 0444, - sflc_sysfs_showVolNrSlices, - NULL -); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Creates and registers a sysfs_Volume instance. Returns ERR_PTR() on error. */ -sflc_sysfs_Volume * sflc_sysfs_volCreateAndAdd(sflc_Volume * pvol) -{ - sflc_sysfs_Volume * vol; - int err; - - /* Allocate device */ - vol = kzalloc(sizeof(sflc_sysfs_Volume), GFP_KERNEL); - if (!vol) { - err = -ENOMEM; - pr_err("Could not allocate sysfs_Volume\n"); - goto err_vol_alloc; - } - - /* Set volume */ - vol->pvol = pvol; - - /* Set name */ - err = dev_set_name(&vol->kdev, "%s", pvol->vol_name); - if (err) { - pr_err("Could not set device name %s; error %d\n", pvol->vol_name, err); - goto err_dev_set_name; - } - - /* Set destructor */ - vol->kdev.release = sflc_sysfs_volRelease; - /* Set parent */ - vol->kdev.parent = sflc_sysfs_root; - - /* Register */ - err = device_register(&vol->kdev); - if (err) { - pr_err("Could not register volume %s; error %d\n", pvol->vol_name, err); - goto err_dev_register; - } - - /* Add mapped_slices attribute */ - err = device_create_file(&vol->kdev, &sflc_sysfs_volNrSlicesAttr); - if (err) { - pr_err("Could not create mapped_slices device file; error %d\n", err); - goto err_dev_create_file; - } - - return vol; - - -err_dev_create_file: - device_unregister(&vol->kdev); -err_dev_register: - put_device(&vol->kdev); -err_dev_set_name: - kfree(vol); -err_vol_alloc: - return ERR_PTR(err); -} - -/* Releases a reference to a sysfs_Device instance */ -void sflc_sysfs_putVol(sflc_sysfs_Volume * vol) -{ - device_unregister(&vol->kdev); -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static ssize_t sflc_sysfs_showVolNrSlices(struct device * kdev, struct device_attribute * attr, char * buf) -{ - sflc_sysfs_Volume * vol = container_of(kdev, sflc_sysfs_Volume, kdev); - sflc_Volume * pvol = vol->pvol; - - return sprintf(buf, "%u\n", pvol->mapped_slices); -} - -static void sflc_sysfs_volRelease(struct device * kdev) -{ - sflc_sysfs_Volume * vol; - - /* Cast */ - vol = container_of(kdev, sflc_sysfs_Volume, kdev); - - /* Just free */ - kfree(vol); - - return; -} diff --git a/dm-sflc/target/target.c b/dm-sflc/target/target.c deleted file mode 100644 index afb143a..0000000 --- a/dm-sflc/target/target.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Methods of our DM target - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include "target.h" -#include "device/device.h" -#include "volume/volume.h" -#include "utils/bio.h" -#include "utils/string.h" -#include "log/log.h" - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static int sflc_tgt_ctr(struct dm_target *ti, unsigned int argc, char **argv); -static void sflc_tgt_dtr(struct dm_target *ti); -static int sflc_tgt_map(struct dm_target *ti, struct bio *bio); -static void sflc_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits); -static int sflc_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn, - void *data); - -/***************************************************** - * PUBLIC VARIABLES DEFINITIONS * - *****************************************************/ - -struct target_type sflc_target = { - .name = "shufflecake", - .version = {1, 0, 0}, - .module = THIS_MODULE, - .ctr = sflc_tgt_ctr, - .dtr = sflc_tgt_dtr, - .map = sflc_tgt_map, - .status = NULL, - .io_hints = sflc_tgt_ioHints, - .iterate_devices = sflc_tgt_iterateDevices, -}; - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Called every time we create a volume with the userland tool */ -static int sflc_tgt_ctr(struct dm_target *ti, unsigned int argc, char **argv) -{ - char * bdev_path; - int vol_idx; - char * enckey_hex; - u8 enckey[SFLC_SK_KEY_LEN]; - u32 tot_slices; - sflc_Device * dev; - sflc_Volume * vol; - int err; - - /* - * Parse arguments. - * - * argv[0]: underlying block device path - * argv[1]: volume index within the device - * argv[2]: number of 1 MB slices in the underlying device - * argv[3]: 32-byte encryption key (hex-encoded) - */ - if (argc != 4) { - ti->error = "Invalid argument count"; - return -EINVAL; - } - bdev_path = argv[0]; - sscanf(argv[1], "%d", &vol_idx); - sscanf(argv[2], "%u", &tot_slices); - enckey_hex = argv[3]; - - /* Decode the encryption key */ - if (strlen(enckey_hex) != 2 * SFLC_SK_KEY_LEN) { - pr_err("Hexadecimal key (length %lu): %s\n", strlen(enckey_hex), enckey_hex); - ti->error = "Invalid key length"; - return -EINVAL; - } - err = sflc_str_hexDecode(enckey_hex, enckey); - if (err) { - ti->error = "Could not decode hexadecimal encryption key"; - return err; - } - - /* Acquire the big device lock */ - if (down_interruptible(&sflc_dev_mutex)) { - ti->error = "Interrupted while waiting for access to Device"; - return -EINTR; - } - - /* Check if we already have a Device for this bdev */ - dev = sflc_dev_lookupByPath(bdev_path); - if (IS_ERR(dev)) { - ti->error = "Could not look up device by path (interrupted)"; - up(&sflc_dev_mutex); - return PTR_ERR(dev); - } - - /* Otherwise create it (also adds it to the device list) */ - if (!dev) { - pr_notice("Device for %s didn't exist before, going to create it\n", bdev_path); - dev = sflc_dev_create(ti, bdev_path, tot_slices); - } else { - pr_notice("Device on %s already existed\n", bdev_path); - } - - /* Check for device creation errors */ - if (IS_ERR(dev)) { - ti->error = "Could not create device"; - up(&sflc_dev_mutex); - return PTR_ERR(dev); - } - - /* Create the volume (also adds it to the device) */ - vol = sflc_vol_create(ti, dev, vol_idx, enckey); - if (IS_ERR(vol)) { - ti->error = "Error creating volume"; - up(&sflc_dev_mutex); - return PTR_ERR(vol); - } - pr_debug("Now %d volumes are linked to device %s\n", dev->vol_cnt, bdev_path); - - /* Release the big device lock */ - up(&sflc_dev_mutex); - - /* Tell DM we want one SFLC sector at a time */ - ti->max_io_len = SFLC_DEV_SECTOR_SCALE; - /* Enable REQ_OP_FLUSH bios */ - ti->num_flush_bios = 1; - /* Disable REQ_OP_WRITE_ZEROES and REQ_OP_SECURE_ERASE (can't be passed through as - they would break deniability, and they would be too complicated to handle individually) */ - ti->num_secure_erase_bios = 0; - ti->num_write_zeroes_bios = 0; - /* Momentarily disable REQ_OP_DISCARD_BIOS - TODO: will need to support them to release slice mappings */ - ti->num_discard_bios = 0; - /* When we receive a ->map call, we won't need to take the device lock anymore */ - ti->private = vol; - - return 0; -} - -/* Called every time we destroy a volume with the userland tool */ -static void sflc_tgt_dtr(struct dm_target *ti) -{ - sflc_Volume * vol = ti->private; - sflc_Device * dev = vol->dev; - - pr_debug("Destroying volume \"%s\"\n", vol->vol_name); - - /* We do need to take the device lock here, as we'll be modifying the device */ - if (down_interruptible(&sflc_dev_mutex)) { - pr_err("Interrupted while waiting to destroy volume\n"); - return; - } - - /* Destroy volume (also decreases refcount in device) */ - sflc_vol_destroy(ti, vol); - - /* Destroy the device */ - if (dev->vol_cnt == 0) { - pr_notice("Removed the last volume from device\n"); - sflc_dev_destroy(ti, dev); - } - - /* End of critical section */ - up(&sflc_dev_mutex); - - return; -} - -/* Callback for every bio submitted to our virtual block device */ -static int sflc_tgt_map(struct dm_target *ti, struct bio *bio) -{ - int err; - sflc_Volume * vol = ti->private; - - /* If no data, just quickly remap the sector and the block device (no crypto) */ - /* TODO: this is dangerous for deniability, will need more filtering */ - if (unlikely(!bio_has_data(bio))) { - pr_debug("No-data bio: bio_op = %d", bio_op(bio)); - err = sflc_vol_remapBioFast(vol, bio); - if (err) { - pr_err("Could not remap bio; error %d\n", err); - return DM_MAPIO_KILL; - } - return DM_MAPIO_REMAPPED; - } - - /* At this point, the bio has data. Do a few sanity checks */ - /* TODO: I think we can get rid of all of them */ - - /* Check that it is properly aligned and it doesn't cross vector boundaries */ - if (unlikely(!sflc_bio_isAligned(bio))) { - pr_err("Unaligned bio!\n"); - return DM_MAPIO_KILL; - } - /* If it contains more than one SFLC sector, complain with the DM layer and continue */ - if (unlikely(bio->bi_iter.bi_size > SFLC_DEV_SECTOR_SIZE)) { - pr_notice("Large bio of size %u\n", bio->bi_iter.bi_size); - dm_accept_partial_bio(bio, SFLC_DEV_SECTOR_SCALE); - } - /* Check that it contains exactly one SFLC sector */ - if (unlikely(bio->bi_iter.bi_size != SFLC_DEV_SECTOR_SIZE)) { - pr_err("Wrong length (%u) of bio\n", bio->bi_iter.bi_size); - return DM_MAPIO_KILL; - } - - /* Now it is safe, process it */ - err = sflc_vol_processBio(vol, bio); - if (err) { - pr_err("Could not enqueue bio\n"); - return DM_MAPIO_KILL; - } - - return DM_MAPIO_SUBMITTED; -} - -/* Callback executed to inform the DM about our 4096-byte sector size */ -static void sflc_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits) -{ - sflc_Volume * vol = ti->private; - - pr_info("Called io_hints on volume \"%s\"\n", vol->vol_name); - - limits->logical_block_size = SFLC_DEV_SECTOR_SIZE; - limits->physical_block_size = SFLC_DEV_SECTOR_SIZE; - - limits->io_min = SFLC_DEV_SECTOR_SIZE; - limits->io_opt = SFLC_DEV_SECTOR_SIZE; - - return; -} - -/* Callback needed for God knows what, otherwise io_hints never gets called */ -static int sflc_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn, - void *data) -{ - sflc_Volume * vol = ti->private; - sflc_Device * dev = vol->dev; - - pr_debug("Called iterate_devices on volume \"%s\"\n", vol->vol_name); - - if (!fn) { - return -EINVAL; - } - return fn(ti, vol->dev->bdev, 0, - (dev->dev_header_size + dev->tot_slices * SFLC_DEV_PHYS_SLICE_SIZE) * SFLC_DEV_SECTOR_SCALE, - data); -} From 64076b2652bd0161249aeda54b14f9d355b62c06 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 3 Aug 2024 12:01:23 +0200 Subject: [PATCH 59/75] Finished unification --- dm-sflc/Kbuild | 4 + dm-sflc/dev_vol.c | 21 ++ dm-sflc/lite/crypto.c | 125 +++++++++++ dm-sflc/lite/device.c | 204 +++++++++++++++++ dm-sflc/lite/posmap.c | 376 ++++++++++++++++++++++++++++++++ dm-sflc/lite/read.c | 168 ++++++++++++++ dm-sflc/lite/sflc_lite.c | 161 ++++++++++++++ dm-sflc/lite/sflc_lite.h | 182 ++++++++++++++++ dm-sflc/lite/sflite_constants.h | 53 +++++ dm-sflc/lite/sysfs.c | 116 ++++++++++ dm-sflc/lite/volume.c | 162 ++++++++++++++ dm-sflc/lite/write.c | 148 +++++++++++++ dm-sflc/old/device/device.c | 7 +- dm-sflc/old/volume/volume.c | 7 +- dm-sflc/sflc.c | 11 +- dm-sflc/sflc.h | 3 + 16 files changed, 1745 insertions(+), 3 deletions(-) create mode 100644 dm-sflc/lite/crypto.c create mode 100644 dm-sflc/lite/device.c create mode 100644 dm-sflc/lite/posmap.c create mode 100644 dm-sflc/lite/read.c create mode 100644 dm-sflc/lite/sflc_lite.c create mode 100644 dm-sflc/lite/sflc_lite.h create mode 100644 dm-sflc/lite/sflite_constants.h create mode 100644 dm-sflc/lite/sysfs.c create mode 100644 dm-sflc/lite/volume.c create mode 100644 dm-sflc/lite/write.c diff --git a/dm-sflc/Kbuild b/dm-sflc/Kbuild index 5c5c705..8b39934 100644 --- a/dm-sflc/Kbuild +++ b/dm-sflc/Kbuild @@ -34,6 +34,10 @@ OBJ_LIST += old/utils/string.o old/utils/bio.o old/utils/pools.o old/utils/workq OBJ_LIST += old/crypto/rand/rand.o OBJ_LIST += old/crypto/symkey/symkey.o old/crypto/symkey/skreq_pool.o +OBJ_LIST += lite/sflc_lite.o lite/sysfs.o +OBJ_LIST += lite/device.o lite/volume.o +OBJ_LIST += lite/posmap.o lite/read.o lite/write.o lite/crypto.o + $(MODULE_NAME)-y += $(OBJ_LIST) diff --git a/dm-sflc/dev_vol.c b/dm-sflc/dev_vol.c index 422831f..7d6f258 100644 --- a/dm-sflc/dev_vol.c +++ b/dm-sflc/dev_vol.c @@ -73,6 +73,13 @@ struct sflc_device *sflc_dev_create(struct dm_target *ti, int argc, char **argv) goto bad_inner; } break; + case SFLC_MODE_LITE: + sdev->sflite_dev = sflite_dev_create(ti, argc, argv, &sdev->kobj); + if (IS_ERR(sdev->sflite_dev)) { + err = PTR_ERR(sdev->sflite_dev); + goto bad_inner; + } + break; default: DMERR("Invalid Shufflecake mode %d", mode); err = -EINVAL; @@ -99,6 +106,9 @@ void sflc_dev_destroy(struct sflc_device *sdev) case SFLC_MODE_LEGACY: sfold_dev_destroy(sdev->sfold_dev); break; + case SFLC_MODE_LITE: + sflite_dev_destroy(sdev->sflite_dev); + break; default: DMCRIT("Destroying device with invalid Shufflecake mode %d", sdev->mode); return; @@ -150,6 +160,14 @@ struct sflc_volume *sflc_vol_create(struct sflc_device *sdev, struct dm_target * } svol->tt = &sfold_target_type; break; + case SFLC_MODE_LITE: + svol->sflite_vol = sflite_vol_create(ti, sdev->sflite_dev, argc, argv, &svol->kobj); + if (IS_ERR(svol->sflite_vol)) { + err = PTR_ERR(svol->sflite_vol); + goto bad_inner; + } + svol->tt = &sflite_target_type; + break; default: DMERR("Invalid Shufflecake mode %d", mode); err = -EINVAL; @@ -175,6 +193,9 @@ void sflc_vol_destroy(struct sflc_volume *svol) case SFLC_MODE_LEGACY: sfold_vol_destroy(svol->sfold_vol); break; + case SFLC_MODE_LITE: + sflite_vol_destroy(svol->sflite_vol); + break; default: DMCRIT("Destroying volume with invalid Shufflecake mode %d", svol->mode); return; diff --git a/dm-sflc/lite/crypto.c b/dm-sflc/lite/crypto.c new file mode 100644 index 0000000..8e27203 --- /dev/null +++ b/dm-sflc/lite/crypto.c @@ -0,0 +1,125 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include +#include "sflite_constants.h" + +#include "sflc_lite.h" + + +/** + * Encrypt/decrypt exactly one block, already encoded in the scatterlist. + * All other crypto functions reduce to this one. + * The IV is constructed as the right-0-padded LE representation of the + * physical block number, which is exactly what dm-crypt does when using the + * IV mode "plain64". + */ +static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, + struct scatterlist *dst, u64 pblk_num, int rw) +{ + u8 iv[SFLITE_XTS_IVLEN]; + struct skcipher_request *req = NULL; + DECLARE_CRYPTO_WAIT(wait); + int err; + + // TODO not too sure about the gfp_mask here + // TODO move @req into struct sflite_io? + req = skcipher_request_alloc(tfm, GFP_NOIO); + if (!req) + return -ENOMEM; + + skcipher_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + crypto_req_done, &wait); + + /* Construct IV */ + memset(iv, 0, SFLITE_XTS_IVLEN); + *(__le64 *)iv = cpu_to_le64(pblk_num); + + skcipher_request_set_crypt(req, src, dst, SFLITE_BLOCK_SIZE, iv); + if (rw == READ) + err = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); + else + err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); + skcipher_request_free(req); + + return err; +} + +/* Encrypt-decrypt a single block (memory buffer is a page) */ +int sflite_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw) +{ + struct scatterlist dst, src, *p_dst; + bool is_inplace; + + /* Use same scatterlist if in-place */ + is_inplace = (src_page == dst_page); + p_dst = is_inplace ? &src : &dst; + + /* We assume PAGE_SIZE == SFLITE_BLOCK_SIZE */ + /* And orig_bio to start at offset 0 within the page */ + sg_init_table(&src, 1); + sg_set_page(&src, src_page, SFLITE_BLOCK_SIZE, 0); + if (!is_inplace) { + sg_init_table(&dst, 1); + sg_set_page(&dst, dst_page, SFLITE_BLOCK_SIZE, 0); + } + + return crypt_sg(tfm, &src, p_dst, pblk_num, rw); +} + + +/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ +int sflite_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, + u64 num_blocks, u64 first_pblk_num, int rw) +{ + struct scatterlist dst, src, *p_dst; + u64 pblk_num; + bool is_inplace; + int err; + + /* Use same scatterlist if in-place */ + is_inplace = (src_buf == dst_buf); + p_dst = is_inplace ? &src : &dst; + + for (pblk_num = first_pblk_num; + pblk_num < first_pblk_num + num_blocks; + pblk_num++) { + sg_init_one(&src, src_buf, SFLITE_BLOCK_SIZE); + if (!is_inplace) + sg_init_one(&dst, dst_buf, SFLITE_BLOCK_SIZE); + + err = crypt_sg(tfm, &src, p_dst, pblk_num, rw); + if (err) + return err; + + src_buf += SFLITE_BLOCK_SIZE; + dst_buf += SFLITE_BLOCK_SIZE; + } + + return 0; +} + diff --git a/dm-sflc/lite/device.c b/dm-sflc/lite/device.c new file mode 100644 index 0000000..e62aa54 --- /dev/null +++ b/dm-sflc/lite/device.c @@ -0,0 +1,204 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include +#include +#include "sflc_lite.h" + + + +/* Depth of the mempool backing the bio_set */ +#define SFLITE_BIOSET_BIOS 64 + + +/* Fisher-Yates shuffle */ +static void fisheryates_u32(u32 *v, u32 len) +{ + u32 i, j; + + for (i = len-1; i >= 1; i--) { + j = get_random_u32_below(i+1); + swap(v[i], v[j]); + } + + return; +} + +/** + * Arguments: + * argv[0]: Shufflecake mode: legacy/lite + * argv[1]: Shufflecake-unique device ID + * argv[2]: path to underlying physical device + * argv[3]: volume index within the device + * argv[4]: number of 1 MB slices in the underlying device + * argv[5]: 64-byte encryption key (hex-encoded) + */ +struct sflite_device *sflite_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj) +{ + struct sflite_device *sdev; + dev_t devt; + u32 dev_id; + u32 tot_slices; + int i; + int err; + + sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + if (!sdev) { + DMERR("Could not allocate device"); + return ERR_PTR(-ENOMEM); + } + + /* Parse args */ + if (argc != 6) { + pr_err("Wrong argument count"); + err = -EINVAL; + goto bad_parse; + } + sscanf(argv[1], "%u", &dev_id); + if (sscanf(argv[4], "%u", &tot_slices) != 1) { + pr_err("Could not decode tot_slices\n"); + err = -EINVAL; + goto bad_parse; + } + + sdev->dev_id = dev_id; + + /* Look up block device and set name */ + err = lookup_bdev(argv[2], &devt); + if (err) { + DMERR("Could not look up block device"); + goto bad_lookup; + } + format_dev_t(sdev->name, devt); + + /* Compute sizes */ + sdev->tot_slices = tot_slices; + sdev->nr_free_slices = tot_slices; + /* Enough posmap blocks to fit all the entries */ + sdev->posmap_size_sectors = SFLITE_BLOCK_SCALE * + DIV_ROUND_UP(tot_slices, SFLITE_PSIS_PER_BLOCK); + /* DMB + VMBs + PosMaps */ + sdev->dev_header_size_sectors = SFLITE_BLOCK_SCALE + + (SFLITE_DEV_MAX_VOLUMES * SFLITE_BLOCK_SCALE) + + (SFLITE_DEV_MAX_VOLUMES * sdev->posmap_size_sectors); + + /* Shuffled PSIs */ + mutex_init(&sdev->slices_lock); + sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); + if (!sdev->slices_ofld) { + DMERR("Could not allocate PSI occupation bitfield"); + err = -ENOMEM; + goto bad_ofld; + } + + sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); + if (!sdev->prmslices) { + DMERR("Could not allocate shuffled PSI array"); + err = -ENOMEM; + goto bad_prmslices; + } + /* Generate a permutation */ + for (i = 0; i < tot_slices; i++) + sdev->prmslices[i] = i; + fisheryates_u32(sdev->prmslices, tot_slices); + sdev->prmslices_octr = 0; + + /* Bioset */ + err = bioset_init(&sdev->bioset, SFLITE_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); + if (err) { + DMERR("Could not init bioset; error %d", err); + goto bad_bioset; + } + + /* Client for dm-io */ + sdev->io_client = dm_io_client_create(); + if (IS_ERR(sdev->io_client)) { + err = PTR_ERR(sdev->io_client); + DMERR("Could not create dm-io client; error %d", err); + goto bad_dmio_client; + } + + /* I/O workqueue */ + sdev->io_queue = alloc_workqueue("sflite_%s_io", + WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, + 0, sdev->name); + if (!sdev->io_queue) { + err = -ENOMEM; + DMERR("Could not allocate I/O workqueue"); + goto bad_io_wq; + } + /* Decryption workqueue */ + sdev->crypt_queue = alloc_workqueue("sflite_%s_crypt", + WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, + 0, sdev->name); + if (!sdev->crypt_queue) { + err = -ENOMEM; + DMERR("Could not allocate decryption workqueue"); + goto bad_crypt_wq; + } + + /* Add to sysfs, once initialised */ + sdev->kobj_parent = kobj; + err = sflite_sysfs_add_device(sdev); + if (err) + goto bad_sysfs; + + return sdev; + + +bad_sysfs: + destroy_workqueue(sdev->crypt_queue); +bad_crypt_wq: + destroy_workqueue(sdev->io_queue); +bad_io_wq: + dm_io_client_destroy(sdev->io_client); +bad_dmio_client: + bioset_exit(&sdev->bioset); +bad_bioset: + vfree(sdev->prmslices); +bad_prmslices: + vfree(sdev->slices_ofld); +bad_ofld: +bad_lookup: +bad_parse: + kfree(sdev); + return ERR_PTR(err); +} + + +void sflite_dev_destroy(struct sflite_device *sdev) +{ + sflite_sysfs_remove_device(sdev); + destroy_workqueue(sdev->crypt_queue); + destroy_workqueue(sdev->io_queue); + dm_io_client_destroy(sdev->io_client); + bioset_exit(&sdev->bioset); + vfree(sdev->prmslices); + vfree(sdev->slices_ofld); + kfree(sdev); + + return; +} + diff --git a/dm-sflc/lite/posmap.c b/dm-sflc/lite/posmap.c new file mode 100644 index 0000000..eb57072 --- /dev/null +++ b/dm-sflc/lite/posmap.c @@ -0,0 +1,376 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include "sflc_lite.h" + + +/* Helpers */ + +#define IS_PSI_TAKEN(sdev, psi) ( (sdev)->slices_ofld[(psi)] ) +#define NEXT_RANDOM_PSI(sdev) ( (sdev)->prmslices[(sdev)->prmslices_octr] ) +#define IS_LAST_LSI_IN_BLOCK(lsi, sdev) ( (((lsi)+1) % SFLITE_PSIS_PER_BLOCK == 0) || \ + (((lsi)+1) == (sdev)->tot_slices) ) + + +/* + *---------------------------- + * Create slice mapping + *---------------------------- + */ + +/** + * Return the next free PSI in the device's shuffled array, without modifying + * the device state. + * + * MUTEX: @sdev->slices_lock must be held. + */ +static int peek_next_free_psi(struct sflite_device *sdev, u32 *psi) +{ + if (unlikely(!sdev->nr_free_slices)) + return -ENOSPC; + if (unlikely(sdev->prmslices_octr >= sdev->tot_slices)) { + DMCRIT("octr = %u, tot_slices = %u, free_slices = %u", sdev->prmslices_octr, sdev->tot_slices, sdev->nr_free_slices); + print_hex_dump(KERN_CRIT, "prmslices(REV) ", DUMP_PREFIX_OFFSET, 32, 4, sdev->prmslices, 4*sdev->tot_slices, false); + msleep(10000); + print_hex_dump(KERN_CRIT, "ofld(REV) ", DUMP_PREFIX_OFFSET, 32, 1, sdev->slices_ofld, sdev->tot_slices, false); + msleep(10000); + return -ENOTRECOVERABLE; // Grave inconsistency + } + + /* Invariant: @prmslices_octr points to a free slice */ + *psi = NEXT_RANDOM_PSI(sdev); + if (unlikely(IS_PSI_TAKEN(sdev, *psi))){ + DMCRIT("octr = %u, tot_slices = %u, free_slices = %u", sdev->prmslices_octr, sdev->tot_slices, sdev->nr_free_slices); + DMCRIT("PSI %u is occupied", *psi); + print_hex_dump(KERN_CRIT, "prmslices ", DUMP_PREFIX_OFFSET, 32, 4, sdev->prmslices, 4*sdev->tot_slices, false); + msleep(10000); + print_hex_dump(KERN_CRIT, "ofld ", DUMP_PREFIX_OFFSET, 32, 1, sdev->slices_ofld, sdev->tot_slices, false); + msleep(10000); + return -ENOTRECOVERABLE; // Grave inconsistency + } + + return 0; +} + +/** + * Map LSI => PSI, only in memory. + * Sanity checks to be performed by the caller. + * + * MUTEX: @sdev->slices_lock must be held. + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + */ +static void _create_local_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 psi) +{ + struct sflite_device *sdev = svol->sdev; + + /* Grab it from the device */ + sdev->slices_ofld[psi] = true; + sdev->nr_free_slices--; + // Preserve the invariant: @prmslices_octr must point to a free slice + while(sdev->prmslices_octr < sdev->tot_slices && + IS_PSI_TAKEN(sdev, NEXT_RANDOM_PSI(sdev))) { + sdev->prmslices_octr++; + } + + /* Insert in the volume */ + svol->posmap[lsi] = psi; + svol->nr_mapped_slices++; + + return; +} + +/** + * Delete mapping for the given LSI, only in memory. + * Sanity checks to be performed by the caller. + * + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + */ +static void _delete_local_slice_mapping(struct sflite_volume *svol, u32 lsi) +{ + /* Delete mapping in the volume */ + svol->posmap[lsi] = SFLITE_PSI_INVALID; + svol->nr_mapped_slices--; + + /* Don't do anything in the device though, leave it there: we don't yet + * have an obvious way to release PSIs. + * This means a PSI will be incorrectly marked as occupied, but that's + * not too bad: the PSI shuffling and its occupation counter are + * ephemeral, so they reset if you close and reopen all the volumes. */ + return; +} + +/** + * Synchronously store (and flush) the given posmap block + * + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + */ +static int store_posmap_block(struct sflite_volume *svol, u32 posmap_block_num) +{ + struct sflite_device *sdev = svol->sdev; + struct page *page; + struct bio *bio; + int err; + + /* Sync + flush TODO GFP mask ok? */ + bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, + REQ_OP_WRITE | REQ_SYNC | REQ_FUA, GFP_NOIO, + &sdev->bioset); + if (!bio) { + DMERR("Could not allocate posmap block bio"); + return -ENOMEM; + } + bio->bi_iter.bi_sector = SFLITE_POSMAP_START_SECTOR(svol) + + (posmap_block_num << SFLITE_BLOCK_SHIFT); + + /* Alloc and add page TODO GFP mask */ + page = alloc_page(GFP_NOIO); + if (!page) { + DMERR("Could not allocate posmap block page"); + err = -ENOMEM; + goto bad_alloc_page; + } + // TODO remove this error check + if (unlikely(!bio_add_page(bio, page, SFLITE_BLOCK_SIZE, 0))) { + DMCRIT("Could not add posmap block page to bio!"); + err = -ENOTRECOVERABLE; + goto bad_add_page; + } + + /* Serialise posmap block onto the page */ + void *page_ptr = kmap_local_page(page); + u32 first_lsi = posmap_block_num * SFLITE_PSIS_PER_BLOCK; + u32 last_lsi = min(first_lsi + SFLITE_PSIS_PER_BLOCK, sdev->tot_slices); + u32 lsi; + for (lsi = first_lsi; lsi < last_lsi; lsi++) { + u32 psi = svol->posmap[lsi]; + __be32 *be_psi = (__be32*) (page_ptr + ((lsi-first_lsi) * sizeof(__be32))); + *be_psi = cpu_to_be32(psi); + } + +// print_hex_dump(KERN_WARNING, "page_ptr(REV) ", DUMP_PREFIX_OFFSET, 32, 4, page_ptr, SFLITE_BLOCK_SIZE, false); +// msleep(100); + + kunmap_local(page_ptr); + + /* Encrypt the block in place */ + err = sflite_crypt_block_page(svol->tfm, page, page, + bio->bi_iter.bi_sector >> SFLITE_BLOCK_SHIFT, WRITE); + if (err) { + DMERR("Could not encrypt posmap block; error %d", err); + goto bad_encrypt; + } + + /* Submit */ + err = submit_bio_wait(bio); + if (err) + DMERR("Could not complete posmap block bio; error %d", err); + +bad_encrypt: +bad_add_page: + __free_page(page); +bad_alloc_page: + bio_put(bio); + return err; +} + + +/** + * Create a new mapping for the given LSI, and synchronise back to disk. + * + * MUTEX: @svol->posmap_lock must be held, except under volume ctor. + * MUTEX: takes @sdev->slices_lock. + * + * Syncing to disk means the posmap lock will be held (by the caller) for a long + * time thus blocking out all the other incoming bio's, even unrelated ones + * (falling in different slices). Several strategies are possible to avoid this + * problem, but for now we keep this simple implementation. + */ +int sflite_create_persistent_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 *psi) +{ + struct sflite_device *sdev = svol->sdev; + int err; + + /* Bounds check TODO redundant? */ + if(unlikely(lsi >= svol->sdev->tot_slices)) + return -EINVAL; + /* Check mapping not existent TODO redundant? */ + if (unlikely(svol->posmap[lsi] != SFLITE_PSI_INVALID)) + return -EINVAL; + + /* Create mapping */ + if (mutex_lock_interruptible(&sdev->slices_lock)) + return -ERESTARTSYS; + err = peek_next_free_psi(sdev, psi); + if (err) { + mutex_unlock(&sdev->slices_lock); + return err; + } + _create_local_slice_mapping(svol, lsi, *psi); + mutex_unlock(&sdev->slices_lock); + + /* Write posmap block to disk */ + err = store_posmap_block(svol, lsi/SFLITE_PSIS_PER_BLOCK); + if (err) { + DMERR("Could not store posmap block; error %d", err); + _delete_local_slice_mapping(svol, lsi); + return err; + } + + return 0; +} + + +/* + *---------------------------- + * Load position map + *---------------------------- + */ + +/** + * Synchronously read the entire on-disk encrypted position map + * + * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). + */ +static int read_encrypted_posmap(struct sflite_volume *svol) +{ + struct dm_io_request io_req = { + .bi_opf = REQ_OP_READ | REQ_SYNC, + .mem.type = DM_IO_VMA, + .mem.ptr.vma = svol->posmap, + .notify.fn = NULL, + .client = svol->sdev->io_client + }; + struct dm_io_region io_region = { + .bdev = svol->dm_dev->bdev, + .sector = SFLITE_POSMAP_START_SECTOR(svol), + .count = svol->sdev->posmap_size_sectors + }; + + return dm_io(&io_req, 1, &io_region, NULL); +} + +/** + * De-serialise the position map entries. On the fly, if a conflict is detected, + * resolve it by sampling a new PSI, and sync to disk (block by block). + * + * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). + * MUTEX: @sdev->slices_lock must be held. + */ +static int _deserialise_and_sanitise_posmap(struct sflite_volume *svol) +{ + struct sflite_device *sdev = svol->sdev; + void *posmap_ptr = svol->posmap; + u32 lsi; + bool posmap_block_dirty; + int err; + + for (lsi = 0; lsi < sdev->tot_slices; lsi++) { + /* Reset dirty bit at the start of every posmap block */ + if (lsi % SFLITE_PSIS_PER_BLOCK == 0) + posmap_block_dirty = false; + + /* De-serialise posmap entry */ + __be32 *be_psi = (__be32*) (posmap_ptr + (lsi * sizeof(__be32))); + u32 psi = be32_to_cpu(*be_psi); + + /* If LSI unmapped, skip mapping creation */ + if (psi == SFLITE_PSI_INVALID) { + svol->posmap[lsi] = psi; + goto skip_create_mapping; + } + + /* If PSI out of bounds, something's seriously wrong */ + if (psi >= sdev->tot_slices) { + DMERR("Decrypted PSI out of bounds: %u >= %u", psi, sdev->tot_slices); + return -EDOM; + } + + /* If PSI already taken, sample a new one */ + if (sdev->slices_ofld[psi]) { + DMWARN("Corruption of volume %u: LSI %u was evicted from PSI %u", + svol->vol_idx, lsi, psi); + err = peek_next_free_psi(sdev, &psi); + if (err) + return err; + posmap_block_dirty = true; + } + /* Whether sanitised or not, create the mapping locally */ + _create_local_slice_mapping(svol, lsi, psi); + +skip_create_mapping: + + /* Only check dirty bit at the end of the posmap block */ + if (posmap_block_dirty && + IS_LAST_LSI_IN_BLOCK(lsi, sdev)) { + err = store_posmap_block(svol, lsi/SFLITE_PSIS_PER_BLOCK); + if (err) + return err; + } + } + + return 0; +} + + +/** + * Load the volume's position map from the disk. If some conflicts are present + * (i.e. an LSI is mapped to a PSI that's already taken), then resolve them + * (i.e. re-sample a free PSI for the "unlucky" LSI) and sync back to disk. + * + * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). + * MUTEX: takes @sdev->slices_lock. + */ +int sflite_load_and_sanitise_posmap(struct sflite_volume *svol) +{ + int err; + struct sflite_device *sdev = svol->sdev; + + /* Read raw posmap from disk */ + err = read_encrypted_posmap(svol); + if (err) + return err; + + /* Decrypt in place */ + err = sflite_crypt_blocks_vm(svol->tfm, svol->posmap, svol->posmap, + svol->sdev->posmap_size_sectors >> SFLITE_BLOCK_SHIFT, + SFLITE_POSMAP_START_SECTOR(svol) >> SFLITE_BLOCK_SHIFT, + READ); + if (err) + return err; + + /* Deserialise and sanitise as you go */ + if (mutex_lock_interruptible(&sdev->slices_lock)) + return -ERESTARTSYS; + err = _deserialise_and_sanitise_posmap(svol); + mutex_unlock(&sdev->slices_lock); + if (err) + return err; + +// print_hex_dump(KERN_CRIT, "posmap(REV) ", DUMP_PREFIX_OFFSET, 32, 4, svol->posmap, 4*sdev->tot_slices, false); +// msleep(2000); + + return 0; +} + diff --git a/dm-sflc/lite/read.c b/dm-sflc/lite/read.c new file mode 100644 index 0000000..c7a2016 --- /dev/null +++ b/dm-sflc/lite/read.c @@ -0,0 +1,168 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "sflc_lite.h" +#include + + +static void sflite_read_endio(struct bio *phys_bio); +static void sflite_decrypt_work_fn(struct work_struct *work); + + +/* Landing here from ->map() through the io_queue */ +void sflite_read_work_fn(struct work_struct *work) +{ + struct sflite_io *sio = container_of(work, struct sflite_io, work); + struct sflite_volume *svol = sio->svol; + struct sflite_device *sdev = svol->sdev; + struct bio *orig_bio = sio->orig_bio; + struct bio *phys_bio; + u32 lsi = sio->lsi; + u32 block_offset = sio->block_offset; + u32 psi; + + /* Read position map */ + if (mutex_lock_interruptible(&svol->posmap_lock)) { + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + psi = svol->posmap[lsi]; + mutex_unlock(&svol->posmap_lock); + + /* If LSI is unmapped, short-circuit and return all zeros */ + if (psi == SFLITE_PSI_INVALID) { + + zero_fill_bio(orig_bio); + orig_bio->bi_status = BLK_STS_OK; + goto endio; + } + sio->psi = psi; + +// DMWARN("READ: LSI=%u, PSI=%u, offset=%u", lsi, psi, sio->block_offset); +// msleep(100); + + /* Shallow-copy the bio and submit it (different bi_endio). + We can shallow-copy because we don't need to own the pages, + we can decrypt in place. */ + + + //DMWARN("READ: shallow copying"); + //msleep(500); + + /* Shallow copy */ + phys_bio = bio_alloc_clone(svol->dm_dev->bdev, orig_bio, GFP_NOIO, &sdev->bioset); + if (!phys_bio) { + DMERR("Could not clone original bio"); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + /* Insert in the I/O struct */ + sio->phys_bio = phys_bio; + +// DMWARN("READ: submitting bio"); +// msleep(500); + + /* Remap sector */ + phys_bio->bi_iter.bi_sector = SFLITE_PHYS_BIO_SECTOR(sdev, psi, block_offset); + /* Set fields for the endio */ + phys_bio->bi_private = sio; + phys_bio->bi_end_io = sflite_read_endio; + /* Submit */ + dm_submit_bio_remap(orig_bio, phys_bio); + + return; + + +endio: + bio_endio(orig_bio); + return; +} + + +/* ISR for the phys_bio */ +static void sflite_read_endio(struct bio *phys_bio) +{ + struct sflite_io *sio = phys_bio->bi_private; + +// DMWARN("READ ENDIO: queueing decryption"); +// //msleep(500); + + /* Can't decrypt here in ISR: submit to decryption workqueue. + * Can reuse the same work item, though, since it was popped out of the + * io_queue already */ + INIT_WORK(&sio->work, sflite_decrypt_work_fn); + queue_work(sio->svol->sdev->crypt_queue, &sio->work); +} + + +/* Decrypt and endio */ +static void sflite_decrypt_work_fn(struct work_struct *work) +{ + struct sflite_io *sio = container_of(work, struct sflite_io, work); + struct sflite_volume *svol = sio->svol; + struct bio *orig_bio = sio->orig_bio; + struct bio *phys_bio = sio->phys_bio; + struct bio_vec bvl = bio_iovec(orig_bio); + int err; + + /* If physical bio failed, then fail-fast */ + if (phys_bio->bi_status != BLK_STS_OK) { + orig_bio->bi_status = phys_bio->bi_status; + goto endio; + } + +// DMWARN("DECRYPT FN: decrypting page in place"); +// msleep(2000); + + /* Decrypt page in-place */ + err = sflite_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_page, + SFLITE_PHYS_BIO_SECTOR(svol->sdev, sio->psi, sio->block_offset) >> SFLITE_BLOCK_SHIFT, + READ); + if (err) { + DMERR("Could not decrypt bio; error %d", err); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + +// print_hex_dump(KERN_WARNING, "readpage ", DUMP_PREFIX_OFFSET, 32, 1, bvl.bv_page, SFLITE_BLOCK_SIZE, true); +// msleep(2000); + +// DMWARN("DECRYPT FN: bio_advance"); +// msleep(300); + + /* Advance original bio by one block */ + bio_advance(orig_bio, SFLITE_BLOCK_SIZE); + orig_bio->bi_status = BLK_STS_OK; + +endio: + /* Free the physical bio */ +// DMWARN("DECRYPT FN: bio_put"); +// msleep(300); + bio_put(phys_bio); + /* End original bio */ +// DMWARN("DECRYPT FN: bio_endio\n\n\n\n"); +// msleep(300); + bio_endio(orig_bio); + + return; +} diff --git a/dm-sflc/lite/sflc_lite.c b/dm-sflc/lite/sflc_lite.c new file mode 100644 index 0000000..edc245f --- /dev/null +++ b/dm-sflc/lite/sflc_lite.c @@ -0,0 +1,161 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include +#include +#include "sflite_constants.h" +#include "sflc_lite.h" + +// Only to import the definition of struct sflc_volume +#include "sflc.h" + +#include + + +/* + *---------------------------- + * Device mapper target + *---------------------------- + */ + +static int sflite_map(struct dm_target *ti, struct bio *bio) +{ + struct sflite_io *sio = dm_per_bio_data(bio, sizeof(struct sflite_io)); + struct sflc_volume *top_vol = ti->private; + struct sflite_volume *svol = top_vol->sflite_vol; + sector_t lblk_num = bio->bi_iter.bi_sector >> SFLITE_BLOCK_SHIFT; + + if (unlikely(!bio_has_data(bio))) { +// DMWARN("No-data bio: bio_op() = %d, bi_opf = %u, bi_io_vec = %p, bi_idx = %u", bio_op(bio), bio->bi_opf, bio->bi_io_vec, bio->bi_iter.bi_idx); +// msleep(100); + } + + /* Flush requests are just passed down, since our position map is + * currently write-through, so we have no volatile cache */ + if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { + /* Has to be empty though */ + if (bio_sectors(bio)) { + DMWARN("Non-empty flush request!"); + msleep(3000); + return DM_MAPIO_KILL; + } +// DMWARN("REQ_PREFLUSH empty (phew), sector: %llu", bio->bi_iter.bi_sector); +// msleep(100); + bio_set_dev(bio, svol->dm_dev->bdev); + return DM_MAPIO_REMAPPED; + } + + /* Accept one block at a time TODO improve */ + if (unlikely(bio->bi_iter.bi_size > SFLITE_BLOCK_SIZE)) { + DMWARN("Big bio: %u", bio->bi_iter.bi_size); + msleep(300); + dm_accept_partial_bio(bio, SFLITE_BLOCK_SCALE); + } + /* Only one segment, single page, starting at 0 TODO improve */ + if (unlikely(bio_segments(bio) > 1 || + bio_offset(bio) != 0)) { + DMWARN("Unaligned bio!"); + msleep(3000); + return DM_MAPIO_KILL; + } + if (unlikely(bio->bi_iter.bi_size != SFLITE_BLOCK_SIZE)) { + DMWARN("Wrong bio size: %u", bio->bi_iter.bi_size); + msleep(3000); + return DM_MAPIO_KILL; + } + + /* Init I/O struct */ + sio->svol = svol; + sio->orig_bio = bio; + sio->lsi = lblk_num >> SFLITE_SLICE_SHIFT; + sio->block_offset = lblk_num & ((1U << SFLITE_SLICE_SHIFT) - 1); + + /* Enqueue */ + if (bio_data_dir(bio) == READ) + INIT_WORK(&sio->work, sflite_read_work_fn); + else + INIT_WORK(&sio->work, sflite_write_work_fn); + queue_work(svol->sdev->io_queue, &sio->work); + + return DM_MAPIO_SUBMITTED; +} + + +static void sflite_io_hints(struct dm_target *ti, struct queue_limits *limits) +{ + // Currently, we only handle one block at a time TODO improve + limits->logical_block_size = SFLITE_BLOCK_SIZE; + limits->physical_block_size = SFLITE_BLOCK_SIZE; + limits->io_min = SFLITE_BLOCK_SIZE; + limits->io_opt = SFLITE_BLOCK_SIZE; + + return; +} + + +static int sflite_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) +{ + struct sflc_volume *top_vol = ti->private; + struct sflite_volume *svol = top_vol->sflite_vol; + struct sflite_device *sdev = svol->sdev; + + if (!fn) { + dump_stack(); + msleep(2000); + return -EINVAL; + } + return fn(ti, svol->dm_dev, 0, sdev->dev_header_size_sectors + ti->len, data); +} + + +struct target_type sflite_target_type = { + .map = sflite_map, + .io_hints = sflite_io_hints, + .iterate_devices = sflite_iterate_devices, +}; + + +/* + *---------------------------- + * Init and exit + *---------------------------- + */ + +int sflite_init(void) +{ + /* For the moment, we assume PAGE_SIZE == SFLITE_BLOCK_SIZE TODO improve */ + if (SFLITE_BLOCK_SIZE != PAGE_SIZE) { + DMERR("Error, PAGE_SIZE != %d bytes not yet supported", SFLITE_BLOCK_SIZE); + return -ENOTRECOVERABLE; + } + + return 0; +} + + +void sflite_exit(void) +{ + return; +} + diff --git a/dm-sflc/lite/sflc_lite.h b/dm-sflc/lite/sflc_lite.h new file mode 100644 index 0000000..1c2e5a7 --- /dev/null +++ b/dm-sflc/lite/sflc_lite.h @@ -0,0 +1,182 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _SFLITE_SFLITE_H +#define _SFLITE_SFLITE_H + +#include +#include +#include +#include +#include "sflite_constants.h" +#include "sflc_constants.h" + + +/* + *---------------------------- + * Structs + *---------------------------- + */ + +struct sflite_device +{ + /* Shufflecake-unique device ID */ + u32 dev_id; + /* : */ + char name[16]; + + /* Logical size of each volume */ + u32 tot_slices; + /* Header sizes in 512-byte sectors */ + sector_t posmap_size_sectors; + sector_t dev_header_size_sectors; + + /* Shuffled array of PSIs */ + struct mutex slices_lock; + u32 *prmslices; + u32 prmslices_octr; + bool *slices_ofld; + u32 nr_free_slices; + + /* Parent sysfs directory */ + struct kobject *kobj_parent; + + /* Resource sharing */ + struct bio_set bioset; + struct dm_io_client *io_client; + struct workqueue_struct *io_queue; + struct workqueue_struct *crypt_queue; +}; + +struct sflite_volume +{ + /* Backing device */ + struct sflite_device *sdev; + + /* Underlying block device. This can't go in the sflite_device struct, + * because each ti grabs its own reference. */ + struct dm_dev *dm_dev; + struct dm_target *ti; + + /* Volume index within the device */ + u32 vol_idx; + /* Volume name: sflite__ */ + char name[32]; + + /* Position map */ + struct mutex posmap_lock; + u32 *posmap; + u32 nr_mapped_slices; + + /* Parent sysfs directory */ + struct kobject *kobj_parent; + + /* Crypto */ + u8 enckey[SFLITE_XTS_KEYLEN]; + struct crypto_skcipher *tfm; +}; + +struct sflite_io +{ + struct sflite_volume *svol; + + struct bio *orig_bio; + struct bio *phys_bio; + u32 lsi; + u32 block_offset; + u32 psi; + + struct work_struct work; +}; + + +/* + *---------------------------- + * Macros + *---------------------------- + */ + +/* Starting sector of position map */ +#define SFLITE_POSMAP_START_SECTOR(svol) \ + (SFLITE_BLOCK_SCALE * (1 + SFLITE_DEV_MAX_VOLUMES) + \ + (svol)->vol_idx * (svol)->sdev->posmap_size_sectors) + + +/* Physical sector of a remapped bio */ +#define SFLITE_PHYS_BIO_SECTOR(sdev, psi, off) ( \ + (sdev)->dev_header_size_sectors + ( \ + ((psi << SFLITE_SLICE_SHIFT) + off) << SFLITE_BLOCK_SHIFT \ + ) \ +) + + +/* + *---------------------------- + * Public variables + *---------------------------- + */ + +extern struct target_type sflite_target_type; + + +/* + *---------------------------- + * Functions + *---------------------------- + */ + +/* Init and exit */ +int sflite_init(void); +void sflite_exit(void); + +/* Device */ +struct sflite_device *sflite_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj); +void sflite_dev_destroy(struct sflite_device *sdev); + +/* Volume */ +struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_device *sdev, + int argc, char **argv, struct kobject *kobj); +void sflite_vol_destroy(struct sflite_volume *svol); + +/* Sysfs */ +int sflite_sysfs_add_device(struct sflite_device *sdev); +void sflite_sysfs_remove_device(struct sflite_device *sdev); +int sflite_sysfs_add_volume(struct sflite_volume *svol); +void sflite_sysfs_remove_volume(struct sflite_volume *svol); + +/* Bio mapping */ +void sflite_read_work_fn(struct work_struct *work); +void sflite_write_work_fn(struct work_struct *work); + +/* Position map */ +int sflite_load_and_sanitise_posmap(struct sflite_volume *svol); +int sflite_create_persistent_slice_mapping(struct sflite_volume *svol, u32 lsi, u32 *psi); + +/* Crypto */ +int sflite_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, + u64 num_blocks, u64 first_pblk_num, int rw); +int sflite_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, + struct page *dst_page, u64 pblk_num, int rw); + + +#endif /* _SFLITE_SFLITE_H */ diff --git a/dm-sflc/lite/sflite_constants.h b/dm-sflc/lite/sflite_constants.h new file mode 100644 index 0000000..801ff59 --- /dev/null +++ b/dm-sflc/lite/sflite_constants.h @@ -0,0 +1,53 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/* Constants specific to Shufflecake Lite */ + +#ifndef _SFLITE_SFLITE_CONSTANTS_H_ +#define _SFLITE_SFLITE_CONSTANTS_H_ + + +#define SFLITE_BLOCK_SIZE 4096 /* bytes */ +#define SFLITE_BLOCK_SHIFT 3 +#define SFLITE_BLOCK_SCALE (1 << SFLITE_BLOCK_SHIFT) /* 8 sectors in a block */ +#define SFLITE_SLICE_SHIFT 8 +#define SFLITE_SLICE_SCALE (1 << SFLITE_SLICE_SHIFT) /* 256 blocks in a slice */ + + +/* XTS requires doubling the key size */ +#define SFLITE_XTS_KEYLEN 64 /* bytes */ +/* The IV is the right-0-padded LE physical block number */ +#define SFLITE_XTS_IVLEN 16 /* bytes */ + + +#define SFLITE_DEV_MAX_VOLUMES 15 +#define SFLITE_MAX_DEVS 1024 + + +#define SFLITE_PSI_INVALID 0xFFFFFFFF +/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ +#define SFLITE_PSIS_PER_BLOCK 1024 + + + +#endif /* _SFLITE_SFLITE_CONSTANTS_H_ */ diff --git a/dm-sflc/lite/sysfs.c b/dm-sflc/lite/sysfs.c new file mode 100644 index 0000000..88e2d06 --- /dev/null +++ b/dm-sflc/lite/sysfs.c @@ -0,0 +1,116 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "sflc_lite.h" + +// Only to import the definitions of structs sflc_volume and sflc_device +#include "sflc.h" + +/* + *---------------------------- + * Device entries + *---------------------------- + */ + +static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_device *top_dev = container_of(kobj, struct sflc_device, kobj); + struct sflite_device *sdev = top_dev->sflite_dev; + + return sysfs_emit(buf, "%u\n", sdev->tot_slices); +} + +static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_device *top_dev = container_of(kobj, struct sflc_device, kobj); + struct sflite_device *sdev = top_dev->sflite_dev; + int ret; + + if (mutex_lock_interruptible(&sdev->slices_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", sdev->nr_free_slices); + mutex_unlock(&sdev->slices_lock); + + return ret; +} + +static struct kobj_attribute tot_slices_kattr = __ATTR_RO(tot_slices); +static struct kobj_attribute free_slices_kattr = __ATTR_RO(free_slices); +static struct attribute *sflite_device_attrs[] = { + &tot_slices_kattr.attr, + &free_slices_kattr.attr, + NULL +}; +static const struct attribute_group sflite_device_attr_group = { + .attrs = sflite_device_attrs, +}; + +int sflite_sysfs_add_device(struct sflite_device *sdev) +{ + return sysfs_create_group(sdev->kobj_parent, &sflite_device_attr_group); +} + +void sflite_sysfs_remove_device(struct sflite_device *sdev) +{ + sysfs_remove_group(sdev->kobj_parent, &sflite_device_attr_group); +} + + +/* + *---------------------------- + * Volume entries + *---------------------------- + */ + +static ssize_t mapped_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) +{ + struct sflc_volume *top_vol = container_of(kobj, struct sflc_volume, kobj); + struct sflite_volume *svol = top_vol->sflite_vol; + int ret; + + if (mutex_lock_interruptible(&svol->posmap_lock)) + return -ERESTARTSYS; + ret = sysfs_emit(buf, "%u\n", svol->nr_mapped_slices); + mutex_unlock(&svol->posmap_lock); + + return ret; +} + +static struct kobj_attribute mapped_slices_kattr = __ATTR_RO(mapped_slices); +static struct attribute *sflite_volume_attrs[] = { + &mapped_slices_kattr.attr, + NULL +}; +static const struct attribute_group sflite_volume_attr_group = { + .attrs = sflite_volume_attrs, +}; + +int sflite_sysfs_add_volume(struct sflite_volume *svol) +{ + return sysfs_create_group(svol->kobj_parent, &sflite_volume_attr_group); +} + +void sflite_sysfs_remove_volume(struct sflite_volume *svol) +{ + sysfs_remove_group(svol->kobj_parent, &sflite_volume_attr_group); +} diff --git a/dm-sflc/lite/volume.c b/dm-sflc/lite/volume.c new file mode 100644 index 0000000..78dc76b --- /dev/null +++ b/dm-sflc/lite/volume.c @@ -0,0 +1,162 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include +#include "sflc_lite.h" + + +/** + * Arguments: + * argv[0]: Shufflecake mode: legacy/lite + * argv[1]: Shufflecake-unique device ID + * argv[2]: path to underlying physical device + * argv[3]: volume index within the device + * argv[4]: number of 1 MB slices in the underlying device + * argv[5]: 64-byte encryption key (hex-encoded) + */ +struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_device* sdev, + int argc, char **argv, struct kobject *kobj) +{ + struct sflite_volume *svol; + u32 vol_idx; + int err; + + svol = kzalloc(sizeof(*svol), GFP_KERNEL); + if (!svol) { + DMERR("Could not allocate volume"); + return ERR_PTR(-ENOMEM); + } + + /* Parse arguments */ + if (argc != 6) { + DMERR("Wrong argument count"); + err = -EINVAL; + goto bad_parse; + } + if (sscanf(argv[3], "%u", &vol_idx) != 1) { + DMERR("Could not decode tot_slices\n"); + err = -EINVAL; + goto bad_parse; + } + /* Decode the encryption key */ + if (strlen(argv[5]) != 2 * SFLITE_XTS_KEYLEN) { + DMERR("Invalid key length"); + err = -EINVAL; + goto bad_parse; + } + err = hex2bin(svol->enckey, argv[5], SFLITE_XTS_KEYLEN); + if (err) { + DMERR("Could not decode hexadecimal encryption key"); + err = -EINVAL; + goto bad_parse; + } + + svol->sdev = sdev; + svol->vol_idx = vol_idx; + sprintf(svol->name, "sflc_%u_%u", sdev->dev_id, vol_idx); + + svol->ti = ti; + err = dm_get_device(ti, sdev->name, + dm_table_get_mode(ti->table), &svol->dm_dev); + if (err) { + ti->error = "Device lookup failed"; + goto bad_dm_dev; + } + + /* Crypto */ + svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); + if (IS_ERR(svol->tfm)) { + err = PTR_ERR(svol->tfm); + DMERR("Could not allocate AES-XTS cipher handle; error %d", err); + goto bad_tfm_alloc; + } + err = crypto_skcipher_setkey(svol->tfm, svol->enckey, SFLITE_XTS_KEYLEN); + if (err) { + DMERR("Could not set key in crypto transform; error %d", err); + goto bad_tfm_setkey; + } + + /* Position map */ + mutex_init(&svol->posmap_lock); + /* Slight over-allocation, to fit a whole number of blocks */ + svol->posmap = vmalloc(sdev->posmap_size_sectors * SECTOR_SIZE); + if (!svol->posmap) { + DMERR("Could not allocate position map"); + err = -ENOMEM; + goto bad_posmap_alloc; + } + svol->nr_mapped_slices = 0; + /* Load from disk */ + err = sflite_load_and_sanitise_posmap(svol); + if (err) { + DMERR("Could not load position map from disk; error %d", err); + goto bad_posmap_load; + } + + /* Add to sysfs, once initialised */ + err = sflite_sysfs_add_volume(svol); + if (err) { + DMERR("Could not register volume with sysfs; error %d", err); + goto bad_sysfs; + } + + /* Only accept one block per request for simplicity TODO: improve to one slice*/ + ti->max_io_len = SFLITE_BLOCK_SCALE; + ti->flush_supported = true; + ti->num_flush_bios = 1; + ti->discards_supported = false; + ti->num_discard_bios = 0; + ti->num_secure_erase_bios = 0; + ti->num_write_zeroes_bios = 0; + ti->accounts_remapped_io = true; + ti->per_io_data_size = sizeof(struct sflite_io); + ti->private = svol; + + return svol; + + +bad_sysfs: +bad_posmap_load: + vfree(svol->posmap); +bad_posmap_alloc: +bad_tfm_setkey: + crypto_free_skcipher(svol->tfm); +bad_tfm_alloc: + dm_put_device(ti, svol->dm_dev); +bad_dm_dev: +bad_parse: + kfree(svol); + return ERR_PTR(err); +} + + +void sflite_vol_destroy(struct sflite_volume *svol) +{ + sflite_sysfs_remove_volume(svol); + vfree(svol->posmap); + crypto_free_skcipher(svol->tfm); + dm_put_device(svol->ti, svol->dm_dev); + kfree(svol); + + return; +} diff --git a/dm-sflc/lite/write.c b/dm-sflc/lite/write.c new file mode 100644 index 0000000..5b2fb66 --- /dev/null +++ b/dm-sflc/lite/write.c @@ -0,0 +1,148 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#include "sflc_lite.h" +#include + + +static void sflite_write_endio(struct bio *phys_bio); + + +void sflite_write_work_fn(struct work_struct *work) +{ + struct sflite_io *sio = container_of(work, struct sflite_io, work); + struct sflite_volume *svol = sio->svol; + struct sflite_device *sdev = svol->sdev; + struct bio *orig_bio = sio->orig_bio; + struct bio_vec bvl = bio_iovec(orig_bio); + struct bio *phys_bio; + struct page *page; + u32 lsi = sio->lsi; + u32 block_offset = sio->block_offset; + u32 psi; + int err; + +// DMWARN("WRITE: dequeued. Sector = %llu", orig_bio->bi_iter.bi_sector); +// msleep(100); + + + /* Read existing mapping, or create new one */ + if (mutex_lock_interruptible(&svol->posmap_lock)) { + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + psi = svol->posmap[lsi]; + /* If LSI unmapped, create new mapping, while holding the lock */ + if (psi == SFLITE_PSI_INVALID) { +// DMWARN("WRITE: unmapped LSI %u, sampling PSI", lsi); +// msleep(100); + + err = sflite_create_persistent_slice_mapping(svol, lsi, &psi); + if (err){ + DMERR("Could not create slice mapping; error %d", err); + mutex_unlock(&svol->posmap_lock); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } +// DMWARN("WRITE: sampled PSI %u for LSI %u", psi, lsi); +// msleep(100); + } + mutex_unlock(&svol->posmap_lock); + sio->psi = psi; + + /* Allocate physical bio */ + phys_bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, orig_bio->bi_opf, + GFP_NOIO, &sdev->bioset); + if (!phys_bio) { + DMERR("Could not allocate physical bio"); + orig_bio->bi_status = BLK_STS_IOERR; + goto endio; + } + /* Insert in the I/O struct */ + sio->phys_bio = phys_bio; + + /* Physical bio needs its own page */ + page = alloc_pages(GFP_NOIO, 0); + if (!page) { + DMERR("Could not allocate page for physical bio"); + orig_bio->bi_status = BLK_STS_IOERR; + goto bad_alloc_page; + } + + /* Remap sector */ + phys_bio->bi_iter.bi_sector = SFLITE_PHYS_BIO_SECTOR(sdev, psi, block_offset); + /* Encrypt */ + err = sflite_crypt_block_page(svol->tfm, bvl.bv_page, page, + phys_bio->bi_iter.bi_sector >> SFLITE_BLOCK_SHIFT, WRITE); + if (err) { + DMERR("Could not encrypt bio; error %d", err); + orig_bio->bi_status = BLK_STS_IOERR; + goto bad_encrypt; + } + + /* Add page to bio */ + __bio_add_page(phys_bio, page, SFLITE_BLOCK_SIZE, 0); + /* Set fields for the endio */ + phys_bio->bi_private = sio; + phys_bio->bi_end_io = sflite_write_endio; + /* Submit */ + dm_submit_bio_remap(orig_bio, phys_bio); + + return; + + +bad_encrypt: + __free_page(page); +bad_alloc_page: + bio_put(phys_bio); +endio: + bio_endio(orig_bio); + return; +} + +static void sflite_write_endio(struct bio *phys_bio) +{ + struct sflite_io *sio = phys_bio->bi_private; + struct bio *orig_bio = sio->orig_bio; + + /* If physical bio failed, then fail-fast */ + if (phys_bio->bi_status != BLK_STS_OK) { + orig_bio->bi_status = phys_bio->bi_status; + DMWARN("WRITE ENDIO: phys_bio failed"); + goto endio; + } + + /* Advance original bio by one block */ + bio_advance(orig_bio, SFLITE_BLOCK_SIZE); + orig_bio->bi_status = BLK_STS_OK; + +endio: + /* Free the physical bio and its page */ + bio_free_pages(phys_bio); + bio_put(phys_bio); + /* End original bio */ + bio_endio(orig_bio); + + return; +} + diff --git a/dm-sflc/old/device/device.c b/dm-sflc/old/device/device.c index 1795575..b5045c1 100644 --- a/dm-sflc/old/device/device.c +++ b/dm-sflc/old/device/device.c @@ -54,7 +54,7 @@ static int sfold_dev_initAndShufflePsiArray(u32 *psi_array, u32 len); *****************************************************/ /** - * Creates Device and adds it to the list. Returns an ERR_PTR() if unsuccessful. + * Creates Device. Returns an ERR_PTR() if unsuccessful. * Arguments: * argv[0]: Shufflecake mode: legacy/lite * argv[1]: Shufflecake-unique device ID @@ -80,6 +80,11 @@ sfold_Device *sfold_dev_create(struct dm_target *ti, int argc, char **argv, stru } /* Parse args */ + if (argc != 6) { + pr_err("Wrong argument count"); + err = -EINVAL; + goto err_parse; + } sscanf(argv[1], "%u", &dev_id); if (sscanf(argv[4], "%u", &tot_slices) != 1) { pr_err("Could not decode tot_slices\n"); diff --git a/dm-sflc/old/volume/volume.c b/dm-sflc/old/volume/volume.c index e8b97b6..862d8f5 100644 --- a/dm-sflc/old/volume/volume.c +++ b/dm-sflc/old/volume/volume.c @@ -41,7 +41,7 @@ *****************************************************/ /** - * Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful + * Creates volume. Returns an ERR_PTR() if unsuccessful * Arguments: * argv[0]: Shufflecake mode: legacy/lite * argv[1]: Shufflecake-unique device ID @@ -67,6 +67,11 @@ sfold_Volume * sfold_vol_create(struct dm_target * ti, sfold_Device* dev, } /* Parse args */ + if (argc != 6) { + pr_err("Wrong argument count"); + err = -EINVAL; + goto err_parse; + } if (sscanf(argv[3], "%u", &vol_idx) != 1) { pr_err("Could not decode tot_slices\n"); err = -EINVAL; diff --git a/dm-sflc/sflc.c b/dm-sflc/sflc.c index 0938fb0..5f154ab 100644 --- a/dm-sflc/sflc.c +++ b/dm-sflc/sflc.c @@ -26,6 +26,7 @@ #include "sflc.h" #include "old/sflc_old.h" +#include "lite/sflc_lite.h" // Global variables @@ -228,11 +229,16 @@ static int sflc_init(void) if (ret) goto err_sysfs; - /* Init the legacy module */ + /* Init the Legacy module */ ret = sfold_init(); if (ret) goto err_sfold; + /* Init the Lite module */ + ret = sflite_init(); + if (ret) + goto err_sflite; + /* Register the DM callbacks */ ret = dm_register_target(&sflc_target_type); if (ret < 0) @@ -243,6 +249,8 @@ static int sflc_init(void) err_dm: + sflite_exit(); +err_sflite: sfold_exit(); err_sfold: sflc_sysfs_exit(); @@ -256,6 +264,7 @@ static void sflc_exit(void) { dm_unregister_target(&sflc_target_type); sfold_exit(); + sflite_exit(); sflc_sysfs_exit(); DMINFO("unloaded"); diff --git a/dm-sflc/sflc.h b/dm-sflc/sflc.h index 6248f74..1462d16 100644 --- a/dm-sflc/sflc.h +++ b/dm-sflc/sflc.h @@ -29,6 +29,7 @@ #include "sflc_constants.h" #include "old/sflc_old.h" +#include "lite/sflc_lite.h" /* @@ -50,6 +51,7 @@ struct sflc_device int mode; union { sfold_Device *sfold_dev; + struct sflite_device *sflite_dev; }; /* Sysfs */ @@ -68,6 +70,7 @@ struct sflc_volume int mode; union { sfold_Volume *sfold_vol; + struct sflite_volume *sflite_vol; }; /* Pointers to concrete, mode-specific callbacks */ struct target_type *tt; From 322f4367a6357d3bcc44a0830922234cb629a6f4 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 3 Aug 2024 22:40:11 +0200 Subject: [PATCH 60/75] Bugfix --- .gitignore | 2 + dm-sflc/dev_vol.c | 3 + dm-sflc/lite/volume.c | 1 + dm-sflc/sflc.c | 14 ++ dm-sflc/sysfs.c | 9 +- .../.gitignore | 0 .../Makefile | 0 .../Makefile.sources | 0 .../include/actions/device.h | 0 .../include/actions/volume.h | 0 .../include/cli/cli.h | 0 .../include/commands/commands.h | 0 .../include/header/device_master_block.h | 0 .../include/header/position_map.h | 0 .../include/header/volume_master_block.h | 0 .../include/sflc_constants.h | 0 .../include/utils/crypto.h | 0 .../include/utils/disk.h | 0 .../include/utils/dm.h | 0 .../include/utils/file.h | 0 .../include/utils/input.h | 0 .../include/utils/log.h | 0 .../include/utils/math.h | 0 .../include/utils/sflc.h | 0 .../include/utils/string.h | 0 .../src/actions/close.c | 0 .../src/actions/close_vol.c | 0 .../src/actions/create.c | 0 .../src/actions/create_vol.c | 0 .../src/actions/dmb.c | 0 .../src/actions/open.c | 0 .../src/actions/open_vol.c | 0 .../src/cli/close.c | 0 .../src/cli/dispatch.c | 0 .../src/cli/init.c | 0 .../src/cli/open.c | 0 .../src/commands/close.c | 0 .../src/commands/init.c | 0 .../src/commands/open.c | 0 .../src/header/device_master_block.c | 0 .../src/header/position_map.c | 0 .../src/header/volume_master_block.c | 0 .../src/main.c | 0 .../src/utils/crypto.c | 0 .../src/utils/disk.c | 0 .../src/utils/dm.c | 0 .../src/utils/file.c | 0 .../src/utils/input.c | 0 .../src/utils/string.c | 0 .../test/actions/test_actions.h | 0 .../test/actions/test_all_actions.c | 0 .../test/actions/test_create.c | 0 .../test/commands/test_commands.h | 0 .../test/commands/test_init.c | 0 .../test/crypto/test_aes256ctr.c | 0 .../test/crypto/test_aes256ctr.h | 0 .../test/crypto/test_aes256gcm.c | 0 .../test/crypto/test_aes256gcm.h | 0 .../test/crypto/test_argon2id.c | 0 .../test/crypto/test_argon2id.h | 0 .../test/main.c | 0 .../test/minunit.h | 0 .../.gitignore | 0 .../Makefile | 4 +- .../Makefile.sources | 0 .../include/cli.h | 22 +-- .../include/commands.h | 24 +-- .../include/header.h | 44 +++--- .../include/operations.h | 16 +- .../include/utils/crypto.h | 42 ++--- .../include/utils/disk.h | 26 +-- .../include/utils/dm.h | 6 +- .../include/utils/file.h | 2 +- .../include/utils/input.h | 6 +- .../include/utils/log.h | 80 +++++----- .../include/utils/math.h | 0 .../include/utils/sflite.h | 49 +++--- .../include/utils/string.h | 4 +- .../src/cli/changepwd.c | 32 ++-- .../src/cli/close.c | 14 +- .../src/cli/dispatch.c | 98 +++++------- .../src/cli/init.c | 34 ++-- .../src/cli/open.c | 16 +- .../src/cli/testpwd.c | 22 +-- .../src/commands/change_pwd.c | 6 +- .../src/commands/close.c | 54 +++---- .../src/commands/init.c | 58 +++---- .../src/commands/open.c | 48 +++--- .../src/commands/test_pwd.c | 6 +- .../src/header/device_master_block.c | 90 +++++------ .../src/header/position_map.c | 26 +-- .../src/header/volume_master_block.c | 72 ++++----- .../src/main.c | 2 +- .../src/operations/devmapper.c | 28 ++-- .../src/operations/dmb.c | 52 +++--- .../src/operations/volume_header.c | 40 ++--- .../src/utils/crypto.c | 148 +++++++++--------- .../src/utils/disk.c | 56 +++---- .../src/utils/dm.c | 57 +++---- .../src/utils/file.c | 6 +- .../src/utils/input.c | 8 +- .../src/utils/string.c | 6 +- .../test/crypto/test_aes256ctr.c | 24 +-- .../test/crypto/test_aes256ctr.h | 0 .../test/crypto/test_aes256gcm.c | 22 +-- .../test/crypto/test_aes256gcm.h | 0 .../test/crypto/test_argon2id.c | 18 +-- .../test/crypto/test_argon2id.h | 0 .../test/main.c | 6 +- .../test/minunit.h | 0 vuvuzela-userland/include/vvz_constants.h | 1 - 111 files changed, 707 insertions(+), 697 deletions(-) rename {shufflecake-userland => shufflecake-userland-legacy}/.gitignore (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/Makefile (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/Makefile.sources (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/actions/device.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/actions/volume.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/cli/cli.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/commands/commands.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/header/device_master_block.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/header/position_map.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/header/volume_master_block.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/sflc_constants.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/crypto.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/disk.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/dm.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/file.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/input.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/log.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/math.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/sflc.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/include/utils/string.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/close.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/close_vol.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/create.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/create_vol.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/dmb.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/open.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/actions/open_vol.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/cli/close.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/cli/dispatch.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/cli/init.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/cli/open.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/commands/close.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/commands/init.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/commands/open.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/header/device_master_block.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/header/position_map.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/header/volume_master_block.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/main.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/utils/crypto.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/utils/disk.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/utils/dm.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/utils/file.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/utils/input.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/src/utils/string.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/actions/test_actions.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/actions/test_all_actions.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/actions/test_create.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/commands/test_commands.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/commands/test_init.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/crypto/test_aes256ctr.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/crypto/test_aes256ctr.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/crypto/test_aes256gcm.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/crypto/test_aes256gcm.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/crypto/test_argon2id.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/crypto/test_argon2id.h (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/main.c (100%) rename {shufflecake-userland => shufflecake-userland-legacy}/test/minunit.h (100%) rename {vuvuzela-userland => shufflecake-userland-lite}/.gitignore (100%) rename {vuvuzela-userland => shufflecake-userland-lite}/Makefile (98%) rename {vuvuzela-userland => shufflecake-userland-lite}/Makefile.sources (100%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/cli.h (79%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/commands.h (87%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/header.h (75%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/operations.h (73%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/crypto.h (72%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/disk.h (75%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/dm.h (92%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/file.h (97%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/input.h (92%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/log.h (58%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/math.h (100%) rename vuvuzela-userland/include/utils/vvz.h => shufflecake-userland-lite/include/utils/sflite.h (68%) rename {vuvuzela-userland => shufflecake-userland-lite}/include/utils/string.h (93%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/cli/changepwd.c (79%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/cli/close.c (85%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/cli/dispatch.c (70%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/cli/init.c (78%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/cli/open.c (87%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/cli/testpwd.c (83%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/commands/change_pwd.c (91%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/commands/close.c (72%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/commands/init.c (69%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/commands/open.c (74%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/commands/test_pwd.c (91%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/header/device_master_block.c (64%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/header/position_map.c (80%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/header/volume_master_block.c (67%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/main.c (97%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/operations/devmapper.c (76%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/operations/dmb.c (67%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/operations/volume_header.c (71%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/utils/crypto.c (66%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/utils/disk.c (74%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/utils/dm.c (75%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/utils/file.c (92%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/utils/input.c (93%) rename {vuvuzela-userland => shufflecake-userland-lite}/src/utils/string.c (92%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/crypto/test_aes256ctr.c (88%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/crypto/test_aes256ctr.h (100%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/crypto/test_aes256gcm.c (87%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/crypto/test_aes256gcm.h (100%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/crypto/test_argon2id.c (84%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/crypto/test_argon2id.h (100%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/main.c (94%) rename {vuvuzela-userland => shufflecake-userland-lite}/test/minunit.h (100%) delete mode 120000 vuvuzela-userland/include/vvz_constants.h diff --git a/.gitignore b/.gitignore index d56891f..2d88f50 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,8 @@ dkms.conf # Shufflecake binaries shufflecake +shufflecake-lite +shufflecake-legacy # Build directory bin/ diff --git a/dm-sflc/dev_vol.c b/dm-sflc/dev_vol.c index 7d6f258..3c5e5b3 100644 --- a/dm-sflc/dev_vol.c +++ b/dm-sflc/dev_vol.c @@ -21,6 +21,8 @@ * If not, see . */ +#include + #include "sflc.h" #include "old/sflc_old.h" @@ -143,6 +145,7 @@ struct sflc_volume *sflc_vol_create(struct sflc_device *sdev, struct dm_target * /* Assign fields */ svol->mode = mode; sprintf(svol->name, "sflc_%u_%u", sdev->dev_id, vol_idx); + svol->sdev = sdev; /* Register with sysfs */ err = sflc_sysfs_register_volume(svol); diff --git a/dm-sflc/lite/volume.c b/dm-sflc/lite/volume.c index 78dc76b..e37d9c1 100644 --- a/dm-sflc/lite/volume.c +++ b/dm-sflc/lite/volume.c @@ -114,6 +114,7 @@ struct sflite_volume *sflite_vol_create(struct dm_target *ti, struct sflite_devi } /* Add to sysfs, once initialised */ + svol->kobj_parent = kobj; err = sflite_sysfs_add_volume(svol); if (err) { DMERR("Could not register volume with sysfs; error %d", err); diff --git a/dm-sflc/sflc.c b/dm-sflc/sflc.c index 5f154ab..67676b2 100644 --- a/dm-sflc/sflc.c +++ b/dm-sflc/sflc.c @@ -23,11 +23,14 @@ #include #include +#include #include "sflc.h" #include "old/sflc_old.h" #include "lite/sflc_lite.h" +#include + // Global variables DEFINE_MUTEX(sflc_alldevs_lock); @@ -224,6 +227,13 @@ static int sflc_init(void) { int ret; + sflc_alldevs = vzalloc(SFLC_MAX_DEVS * sizeof(*sflc_alldevs)); + if (!sflc_alldevs) { + DMERR("Could not allocate sflc_alldevs"); + ret = -ENOMEM; + goto bad_alldevs_alloc; + } + /* Create the first sysfs entries */ ret = sflc_sysfs_init(); if (ret) @@ -255,6 +265,9 @@ err_sflite: err_sfold: sflc_sysfs_exit(); err_sysfs: + vfree(sflc_alldevs); +bad_alldevs_alloc: + DMERR("not loaded"); return ret; } @@ -266,6 +279,7 @@ static void sflc_exit(void) sfold_exit(); sflite_exit(); sflc_sysfs_exit(); + vfree(sflc_alldevs); DMINFO("unloaded"); return; diff --git a/dm-sflc/sysfs.c b/dm-sflc/sysfs.c index acea092..2ef402d 100644 --- a/dm-sflc/sysfs.c +++ b/dm-sflc/sysfs.c @@ -23,6 +23,8 @@ #include "sflc.h" +#include + /* *---------------------------- * Top-level entries @@ -157,11 +159,6 @@ void sflc_sysfs_unregister_device(struct sflc_device *sdev) *---------------------------- */ -static struct attribute *sflc_volume_default_attrs[] = { - NULL -}; -ATTRIBUTE_GROUPS(sflc_volume_default); - static void sflc_volume_kobj_release(struct kobject *kobj) { struct sflc_volume *svol = container_of(kobj, struct sflc_volume, kobj); @@ -172,7 +169,6 @@ static void sflc_volume_kobj_release(struct kobject *kobj) static struct kobj_type sflc_volume_ktype = { .release = sflc_volume_kobj_release, .sysfs_ops = &kobj_sysfs_ops, - .default_groups = sflc_volume_default_groups }; int sflc_sysfs_register_volume(struct sflc_volume *svol) @@ -187,6 +183,7 @@ int sflc_sysfs_register_volume(struct sflc_volume *svol) "%s", svol->name); if (err) goto bad; + /* Emit uevent */ kobject_uevent(&svol->kobj, KOBJ_ADD); diff --git a/shufflecake-userland/.gitignore b/shufflecake-userland-legacy/.gitignore similarity index 100% rename from shufflecake-userland/.gitignore rename to shufflecake-userland-legacy/.gitignore diff --git a/shufflecake-userland/Makefile b/shufflecake-userland-legacy/Makefile similarity index 100% rename from shufflecake-userland/Makefile rename to shufflecake-userland-legacy/Makefile diff --git a/shufflecake-userland/Makefile.sources b/shufflecake-userland-legacy/Makefile.sources similarity index 100% rename from shufflecake-userland/Makefile.sources rename to shufflecake-userland-legacy/Makefile.sources diff --git a/shufflecake-userland/include/actions/device.h b/shufflecake-userland-legacy/include/actions/device.h similarity index 100% rename from shufflecake-userland/include/actions/device.h rename to shufflecake-userland-legacy/include/actions/device.h diff --git a/shufflecake-userland/include/actions/volume.h b/shufflecake-userland-legacy/include/actions/volume.h similarity index 100% rename from shufflecake-userland/include/actions/volume.h rename to shufflecake-userland-legacy/include/actions/volume.h diff --git a/shufflecake-userland/include/cli/cli.h b/shufflecake-userland-legacy/include/cli/cli.h similarity index 100% rename from shufflecake-userland/include/cli/cli.h rename to shufflecake-userland-legacy/include/cli/cli.h diff --git a/shufflecake-userland/include/commands/commands.h b/shufflecake-userland-legacy/include/commands/commands.h similarity index 100% rename from shufflecake-userland/include/commands/commands.h rename to shufflecake-userland-legacy/include/commands/commands.h diff --git a/shufflecake-userland/include/header/device_master_block.h b/shufflecake-userland-legacy/include/header/device_master_block.h similarity index 100% rename from shufflecake-userland/include/header/device_master_block.h rename to shufflecake-userland-legacy/include/header/device_master_block.h diff --git a/shufflecake-userland/include/header/position_map.h b/shufflecake-userland-legacy/include/header/position_map.h similarity index 100% rename from shufflecake-userland/include/header/position_map.h rename to shufflecake-userland-legacy/include/header/position_map.h diff --git a/shufflecake-userland/include/header/volume_master_block.h b/shufflecake-userland-legacy/include/header/volume_master_block.h similarity index 100% rename from shufflecake-userland/include/header/volume_master_block.h rename to shufflecake-userland-legacy/include/header/volume_master_block.h diff --git a/shufflecake-userland/include/sflc_constants.h b/shufflecake-userland-legacy/include/sflc_constants.h similarity index 100% rename from shufflecake-userland/include/sflc_constants.h rename to shufflecake-userland-legacy/include/sflc_constants.h diff --git a/shufflecake-userland/include/utils/crypto.h b/shufflecake-userland-legacy/include/utils/crypto.h similarity index 100% rename from shufflecake-userland/include/utils/crypto.h rename to shufflecake-userland-legacy/include/utils/crypto.h diff --git a/shufflecake-userland/include/utils/disk.h b/shufflecake-userland-legacy/include/utils/disk.h similarity index 100% rename from shufflecake-userland/include/utils/disk.h rename to shufflecake-userland-legacy/include/utils/disk.h diff --git a/shufflecake-userland/include/utils/dm.h b/shufflecake-userland-legacy/include/utils/dm.h similarity index 100% rename from shufflecake-userland/include/utils/dm.h rename to shufflecake-userland-legacy/include/utils/dm.h diff --git a/shufflecake-userland/include/utils/file.h b/shufflecake-userland-legacy/include/utils/file.h similarity index 100% rename from shufflecake-userland/include/utils/file.h rename to shufflecake-userland-legacy/include/utils/file.h diff --git a/shufflecake-userland/include/utils/input.h b/shufflecake-userland-legacy/include/utils/input.h similarity index 100% rename from shufflecake-userland/include/utils/input.h rename to shufflecake-userland-legacy/include/utils/input.h diff --git a/shufflecake-userland/include/utils/log.h b/shufflecake-userland-legacy/include/utils/log.h similarity index 100% rename from shufflecake-userland/include/utils/log.h rename to shufflecake-userland-legacy/include/utils/log.h diff --git a/shufflecake-userland/include/utils/math.h b/shufflecake-userland-legacy/include/utils/math.h similarity index 100% rename from shufflecake-userland/include/utils/math.h rename to shufflecake-userland-legacy/include/utils/math.h diff --git a/shufflecake-userland/include/utils/sflc.h b/shufflecake-userland-legacy/include/utils/sflc.h similarity index 100% rename from shufflecake-userland/include/utils/sflc.h rename to shufflecake-userland-legacy/include/utils/sflc.h diff --git a/shufflecake-userland/include/utils/string.h b/shufflecake-userland-legacy/include/utils/string.h similarity index 100% rename from shufflecake-userland/include/utils/string.h rename to shufflecake-userland-legacy/include/utils/string.h diff --git a/shufflecake-userland/src/actions/close.c b/shufflecake-userland-legacy/src/actions/close.c similarity index 100% rename from shufflecake-userland/src/actions/close.c rename to shufflecake-userland-legacy/src/actions/close.c diff --git a/shufflecake-userland/src/actions/close_vol.c b/shufflecake-userland-legacy/src/actions/close_vol.c similarity index 100% rename from shufflecake-userland/src/actions/close_vol.c rename to shufflecake-userland-legacy/src/actions/close_vol.c diff --git a/shufflecake-userland/src/actions/create.c b/shufflecake-userland-legacy/src/actions/create.c similarity index 100% rename from shufflecake-userland/src/actions/create.c rename to shufflecake-userland-legacy/src/actions/create.c diff --git a/shufflecake-userland/src/actions/create_vol.c b/shufflecake-userland-legacy/src/actions/create_vol.c similarity index 100% rename from shufflecake-userland/src/actions/create_vol.c rename to shufflecake-userland-legacy/src/actions/create_vol.c diff --git a/shufflecake-userland/src/actions/dmb.c b/shufflecake-userland-legacy/src/actions/dmb.c similarity index 100% rename from shufflecake-userland/src/actions/dmb.c rename to shufflecake-userland-legacy/src/actions/dmb.c diff --git a/shufflecake-userland/src/actions/open.c b/shufflecake-userland-legacy/src/actions/open.c similarity index 100% rename from shufflecake-userland/src/actions/open.c rename to shufflecake-userland-legacy/src/actions/open.c diff --git a/shufflecake-userland/src/actions/open_vol.c b/shufflecake-userland-legacy/src/actions/open_vol.c similarity index 100% rename from shufflecake-userland/src/actions/open_vol.c rename to shufflecake-userland-legacy/src/actions/open_vol.c diff --git a/shufflecake-userland/src/cli/close.c b/shufflecake-userland-legacy/src/cli/close.c similarity index 100% rename from shufflecake-userland/src/cli/close.c rename to shufflecake-userland-legacy/src/cli/close.c diff --git a/shufflecake-userland/src/cli/dispatch.c b/shufflecake-userland-legacy/src/cli/dispatch.c similarity index 100% rename from shufflecake-userland/src/cli/dispatch.c rename to shufflecake-userland-legacy/src/cli/dispatch.c diff --git a/shufflecake-userland/src/cli/init.c b/shufflecake-userland-legacy/src/cli/init.c similarity index 100% rename from shufflecake-userland/src/cli/init.c rename to shufflecake-userland-legacy/src/cli/init.c diff --git a/shufflecake-userland/src/cli/open.c b/shufflecake-userland-legacy/src/cli/open.c similarity index 100% rename from shufflecake-userland/src/cli/open.c rename to shufflecake-userland-legacy/src/cli/open.c diff --git a/shufflecake-userland/src/commands/close.c b/shufflecake-userland-legacy/src/commands/close.c similarity index 100% rename from shufflecake-userland/src/commands/close.c rename to shufflecake-userland-legacy/src/commands/close.c diff --git a/shufflecake-userland/src/commands/init.c b/shufflecake-userland-legacy/src/commands/init.c similarity index 100% rename from shufflecake-userland/src/commands/init.c rename to shufflecake-userland-legacy/src/commands/init.c diff --git a/shufflecake-userland/src/commands/open.c b/shufflecake-userland-legacy/src/commands/open.c similarity index 100% rename from shufflecake-userland/src/commands/open.c rename to shufflecake-userland-legacy/src/commands/open.c diff --git a/shufflecake-userland/src/header/device_master_block.c b/shufflecake-userland-legacy/src/header/device_master_block.c similarity index 100% rename from shufflecake-userland/src/header/device_master_block.c rename to shufflecake-userland-legacy/src/header/device_master_block.c diff --git a/shufflecake-userland/src/header/position_map.c b/shufflecake-userland-legacy/src/header/position_map.c similarity index 100% rename from shufflecake-userland/src/header/position_map.c rename to shufflecake-userland-legacy/src/header/position_map.c diff --git a/shufflecake-userland/src/header/volume_master_block.c b/shufflecake-userland-legacy/src/header/volume_master_block.c similarity index 100% rename from shufflecake-userland/src/header/volume_master_block.c rename to shufflecake-userland-legacy/src/header/volume_master_block.c diff --git a/shufflecake-userland/src/main.c b/shufflecake-userland-legacy/src/main.c similarity index 100% rename from shufflecake-userland/src/main.c rename to shufflecake-userland-legacy/src/main.c diff --git a/shufflecake-userland/src/utils/crypto.c b/shufflecake-userland-legacy/src/utils/crypto.c similarity index 100% rename from shufflecake-userland/src/utils/crypto.c rename to shufflecake-userland-legacy/src/utils/crypto.c diff --git a/shufflecake-userland/src/utils/disk.c b/shufflecake-userland-legacy/src/utils/disk.c similarity index 100% rename from shufflecake-userland/src/utils/disk.c rename to shufflecake-userland-legacy/src/utils/disk.c diff --git a/shufflecake-userland/src/utils/dm.c b/shufflecake-userland-legacy/src/utils/dm.c similarity index 100% rename from shufflecake-userland/src/utils/dm.c rename to shufflecake-userland-legacy/src/utils/dm.c diff --git a/shufflecake-userland/src/utils/file.c b/shufflecake-userland-legacy/src/utils/file.c similarity index 100% rename from shufflecake-userland/src/utils/file.c rename to shufflecake-userland-legacy/src/utils/file.c diff --git a/shufflecake-userland/src/utils/input.c b/shufflecake-userland-legacy/src/utils/input.c similarity index 100% rename from shufflecake-userland/src/utils/input.c rename to shufflecake-userland-legacy/src/utils/input.c diff --git a/shufflecake-userland/src/utils/string.c b/shufflecake-userland-legacy/src/utils/string.c similarity index 100% rename from shufflecake-userland/src/utils/string.c rename to shufflecake-userland-legacy/src/utils/string.c diff --git a/shufflecake-userland/test/actions/test_actions.h b/shufflecake-userland-legacy/test/actions/test_actions.h similarity index 100% rename from shufflecake-userland/test/actions/test_actions.h rename to shufflecake-userland-legacy/test/actions/test_actions.h diff --git a/shufflecake-userland/test/actions/test_all_actions.c b/shufflecake-userland-legacy/test/actions/test_all_actions.c similarity index 100% rename from shufflecake-userland/test/actions/test_all_actions.c rename to shufflecake-userland-legacy/test/actions/test_all_actions.c diff --git a/shufflecake-userland/test/actions/test_create.c b/shufflecake-userland-legacy/test/actions/test_create.c similarity index 100% rename from shufflecake-userland/test/actions/test_create.c rename to shufflecake-userland-legacy/test/actions/test_create.c diff --git a/shufflecake-userland/test/commands/test_commands.h b/shufflecake-userland-legacy/test/commands/test_commands.h similarity index 100% rename from shufflecake-userland/test/commands/test_commands.h rename to shufflecake-userland-legacy/test/commands/test_commands.h diff --git a/shufflecake-userland/test/commands/test_init.c b/shufflecake-userland-legacy/test/commands/test_init.c similarity index 100% rename from shufflecake-userland/test/commands/test_init.c rename to shufflecake-userland-legacy/test/commands/test_init.c diff --git a/shufflecake-userland/test/crypto/test_aes256ctr.c b/shufflecake-userland-legacy/test/crypto/test_aes256ctr.c similarity index 100% rename from shufflecake-userland/test/crypto/test_aes256ctr.c rename to shufflecake-userland-legacy/test/crypto/test_aes256ctr.c diff --git a/shufflecake-userland/test/crypto/test_aes256ctr.h b/shufflecake-userland-legacy/test/crypto/test_aes256ctr.h similarity index 100% rename from shufflecake-userland/test/crypto/test_aes256ctr.h rename to shufflecake-userland-legacy/test/crypto/test_aes256ctr.h diff --git a/shufflecake-userland/test/crypto/test_aes256gcm.c b/shufflecake-userland-legacy/test/crypto/test_aes256gcm.c similarity index 100% rename from shufflecake-userland/test/crypto/test_aes256gcm.c rename to shufflecake-userland-legacy/test/crypto/test_aes256gcm.c diff --git a/shufflecake-userland/test/crypto/test_aes256gcm.h b/shufflecake-userland-legacy/test/crypto/test_aes256gcm.h similarity index 100% rename from shufflecake-userland/test/crypto/test_aes256gcm.h rename to shufflecake-userland-legacy/test/crypto/test_aes256gcm.h diff --git a/shufflecake-userland/test/crypto/test_argon2id.c b/shufflecake-userland-legacy/test/crypto/test_argon2id.c similarity index 100% rename from shufflecake-userland/test/crypto/test_argon2id.c rename to shufflecake-userland-legacy/test/crypto/test_argon2id.c diff --git a/shufflecake-userland/test/crypto/test_argon2id.h b/shufflecake-userland-legacy/test/crypto/test_argon2id.h similarity index 100% rename from shufflecake-userland/test/crypto/test_argon2id.h rename to shufflecake-userland-legacy/test/crypto/test_argon2id.h diff --git a/shufflecake-userland/test/main.c b/shufflecake-userland-legacy/test/main.c similarity index 100% rename from shufflecake-userland/test/main.c rename to shufflecake-userland-legacy/test/main.c diff --git a/shufflecake-userland/test/minunit.h b/shufflecake-userland-legacy/test/minunit.h similarity index 100% rename from shufflecake-userland/test/minunit.h rename to shufflecake-userland-legacy/test/minunit.h diff --git a/vuvuzela-userland/.gitignore b/shufflecake-userland-lite/.gitignore similarity index 100% rename from vuvuzela-userland/.gitignore rename to shufflecake-userland-lite/.gitignore diff --git a/vuvuzela-userland/Makefile b/shufflecake-userland-lite/Makefile similarity index 98% rename from vuvuzela-userland/Makefile rename to shufflecake-userland-lite/Makefile index 19abeb7..c0d4151 100644 --- a/vuvuzela-userland/Makefile +++ b/shufflecake-userland-lite/Makefile @@ -61,10 +61,10 @@ DEPS := $(PROJ_DEPS) $(TEST_DEPS) DIRS := $(sort $(dir $(BIN_DIR) $(PROJ_OBJS) $(TEST_OBJS) $(PROJ_DEPS) $(TEST_DEPS))) # The target binaries -MAIN_BIN := $(PROJ_OUT_DIR)/vuvuzela +MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake-lite TEST_BIN := $(TEST_OUT_DIR)/tests # Their symlink -MAIN_LINK := vuvuzela +MAIN_LINK := shufflecake-lite TEST_LINK := tests diff --git a/vuvuzela-userland/Makefile.sources b/shufflecake-userland-lite/Makefile.sources similarity index 100% rename from vuvuzela-userland/Makefile.sources rename to shufflecake-userland-lite/Makefile.sources diff --git a/vuvuzela-userland/include/cli.h b/shufflecake-userland-lite/include/cli.h similarity index 79% rename from vuvuzela-userland/include/cli.h rename to shufflecake-userland-lite/include/cli.h index b58b313..f175931 100644 --- a/vuvuzela-userland/include/cli.h +++ b/shufflecake-userland-lite/include/cli.h @@ -30,15 +30,15 @@ *****************************************************/ /* Action to create volumes */ -#define VVZ_CLI_INITACT "init" +#define SFLITE_CLI_INITACT "init" /* Action to open volumes */ -#define VVZ_CLI_OPENACT "open" +#define SFLITE_CLI_OPENACT "open" /* Action to close volumes */ -#define VVZ_CLI_CLOSEACT "close" +#define SFLITE_CLI_CLOSEACT "close" /* Action to test password */ -#define VVZ_CLI_TESTPWDACT "testpwd" +#define SFLITE_CLI_TESTPWDACT "testpwd" /* Action to change password */ -#define VVZ_CLI_CHANGEPWDACT "changepwd" +#define SFLITE_CLI_CHANGEPWDACT "changepwd" /***************************************************** @@ -46,18 +46,18 @@ *****************************************************/ /* Called by the main to parse the arguments and dispatch to the right command */ -int vvz_cli_dispatch(int argc, char **argv); +int sflite_cli_dispatch(int argc, char **argv); /* Initializes device and create empty volumes */ -int vvz_cli_init(char *block_device, int vvz_mode, int num_volumes, int skip_randfill); +int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill); /* Open volumes */ -int vvz_cli_open(char *block_device, int vvz_mode); +int sflite_cli_open(char *block_device); /* Close volumes */ -int vvz_cli_close(char *block_device); +int sflite_cli_close(char *block_device); /* Test password */ -int vvz_cli_testPwd(char *block_device, int vvz_mode); +int sflite_cli_testPwd(char *block_device); /* Change password */ -int vvz_cli_changePwd(char *block_device, int vvz_mode); +int sflite_cli_changePwd(char *block_device); #endif /* _CLI_H_ */ diff --git a/vuvuzela-userland/include/commands.h b/shufflecake-userland-lite/include/commands.h similarity index 87% rename from vuvuzela-userland/include/commands.h rename to shufflecake-userland-lite/include/commands.h index 1cdab7d..d21c767 100644 --- a/vuvuzela-userland/include/commands.h +++ b/shufflecake-userland-lite/include/commands.h @@ -51,7 +51,7 @@ typedef struct /* Underlying block device */ char *bdev_path; /* Shufflecake mode (legacy,lite,full) */ - int vvz_mode; + int sflite_mode; /* Number of volumes */ size_t nr_vols; /* Volumes' passwords */ @@ -60,7 +60,7 @@ typedef struct /* Option to skip random filling */ bool no_randfill; -} vvz_cmd_InitArgs; +} sflite_cmd_InitArgs; /* Parameters for the open command */ @@ -69,26 +69,26 @@ typedef struct /* Underlying block device */ char *bdev_path; /* Shufflecake mode (legacy,lite,full) */ - int vvz_mode; + int sflite_mode; /* The only password provided */ char *pwd; size_t pwd_len; -} vvz_cmd_OpenArgs; +} sflite_cmd_OpenArgs; typedef struct { /* Underlying block device */ char *bdev_path; /* Shufflecake mode (legacy,lite,full) */ - int vvz_mode; + int sflite_mode; /* Content of the DMB cell */ - vvz_DmbCell *dmb_cell; + sflite_DmbCell *dmb_cell; /* The new password */ char *new_pwd; size_t new_pwd_len; -} vvz_cmd_ChangePwdArgs; +} sflite_cmd_ChangePwdArgs; /***************************************************** @@ -96,19 +96,19 @@ typedef struct *****************************************************/ /* Create N volumes (only formats the device header, does not open the volumes) */ -int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args); +int sflite_cmd_initVolumes(sflite_cmd_InitArgs *args); /* Open M volumes, from the first down to the one whose pwd is provided */ -int vvz_cmd_openVolumes(vvz_cmd_OpenArgs *args); +int sflite_cmd_openVolumes(sflite_cmd_OpenArgs *args); /* Close all volumes on the device (reads the list from sysfs) */ -int vvz_cmd_closeVolumes(char *bdev_path); +int sflite_cmd_closeVolumes(char *bdev_path); /* Tests which volume is unlocked by the given password */ -int vvz_cmd_testPwd(vvz_cmd_OpenArgs *args, vvz_DmbCell *dmb_cell); +int sflite_cmd_testPwd(sflite_cmd_OpenArgs *args, sflite_DmbCell *dmb_cell); /* Changes the specified volume's password */ -int vvz_cmd_changePwd(vvz_cmd_ChangePwdArgs *args); +int sflite_cmd_changePwd(sflite_cmd_ChangePwdArgs *args); #endif /* _COMMANDS_H_ */ diff --git a/vuvuzela-userland/include/header.h b/shufflecake-userland-lite/include/header.h similarity index 75% rename from vuvuzela-userland/include/header.h rename to shufflecake-userland-lite/include/header.h index 2423b40..469fe8b 100644 --- a/vuvuzela-userland/include/header.h +++ b/shufflecake-userland-lite/include/header.h @@ -41,18 +41,18 @@ *****************************************************/ /* The DMB contains one IV + one VMB key + one MAC for each volume */ -#define VVZ_DMB_CELL_SIZE (VVZ_AESGCM_PADDED_IVLEN + VVZ_STANDARD_KEYLEN + VVZ_AESGCM_TAGLEN) +#define SFLITE_DMB_CELL_SIZE (SFLITE_AESGCM_PADDED_IVLEN + SFLITE_STANDARD_KEYLEN + SFLITE_AESGCM_TAGLEN) /* Let us enforce that the one DMB can fit cells for all volumes */ -#if VVZ_ARGON_SALTLEN + (VVZ_DEV_MAX_VOLUMES * VVZ_DMB_CELL_SIZE) > VVZ_BLOCK_SIZE -#error "Invalid combination of parameters: probably VVZ_DEV_MAX_VOLUMES is too big" +#if SFLITE_ARGON_SALTLEN + (SFLITE_DEV_MAX_VOLUMES * SFLITE_DMB_CELL_SIZE) > SFLITE_BLOCK_SIZE +#error "Invalid combination of parameters: probably SFLITE_DEV_MAX_VOLUMES is too big" #endif // The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) -#define VVZ_CLEAR_VMB_LEN (VVZ_BLOCK_SIZE - \ - VVZ_AESGCM_PADDED_IVLEN - \ - VVZ_AESGCM_TAGLEN) +#define SFLITE_CLEAR_VMB_LEN (SFLITE_BLOCK_SIZE - \ + SFLITE_AESGCM_PADDED_IVLEN - \ + SFLITE_AESGCM_TAGLEN) @@ -67,12 +67,12 @@ */ typedef struct { // Each volume's VMB key - char vmb_keys[VVZ_DEV_MAX_VOLUMES][VVZ_STANDARD_KEYLEN]; + char vmb_keys[SFLITE_DEV_MAX_VOLUMES][SFLITE_STANDARD_KEYLEN]; // How many of these need actually be encrypted size_t nr_vols; -} vvz_Dmb; +} sflite_Dmb; /** @@ -81,12 +81,12 @@ typedef struct { */ typedef struct { // The unlocked VMB key - char vmb_key[VVZ_STANDARD_KEYLEN]; + char vmb_key[SFLITE_STANDARD_KEYLEN]; // The index of the volume opened by this VMB key size_t vol_idx; -} vvz_DmbCell; +} sflite_DmbCell; /** @@ -96,15 +96,15 @@ typedef struct { */ typedef struct { // The key that encrypts the volume's data section - char volume_key[VVZ_AESXTS_KEYLEN]; + char volume_key[SFLITE_AESXTS_KEYLEN]; // The key that encrypts the previous volume's master block - char prev_vmb_key[VVZ_STANDARD_KEYLEN]; + char prev_vmb_key[SFLITE_STANDARD_KEYLEN]; // The total number of logical slices virtually available to this volume size_t nr_slices; -} vvz_Vmb; +} sflite_Vmb; /***************************************************** @@ -113,11 +113,11 @@ typedef struct { // Starting block of a volume's position map -static inline uint64_t vvz_pmStartBlock(size_t vol_idx, size_t nr_slices) +static inline uint64_t sflite_pmStartBlock(size_t vol_idx, size_t nr_slices) { return 1 + - VVZ_DEV_MAX_VOLUMES + - vol_idx*ceil(nr_slices, VVZ_SLICE_IDX_PER_BLOCK); + SFLITE_DEV_MAX_VOLUMES + + vol_idx*ceil(nr_slices, SFLITE_SLICE_IDX_PER_BLOCK); } @@ -126,21 +126,21 @@ static inline uint64_t vvz_pmStartBlock(size_t vol_idx, size_t nr_slices) *****************************************************/ /* "Encrypt" each VMB key with its pwd, so the DMB is ready to be written on-disk */ -int vvz_dmb_seal(vvz_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); +int sflite_dmb_seal(sflite_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); /* "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF) */ -int vvz_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, vvz_DmbCell *dmb_cell); +int sflite_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflite_DmbCell *dmb_cell); /* Re-encrypt the content of a single DMB cell */ -int vvz_dmb_setCell(char *disk_block, vvz_DmbCell *dmb_cell, char *pwd, size_t pwd_len); +int sflite_dmb_setCell(char *disk_block, sflite_DmbCell *dmb_cell, char *pwd, size_t pwd_len); /* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ -int vvz_vmb_seal(vvz_Vmb *vmb, char *vmb_key, char *disk_block); +int sflite_vmb_seal(sflite_Vmb *vmb, char *vmb_key, char *disk_block); /* "Decrypt" a VMB coming from the disk, directly using its key */ -int vvz_vmb_unseal(char *disk_block, char *vmb_key, vvz_Vmb *vmb); +int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflite_Vmb *vmb); /* Create an encrypted empty position map for the given number of slices (allocates memory) */ -void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key); +void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key); diff --git a/vuvuzela-userland/include/operations.h b/shufflecake-userland-lite/include/operations.h similarity index 73% rename from vuvuzela-userland/include/operations.h rename to shufflecake-userland-lite/include/operations.h index dbcfd45..25af9fe 100644 --- a/vuvuzela-userland/include/operations.h +++ b/shufflecake-userland-lite/include/operations.h @@ -42,20 +42,20 @@ *****************************************************/ /* Encrypts and writes the DMB to disk */ -int vvz_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, vvz_Dmb *dmb); +int sflite_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflite_Dmb *dmb); /* Reads the DMB from disk and outputs the unlocked VMB key */ -int vvz_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, vvz_DmbCell *dmb_cell); +int sflite_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflite_DmbCell *dmb_cell); /* Reads the DMB from disk, changes the relevant DMB cell, and writes it back */ -int vvz_ops_rewriteDmbCell(char *bdev_path, vvz_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); +int sflite_ops_rewriteDmbCell(char *bdev_path, sflite_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); /* Encrypts and writes a volume header (VMB+PM) on-disk */ -int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size_t vol_idx); +int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflite_Vmb *vmb, size_t vol_idx); /* Reads a VMB from disk and unlocks it */ -int vvz_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, vvz_Vmb *vmb); +int sflite_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflite_Vmb *vmb); -/* Build parameter list for ctor in dm_vvz, and send DM ioctl to create virtual block device */ -int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb *vmb); +/* Build parameter list for ctor in dm_sflite, and send DM ioctl to create virtual block device */ +int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflite_Vmb *vmb); /* Close the volume via the appropriate ioctl to DM */ -int vvz_ops_closeVolume(char *label); +int sflite_ops_closeVolume(char *label); #endif /* _OPERATIONS_H_ */ diff --git a/vuvuzela-userland/include/utils/crypto.h b/shufflecake-userland-lite/include/utils/crypto.h similarity index 72% rename from vuvuzela-userland/include/utils/crypto.h rename to shufflecake-userland-lite/include/utils/crypto.h index c47ca9b..84be972 100644 --- a/vuvuzela-userland/include/utils/crypto.h +++ b/shufflecake-userland-lite/include/utils/crypto.h @@ -33,7 +33,7 @@ #include #include -#include "utils/vvz.h" +#include "utils/sflite.h" /***************************************************** @@ -41,41 +41,41 @@ *****************************************************/ // Key length, for input into AES-CTR and AES-GCM, and for output from Argon -#define VVZ_STANDARD_KEYLEN 32 /* bytes */ +#define SFLITE_STANDARD_KEYLEN 32 /* bytes */ // Key length for AES-XTS -#define VVZ_AESXTS_KEYLEN 64 /* bytes */ +#define SFLITE_AESXTS_KEYLEN 64 /* bytes */ // IV length for AES-CTR -#define VVZ_AESCTR_IVLEN 16 /* bytes */ +#define SFLITE_AESCTR_IVLEN 16 /* bytes */ // IV length for AES-XTS -#define VVZ_AESXTS_IVLEN 16 /* bytes */ +#define SFLITE_AESXTS_IVLEN 16 /* bytes */ // IV length for AES-GCM -#define VVZ_AESGCM_IVLEN 12 /* bytes */ +#define SFLITE_AESGCM_IVLEN 12 /* bytes */ // IVs occupy 16 bytes on-disk, but only the *FIRST* 12 are used for AES-GCM -#define VVZ_AESGCM_PADDED_IVLEN 16 /* bytes */ +#define SFLITE_AESGCM_PADDED_IVLEN 16 /* bytes */ // MAC length for AES-GCM -#define VVZ_AESGCM_TAGLEN 16 /* bytes */ +#define SFLITE_AESGCM_TAGLEN 16 /* bytes */ // Content of output plaintext upon MAC verification failure -#define VVZ_AESGCM_POISON_PT 0xFF +#define SFLITE_AESGCM_POISON_PT 0xFF /* Argon parameters */ // Argon salt length -#define VVZ_ARGON_SALTLEN 16 /* bytes */ +#define SFLITE_ARGON_SALTLEN 16 /* bytes */ // Argon memory parameter // We assume machines with at least 128 MiB available RAM, so 2^17 kiB -#define VVZ_ARGON_M (1 << 17) /* kibibytes */ +#define SFLITE_ARGON_M (1 << 17) /* kibibytes */ // Argon iterations count // We aim for 1-2 seconds on a low-end laptop or mobile (it's a one-time operation) -#define VVZ_ARGON_T 3 +#define SFLITE_ARGON_T 3 // Argon parallelism parameter (recommended to be 2 * CPU cores) // We assume use even on single core devices -#define VVZ_ARGON_P 2 +#define SFLITE_ARGON_P 2 /***************************************************** @@ -83,26 +83,26 @@ *****************************************************/ /* Get slow, strong random bytes (suited for keys) */ -int vvz_rand_getStrongBytes(char *buf, size_t buflen); +int sflite_rand_getStrongBytes(char *buf, size_t buflen); /* Get fast, weak(er) random bytes (suited for IVs and padding) */ -int vvz_rand_getWeakBytes(char *buf, size_t buflen); +int sflite_rand_getWeakBytes(char *buf, size_t buflen); /* AES256-CTR encryption, does not touch the IV. Set ct = NULL for in-place. */ -int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +int sflite_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-CTR decryption, does not touch the IV. Set pt = NULL for in-place. */ -int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); +int sflite_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); /* AES256-XTS encryption. Set ct = NULL for in-place. * The IV is intepreted as a little-endian "sector number" */ -int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +int sflite_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-GCM encryption, does not touch the IV */ -int vvz_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); +int sflite_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); /* AES256-GCM decryption, does not touch the IV (only decrypts if MAC is valid) */ -int vvz_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); +int sflite_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); /* Compute Argon KDF */ -int vvz_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); +int sflite_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); #endif /* _UTILS_CRYPTO_H_ */ diff --git a/vuvuzela-userland/include/utils/disk.h b/shufflecake-userland-lite/include/utils/disk.h similarity index 75% rename from vuvuzela-userland/include/utils/disk.h rename to shufflecake-userland-lite/include/utils/disk.h index a007f39..f2cc8b5 100644 --- a/vuvuzela-userland/include/utils/disk.h +++ b/shufflecake-userland-lite/include/utils/disk.h @@ -36,7 +36,7 @@ #include #include "utils/math.h" -#include "utils/vvz.h" +#include "utils/sflite.h" /***************************************************** @@ -46,25 +46,25 @@ /** * Max slices for given disk size (in 4096-byte blocks). */ -static inline uint32_t vvz_disk_maxSlices(uint64_t size) { +static inline uint32_t sflite_disk_maxSlices(uint64_t size) { uint64_t nr_slices; // Start from upper bound - nr_slices = size / VVZ_SLICE_SCALE; + nr_slices = size / SFLITE_SLICE_SCALE; while(true) { if (nr_slices == 0) break; // Stop when this nr_slices can fit in size, including the header - uint64_t posmap_blocks = ceil(nr_slices, VVZ_SLICE_IDX_PER_BLOCK); - uint64_t header_size = 1 + VVZ_DEV_MAX_VOLUMES * (1 + posmap_blocks); - if (header_size + nr_slices*VVZ_SLICE_SCALE <= size) + uint64_t posmap_blocks = ceil(nr_slices, SFLITE_SLICE_IDX_PER_BLOCK); + uint64_t header_size = 1 + SFLITE_DEV_MAX_VOLUMES * (1 + posmap_blocks); + if (header_size + nr_slices*SFLITE_SLICE_SCALE <= size) break; nr_slices--; } - return nr_slices > VVZ_MAX_SLICES ? VVZ_MAX_SLICES : (uint32_t) nr_slices; + return nr_slices > SFLITE_MAX_SLICES ? SFLITE_MAX_SLICES : (uint32_t) nr_slices; } @@ -73,22 +73,22 @@ static inline uint32_t vvz_disk_maxSlices(uint64_t size) { *****************************************************/ /* Returns a malloc'ed string formatted as : */ -char *vvz_disk_getDeviceName(char *bdev_path); +char *sflite_disk_getDeviceName(char *bdev_path); /* Checks whether the given path points to a block device */ -bool vvz_disk_isBlockDevice(char *path); +bool sflite_disk_isBlockDevice(char *path); /* Returns the size in 4096-byte sectors (or < 0 if error) */ -int64_t vvz_disk_getSize(char *bdev_path); +int64_t sflite_disk_getSize(char *bdev_path); /* Reads a single 4096-byte block from the disk */ -int vvz_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); +int sflite_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); /* Writes many 4096-byte blocks to the disk */ -int vvz_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); +int sflite_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); /* Writes a single 4096-byte block to the disk */ -#define vvz_disk_writeBlock(bdev_path, bnum, buf) vvz_disk_writeManyBlocks(bdev_path, bnum, buf, 1) +#define sflite_disk_writeBlock(bdev_path, bnum, buf) sflite_disk_writeManyBlocks(bdev_path, bnum, buf, 1) #endif /* _UTILS_DISK_H_ */ diff --git a/vuvuzela-userland/include/utils/dm.h b/shufflecake-userland-lite/include/utils/dm.h similarity index 92% rename from vuvuzela-userland/include/utils/dm.h rename to shufflecake-userland-lite/include/utils/dm.h index 1670a73..ba27afb 100644 --- a/vuvuzela-userland/include/utils/dm.h +++ b/shufflecake-userland-lite/include/utils/dm.h @@ -35,7 +35,7 @@ #include -#include "utils/vvz.h" +#include "utils/sflite.h" /***************************************************** @@ -48,9 +48,9 @@ *****************************************************/ /* Create a new Shufflecake virtual device (volume) under /dev/mapper */ -int vvz_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); +int sflite_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); /* Destroy the virtual device under /dev/mapper */ -int vvz_dm_destroy(char * virt_dev_name); +int sflite_dm_destroy(char * virt_dev_name); #endif /* _UTILS_DM_H_ */ diff --git a/vuvuzela-userland/include/utils/file.h b/shufflecake-userland-lite/include/utils/file.h similarity index 97% rename from vuvuzela-userland/include/utils/file.h rename to shufflecake-userland-lite/include/utils/file.h index b4760c3..2346ee6 100644 --- a/vuvuzela-userland/include/utils/file.h +++ b/shufflecake-userland-lite/include/utils/file.h @@ -30,7 +30,7 @@ *****************************************************/ /* Malloc's the buffer for the file contents */ -char *vvz_readFile(char *path); +char *sflite_readFile(char *path); #endif /* _UTILS_FILE_H_ */ diff --git a/vuvuzela-userland/include/utils/input.h b/shufflecake-userland-lite/include/utils/input.h similarity index 92% rename from vuvuzela-userland/include/utils/input.h rename to shufflecake-userland-lite/include/utils/input.h index 068d376..5c54850 100644 --- a/vuvuzela-userland/include/utils/input.h +++ b/shufflecake-userland-lite/include/utils/input.h @@ -30,7 +30,7 @@ *****************************************************/ /* Clear a line from stdin, to use after a failed scanf (it didn't actually read input) */ -#define vvz_ignoreLine() scanf("%*[^\n]") +#define sflite_ignoreLine() scanf("%*[^\n]") /***************************************************** @@ -38,9 +38,9 @@ *****************************************************/ /* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int vvz_safeReadLine(char *buf, size_t bufsize); +int sflite_safeReadLine(char *buf, size_t bufsize); /* Reads a password or passphrase (discarding the newline) from stdin in a secure way (no echo) */ -int vvz_safeReadPassphrase(char *buf, size_t bufsize); +int sflite_safeReadPassphrase(char *buf, size_t bufsize); #endif /* _UTILS_INPUT_H_ */ diff --git a/vuvuzela-userland/include/utils/log.h b/shufflecake-userland-lite/include/utils/log.h similarity index 58% rename from vuvuzela-userland/include/utils/log.h rename to shufflecake-userland-lite/include/utils/log.h index 60a251f..5b15ea5 100644 --- a/vuvuzela-userland/include/utils/log.h +++ b/shufflecake-userland-lite/include/utils/log.h @@ -37,29 +37,29 @@ *****************************************************/ // Printf colours (regular text) -#define VVZ_LOG_BLK "\033[0;30m" -#define VVZ_LOG_RED "\033[0;31m" -#define VVZ_LOG_GRN "\033[0;32m" -#define VVZ_LOG_YEL "\033[0;33m" -#define VVZ_LOG_BLU "\033[0;34m" -#define VVZ_LOG_MAG "\033[0;35m" -#define VVZ_LOG_CYN "\033[0;36m" -#define VVZ_LOG_WHT "\033[0;37m" +#define SFLITE_LOG_BLK "\033[0;30m" +#define SFLITE_LOG_RED "\033[0;31m" +#define SFLITE_LOG_GRN "\033[0;32m" +#define SFLITE_LOG_YEL "\033[0;33m" +#define SFLITE_LOG_BLU "\033[0;34m" +#define SFLITE_LOG_MAG "\033[0;35m" +#define SFLITE_LOG_CYN "\033[0;36m" +#define SFLITE_LOG_WHT "\033[0;37m" // Printf colours (bold text) -#define VVZ_LOG_BBLK "\033[1;30m" -#define VVZ_LOG_BRED "\033[1;31m" -#define VVZ_LOG_BGRN "\033[1;32m" -#define VVZ_LOG_BYEL "\033[1;33m" -#define VVZ_LOG_BBLU "\033[1;34m" -#define VVZ_LOG_BMAG "\033[1;35m" -#define VVZ_LOG_BCYN "\033[1;36m" -#define VVZ_LOG_BWHT "\033[1;37m" +#define SFLITE_LOG_BBLK "\033[1;30m" +#define SFLITE_LOG_BRED "\033[1;31m" +#define SFLITE_LOG_BGRN "\033[1;32m" +#define SFLITE_LOG_BYEL "\033[1;33m" +#define SFLITE_LOG_BBLU "\033[1;34m" +#define SFLITE_LOG_BMAG "\033[1;35m" +#define SFLITE_LOG_BCYN "\033[1;36m" +#define SFLITE_LOG_BWHT "\033[1;37m" // Reset colour -#define VVZ_LOG_RESET "\033[0m" +#define SFLITE_LOG_RESET "\033[0m" // Log level: debug implies detailed logs -#ifdef CONFIG_VVZ_LOG_DEBUG -#define CONFIG_VVZ_LOG_DETAILED +#ifdef CONFIG_SFLITE_LOG_DEBUG +#define CONFIG_SFLITE_LOG_DETAILED #endif @@ -68,42 +68,42 @@ *****************************************************/ // Gives the point in the code where it was called -#define vvz_log_detailed(col, ...) do{ \ - printf(VVZ_LOG_GRN "FUNC " VVZ_LOG_RESET "%s() " \ - VVZ_LOG_GRN "FILE " VVZ_LOG_RESET "%s " \ - VVZ_LOG_GRN "LINE " VVZ_LOG_RESET "%d | ", \ +#define sflite_log_detailed(col, ...) do{ \ + printf(SFLITE_LOG_GRN "FUNC " SFLITE_LOG_RESET "%s() " \ + SFLITE_LOG_GRN "FILE " SFLITE_LOG_RESET "%s " \ + SFLITE_LOG_GRN "LINE " SFLITE_LOG_RESET "%d | ", \ __func__, __FILE__, __LINE__); \ - vvz_log_concise(col, __VA_ARGS__); \ + sflite_log_concise(col, __VA_ARGS__); \ }while(0) // Only writes using the given colour -#define vvz_log_concise(col, ...) do{ \ +#define sflite_log_concise(col, ...) do{ \ printf(col); \ printf(__VA_ARGS__); \ - printf(VVZ_LOG_RESET "\n"); \ + printf(SFLITE_LOG_RESET "\n"); \ }while(0) // Maps to one or the other, based on a Makefile switch -#ifdef CONFIG_VVZ_LOG_DETAILED - #define vvz_log_colour(...) vvz_log_detailed(__VA_ARGS__) +#ifdef CONFIG_SFLITE_LOG_DETAILED + #define sflite_log_colour(...) sflite_log_detailed(__VA_ARGS__) #else - #define vvz_log_colour(...) vvz_log_concise(__VA_ARGS__) + #define sflite_log_colour(...) sflite_log_concise(__VA_ARGS__) #endif // Using specific colours -#define vvz_log_green(...) vvz_log_colour(VVZ_LOG_GRN, __VA_ARGS__) -#define vvz_log_red(...) vvz_log_colour(VVZ_LOG_RED, __VA_ARGS__) -#define vvz_log_yellow(...) vvz_log_colour(VVZ_LOG_YEL, __VA_ARGS__) -#define vvz_log_blue(...) vvz_log_colour(VVZ_LOG_BLU, __VA_ARGS__) -#define vvz_log_normal(...) vvz_log_colour(VVZ_LOG_RESET, __VA_ARGS__) +#define sflite_log_green(...) sflite_log_colour(SFLITE_LOG_GRN, __VA_ARGS__) +#define sflite_log_red(...) sflite_log_colour(SFLITE_LOG_RED, __VA_ARGS__) +#define sflite_log_yellow(...) sflite_log_colour(SFLITE_LOG_YEL, __VA_ARGS__) +#define sflite_log_blue(...) sflite_log_colour(SFLITE_LOG_BLU, __VA_ARGS__) +#define sflite_log_normal(...) sflite_log_colour(SFLITE_LOG_RESET, __VA_ARGS__) // With log levels -#define vvz_log_error(...) vvz_log_colour(VVZ_LOG_RED, "[ERROR] " __VA_ARGS__) -#define vvz_log_warn(...) vvz_log_colour(VVZ_LOG_MAG, "[WARN] " __VA_ARGS__) -#ifdef CONFIG_VVZ_LOG_DEBUG - #define vvz_log_debug(...) vvz_log_colour(VVZ_LOG_CYN, "[DEBUG] " __VA_ARGS__) +#define sflite_log_error(...) sflite_log_colour(SFLITE_LOG_RED, "[ERROR] " __VA_ARGS__) +#define sflite_log_warn(...) sflite_log_colour(SFLITE_LOG_MAG, "[WARN] " __VA_ARGS__) +#ifdef CONFIG_SFLITE_LOG_DEBUG + #define sflite_log_debug(...) sflite_log_colour(SFLITE_LOG_CYN, "[DEBUG] " __VA_ARGS__) #else - #define vvz_log_debug(...) + #define sflite_log_debug(...) #endif @@ -112,7 +112,7 @@ *****************************************************/ // Log a hex string -static inline void vvz_log_hex(char *str, size_t len) +static inline void sflite_log_hex(char *str, size_t len) { int i; unsigned char *s = (unsigned char *) str; diff --git a/vuvuzela-userland/include/utils/math.h b/shufflecake-userland-lite/include/utils/math.h similarity index 100% rename from vuvuzela-userland/include/utils/math.h rename to shufflecake-userland-lite/include/utils/math.h diff --git a/vuvuzela-userland/include/utils/vvz.h b/shufflecake-userland-lite/include/utils/sflite.h similarity index 68% rename from vuvuzela-userland/include/utils/vvz.h rename to shufflecake-userland-lite/include/utils/sflite.h index 71bc399..1dcd963 100644 --- a/vuvuzela-userland/include/utils/vvz.h +++ b/shufflecake-userland-lite/include/utils/sflite.h @@ -22,11 +22,11 @@ */ /* - * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO vvz_constans.h + * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflite_constans.h */ -#ifndef _UTILS_VVZ_H_ -#define _UTILS_VVZ_H_ +#ifndef _UTILS_SFLITE_H_ +#define _UTILS_SFLITE_H_ /***************************************************** @@ -39,46 +39,51 @@ *****************************************************/ /* Name of the DM target in the kernel */ -#define VVZ_DM_TARGET_NAME "vvz" +#define SFLC_DM_TARGET_NAME "shufflecake" + +/* Modes */ +#define SFLC_MODE_LEGACY 0 +#define SFLC_MODE_LITE 1 +#define SFLC_MODE_FULL 2 /* Sizes */ #define KERNEL_SECTOR_SIZE 512 /* bytes */ -#define VVZ_BLOCK_SIZE 4096 /* bytes */ -#define VVZ_BLOCK_SCALE (VVZ_BLOCK_SIZE / KERNEL_SECTOR_SIZE) -#define VVZ_SLICE_SCALE 256 /* blocks in a slice */ -#define VVZ_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ +#define SFLITE_BLOCK_SIZE 4096 /* bytes */ +#define SFLITE_BLOCK_SCALE (SFLITE_BLOCK_SIZE / KERNEL_SECTOR_SIZE) +#define SFLITE_SLICE_SCALE 256 /* blocks in a slice */ +#define SFLITE_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ /* Max number of volumes in a device */ -#define VVZ_DEV_MAX_VOLUMES 15 +#define SFLITE_DEV_MAX_VOLUMES 15 /* Max total number of open devices at any given time */ -#define VVZ_TOT_MAX_DEVICES 1024 -/* A volume name is vvz__ */ -#define VVZ_MAX_VOL_NAME_LEN 15 +#define SFLITE_TOT_MAX_DEVICES 1024 +/* A volume name is sflite__ */ +#define SFLITE_MAX_VOL_NAME_LEN 15 /* A slice index is represented over 32 bits */ -#define VVZ_SLICE_IDX_WIDTH 4 /* bytes */ +#define SFLITE_SLICE_IDX_WIDTH 4 /* bytes */ /* A position map block contains 1024 slice indices */ -#define VVZ_SLICE_IDX_PER_BLOCK (VVZ_BLOCK_SIZE / VVZ_SLICE_IDX_WIDTH) +#define SFLITE_SLICE_IDX_PER_BLOCK (SFLITE_BLOCK_SIZE / SFLITE_SLICE_IDX_WIDTH) /* A PSI of 0xFFFFFFFF indicates an unassigned LSI */ -#define VVZ_EPM_FILLER 0xFF +#define SFLITE_EPM_FILLER 0xFF /* The sysfs file containing the next available device ID */ -#define VVZ_SYSFS_NEXTDEVID "/sys/module/dm_vvz/next_dev_id" +#define SFLITE_SYSFS_NEXTDEVID "/sys/module/dm_sflc/next_dev_id" /* The sysfs directory containing a subdir for each (underlying) block device */ -#define VVZ_SYSFS_BDEVS_DIR "/sys/module/dm_vvz/bdevs" +#define SFLITE_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" /* Within each bdev's subdir, this file shows its number of open volumes */ -#define VVZ_SYSFS_OPENVOLUMES_FILENAME "volumes" +#define SFLITE_SYSFS_OPENVOLUMES_FILENAME "volumes" /* Within each bdev's subdir, this file shows its Shufflecake device ID */ -#define VVZ_SYSFS_DEVID_FILENAME "dev_id" +#define SFLITE_SYSFS_DEVID_FILENAME "dev_id" /* TODO: reasonable? */ -#define VVZ_BDEV_PATH_MAX_LEN 1024 +#define SFLITE_BDEV_PATH_MAX_LEN 1024 /* For when you can't be bothered to upper-bound a buffer size */ -#define VVZ_BIGBUFSIZE 4096 +#define SFLITE_BIGBUFSIZE 4096 -#endif /* _UTILS_VVZ_H_ */ +#endif /* _UTILS_SFLITE_H_ */ diff --git a/vuvuzela-userland/include/utils/string.h b/shufflecake-userland-lite/include/utils/string.h similarity index 93% rename from vuvuzela-userland/include/utils/string.h rename to shufflecake-userland-lite/include/utils/string.h index 99f057b..552ed82 100644 --- a/vuvuzela-userland/include/utils/string.h +++ b/shufflecake-userland-lite/include/utils/string.h @@ -30,10 +30,10 @@ *****************************************************/ /* Malloc's the buffer for the hex string */ -char *vvz_toHex(char *buf, size_t len); +char *sflite_toHex(char *buf, size_t len); /* Replaces all occurrences of character in-place */ -void vvz_str_replaceAll(char *str, char old, char new); +void sflite_str_replaceAll(char *str, char old, char new); #endif /* _UTILS_STRING_H_ */ diff --git a/vuvuzela-userland/src/cli/changepwd.c b/shufflecake-userland-lite/src/cli/changepwd.c similarity index 79% rename from vuvuzela-userland/src/cli/changepwd.c rename to shufflecake-userland-lite/src/cli/changepwd.c index e0f691f..a4f85e7 100644 --- a/vuvuzela-userland/src/cli/changepwd.c +++ b/shufflecake-userland-lite/src/cli/changepwd.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/input.h" #include "utils/log.h" @@ -45,14 +45,14 @@ * * @return Error code, 0 on success */ -int vvz_cli_changePwd(char *block_device) +int sflite_cli_changePwd(char *block_device) { // Requires: block_device is a correct block device path - vvz_cmd_OpenArgs open_args; - vvz_cmd_ChangePwdArgs change_pwd_args; - vvz_DmbCell dmb_cell; - char old_pwd[VVZ_BIGBUFSIZE]; + sflite_cmd_OpenArgs open_args; + sflite_cmd_ChangePwdArgs change_pwd_args; + sflite_DmbCell dmb_cell; + char old_pwd[SFLITE_BIGBUFSIZE]; size_t old_pwd_len; - char new_pwd[VVZ_BIGBUFSIZE]; + char new_pwd[SFLITE_BIGBUFSIZE]; size_t new_pwd_len; int err; @@ -60,9 +60,9 @@ int vvz_cli_changePwd(char *block_device) /* Gather password */ printf("Enter the password you want to change: "); - err = vvz_safeReadPassphrase(old_pwd, VVZ_BIGBUFSIZE); + err = sflite_safeReadPassphrase(old_pwd, SFLITE_BIGBUFSIZE); if (err) { - vvz_log_error("Could not read password; error %d", err); + sflite_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -72,14 +72,14 @@ int vvz_cli_changePwd(char *block_device) open_args.pwd_len = old_pwd_len; /* Test the password */ - err = vvz_cmd_testPwd(&open_args, &dmb_cell); + err = sflite_cmd_testPwd(&open_args, &dmb_cell); if (err) { - vvz_log_error("Could not test password; error %d", err); + sflite_log_error("Could not test password; error %d", err); return err; } /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= VVZ_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= SFLITE_DEV_MAX_VOLUMES) { printf("This password does not unlock any volume.\n"); return 0; } @@ -87,9 +87,9 @@ int vvz_cli_changePwd(char *block_device) /* Gather new password (no secure shell) */ printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); printf("Choose new password for volume %lu: ", dmb_cell.vol_idx); - err = vvz_safeReadLine(new_pwd, VVZ_BIGBUFSIZE); + err = sflite_safeReadLine(new_pwd, SFLITE_BIGBUFSIZE); if (err) { - vvz_log_error("Could not read new password; error %d", err); + sflite_log_error("Could not read new password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -102,9 +102,9 @@ int vvz_cli_changePwd(char *block_device) change_pwd_args.new_pwd_len = new_pwd_len; /* Change password */ - err = vvz_cmd_changePwd(&change_pwd_args); + err = sflite_cmd_changePwd(&change_pwd_args); if (err) { - vvz_log_error("Could not change password; error %d", err); + sflite_log_error("Could not change password; error %d", err); return err; } printf("Password changed successfully.\n"); diff --git a/vuvuzela-userland/src/cli/close.c b/shufflecake-userland-lite/src/cli/close.c similarity index 85% rename from vuvuzela-userland/src/cli/close.c rename to shufflecake-userland-lite/src/cli/close.c index a4c8bbd..ecedda2 100644 --- a/vuvuzela-userland/src/cli/close.c +++ b/shufflecake-userland-lite/src/cli/close.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/input.h" #include "utils/log.h" @@ -45,16 +45,16 @@ * * @return Error code, 0 on success */ -int vvz_cli_close(char *block_device) +int sflite_cli_close(char *block_device) { // Requires: block_device is a correct block device path -// char bdev_path[VVZ_BDEV_PATH_MAX_LEN + 2]; +// char bdev_path[SFLITE_BDEV_PATH_MAX_LEN + 2]; // int err; // /* Gather (absolute) path to underlying block device */ // printf("Enter the absolute path to the underlying block device containing the Shufflecake volumes to close: "); -// err = vvz_safeReadLine(bdev_path, VVZ_BDEV_PATH_MAX_LEN + 2); +// err = sflite_safeReadLine(bdev_path, SFLITE_BDEV_PATH_MAX_LEN + 2); // if (err) { -// vvz_log_error("Could not read path to underlying block device; error %d", err); +// sflite_log_error("Could not read path to underlying block device; error %d", err); // return err; // } // /* Check that it is absolute */ @@ -66,9 +66,9 @@ int vvz_cli_close(char *block_device) /* Actually perform the command */ -// return vvz_cmd_closeVolumes(bdev_path); +// return sflite_cmd_closeVolumes(bdev_path); - return vvz_cmd_closeVolumes(block_device); + return sflite_cmd_closeVolumes(block_device); } diff --git a/vuvuzela-userland/src/cli/dispatch.c b/shufflecake-userland-lite/src/cli/dispatch.c similarity index 70% rename from vuvuzela-userland/src/cli/dispatch.c rename to shufflecake-userland-lite/src/cli/dispatch.c index 3debf68..871b751 100644 --- a/vuvuzela-userland/src/cli/dispatch.c +++ b/shufflecake-userland-lite/src/cli/dispatch.c @@ -32,10 +32,9 @@ #include #include "cli.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/disk.h" #include "utils/log.h" -#include "vvz_constants.h" /***************************************************** @@ -43,29 +42,29 @@ *****************************************************/ /* Used by argp to provide the automatic "-V" option */ -const char *argp_program_version = VVZ_VERSION; +const char *argp_program_version = "0.5.0"; // Temporary hack /* Used by argp to provide the automatic "--help" option */ const char *argp_program_bug_address = ""; /* Signed integer values representing a handle for each option */ -#define VVZ_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option -#define VVZ_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this +#define SFLITE_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option +#define SFLITE_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this /***************************************************** * TYPES * *****************************************************/ -enum vvz_cli_action { - VVZ_ACT_INIT, - VVZ_ACT_OPEN, - VVZ_ACT_CLOSE, - VVZ_ACT_TESTPWD, - VVZ_ACT_CHANGEPWD +enum sflite_cli_action { + SFLITE_ACT_INIT, + SFLITE_ACT_OPEN, + SFLITE_ACT_CLOSE, + SFLITE_ACT_TESTPWD, + SFLITE_ACT_CHANGEPWD }; -struct vvz_cli_arguments { - enum vvz_cli_action act; +struct sflite_cli_arguments { + enum sflite_cli_action act; char *block_device; int sflc_mode; int num_volumes; @@ -112,12 +111,10 @@ static char doc[] = /* Description of each option */ static struct argp_option options[] = { - {"num-volumes", VVZ_OPT_NUMVOLS_KEY, "num", 0, + {"num-volumes", SFLITE_OPT_NUMVOLS_KEY, "num", 0, "Specify number of volumes to be created with `init'. Must be an integer between 1 and 15.", 0 }, // TODO: define MAX_VOLS instead of hardcoding 15 - {"skip-randfill", VVZ_OPT_SKIPRAND_KEY, 0, 0, + {"skip-randfill", SFLITE_OPT_SKIPRAND_KEY, 0, 0, "Skip pre-overwriting block device with random data, only valid with `init'. Faster but less secure. Use only for debugging or testing."}, - {"legacy", VVZ_OPT_LEGACY, 0, 0, - "Use the old (pre-v0.5.0) Shufflecake format. Only valid with `init`, `open', `testpwd', `changepwd'. Use of this option is not recommended. This mode is going to be deprecated in future versions."}, {0} }; @@ -139,12 +136,11 @@ static struct argp argp = {options, _parseArgpKey, args_doc, doc}; * @return Error code, 0 on success */ -int vvz_cli_dispatch(int argc, char **argv) { - struct vvz_cli_arguments arguments; +int sflite_cli_dispatch(int argc, char **argv) { + struct sflite_cli_arguments arguments; arguments.act = -1; arguments.block_device = NULL; - arguments.vvz_mode = VVZ_MODE_LITE; arguments.num_volumes = 0; arguments.skip_randfill = false; @@ -152,41 +148,36 @@ int vvz_cli_dispatch(int argc, char **argv) { argp_parse(&argp, argc, argv, 0, 0, &arguments); /* Check options consistency */ - if (arguments.num_volumes && arguments.act != VVZ_ACT_INIT) { + if (arguments.num_volumes && arguments.act != SFLITE_ACT_INIT) { printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); return EINVAL; } - /* Legacy mode should not be specified with `close' action */ - if (arguments.vvz_mode && arguments.act == VVZ_ACT_CLOSE) { - printf("Error: --legacy should not be used with `close'.\n"); - return EINVAL; - } /* Check options consistency */ - if (arguments.skip_randfill && arguments.act != VVZ_ACT_INIT) { + if (arguments.skip_randfill && arguments.act != SFLITE_ACT_INIT) { printf("Error: --skip-randfill can only be combined with `init'.\n"); return EINVAL; } /* Check that input is actually a block device */ - if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !vvz_disk_isBlockDevice(arguments.block_device)) { + if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !sflite_disk_isBlockDevice(arguments.block_device)) { printf("Error: '%s' is not a valid block device.\n", arguments.block_device); return EINVAL; } /* Dispatch to specific command */ - if (arguments.act == VVZ_ACT_INIT) { - return vvz_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); + if (arguments.act == SFLITE_ACT_INIT) { + return sflite_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); } - if (arguments.act == VVZ_ACT_OPEN) { - return vvz_cli_open(arguments.block_device arguments.vvz_mode,); + if (arguments.act == SFLITE_ACT_OPEN) { + return sflite_cli_open(arguments.block_device); } - if (arguments.act == VVZ_ACT_CLOSE) { - return vvz_cli_close(arguments.block_device); + if (arguments.act == SFLITE_ACT_CLOSE) { + return sflite_cli_close(arguments.block_device); } - if (arguments.act == VVZ_ACT_TESTPWD) { - return vvz_cli_testPwd(arguments.block_device arguments.vvz_mode,); + if (arguments.act == SFLITE_ACT_TESTPWD) { + return sflite_cli_testPwd(arguments.block_device); } - if (arguments.act == VVZ_ACT_CHANGEPWD) { - return vvz_cli_changePwd(arguments.block_device arguments.vvz_mode,); + if (arguments.act == SFLITE_ACT_CHANGEPWD) { + return sflite_cli_changePwd(arguments.block_device); } printf("\n"); @@ -200,26 +191,26 @@ int vvz_cli_dispatch(int argc, char **argv) { *****************************************************/ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { - struct vvz_cli_arguments *arguments = state->input; + struct sflite_cli_arguments *arguments = state->input; switch (key) { /* We are parsing an argument (not an option) */ case ARGP_KEY_ARG: /* We are parsing the command */ if (state->arg_num == 0) { - if (strcmp(arg, VVZ_CLI_INITACT) == 0) { - arguments->act = VVZ_ACT_INIT; - } else if (strcmp(arg, VVZ_CLI_OPENACT) == 0) { - arguments->act = VVZ_ACT_OPEN; - } else if (strcmp(arg, VVZ_CLI_CLOSEACT) == 0) { - arguments->act = VVZ_ACT_CLOSE; - } else if (strcmp(arg, VVZ_CLI_TESTPWDACT) == 0) { - arguments->act = VVZ_ACT_TESTPWD; - } else if (strcmp(arg, VVZ_CLI_CHANGEPWDACT) == 0) { - arguments->act = VVZ_ACT_CHANGEPWD; + if (strcmp(arg, SFLITE_CLI_INITACT) == 0) { + arguments->act = SFLITE_ACT_INIT; + } else if (strcmp(arg, SFLITE_CLI_OPENACT) == 0) { + arguments->act = SFLITE_ACT_OPEN; + } else if (strcmp(arg, SFLITE_CLI_CLOSEACT) == 0) { + arguments->act = SFLITE_ACT_CLOSE; + } else if (strcmp(arg, SFLITE_CLI_TESTPWDACT) == 0) { + arguments->act = SFLITE_ACT_TESTPWD; + } else if (strcmp(arg, SFLITE_CLI_CHANGEPWDACT) == 0) { + arguments->act = SFLITE_ACT_CHANGEPWD; } else { argp_error(state, "Invalid action. Please enter one and only one of: `%s', `%s', `%s', '%s', or '%s'.", - VVZ_CLI_INITACT, VVZ_CLI_OPENACT, VVZ_CLI_CLOSEACT, VVZ_CLI_TESTPWDACT, VVZ_CLI_CHANGEPWDACT); + SFLITE_CLI_INITACT, SFLITE_CLI_OPENACT, SFLITE_CLI_CLOSEACT, SFLITE_CLI_TESTPWDACT, SFLITE_CLI_CHANGEPWDACT); } /* We are parsing the block device */ } else if (state->arg_num == 1) { @@ -231,13 +222,10 @@ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { break; /* We are parsing an option */ - case VVZ_OPT_NUMVOLS_KEY: + case SFLITE_OPT_NUMVOLS_KEY: arguments->num_volumes = atoi(arg); break; - case VVZ_OPT_LEGACY: - arguments->vvz_mode = VVZ_MODE_LEGACY; - break; - case VVZ_OPT_SKIPRAND_KEY: + case SFLITE_OPT_SKIPRAND_KEY: arguments->skip_randfill = true; break; diff --git a/vuvuzela-userland/src/cli/init.c b/shufflecake-userland-lite/src/cli/init.c similarity index 78% rename from vuvuzela-userland/src/cli/init.c rename to shufflecake-userland-lite/src/cli/init.c index fc065d9..0639bb3 100644 --- a/vuvuzela-userland/src/cli/init.c +++ b/shufflecake-userland-lite/src/cli/init.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/input.h" #include "utils/log.h" @@ -45,12 +45,12 @@ * * @return Error code, 0 on success */ -int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) +int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill) { // Requires: block_device is a correct block device path - vvz_cmd_InitArgs args; - char str_nrvols[VVZ_BIGBUFSIZE]; - char *pwds[VVZ_DEV_MAX_VOLUMES]; - size_t pwd_lens[VVZ_DEV_MAX_VOLUMES]; + sflite_cmd_InitArgs args; + char str_nrvols[SFLITE_BIGBUFSIZE]; + char *pwds[SFLITE_DEV_MAX_VOLUMES]; + size_t pwd_lens[SFLITE_DEV_MAX_VOLUMES]; int err; args.bdev_path = block_device; @@ -60,15 +60,15 @@ int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) args.nr_vols = num_volumes; } else { // If not, ask user for number of volumes - printf("\nHow many volumes do you want to create (maximum is %d)? ", VVZ_DEV_MAX_VOLUMES); - err = vvz_safeReadLine(str_nrvols, VVZ_BIGBUFSIZE); + printf("\nHow many volumes do you want to create (maximum is %d)? ", SFLITE_DEV_MAX_VOLUMES); + err = sflite_safeReadLine(str_nrvols, SFLITE_BIGBUFSIZE); if (err) { - vvz_log_error("Error: could not read number of volumes; error %d", err); + sflite_log_error("Error: could not read number of volumes; error %d", err); return err; } /* Parse string */ if (sscanf(str_nrvols, "%lu\n", &args.nr_vols) != 1) { - vvz_log_error("Error: could not parse number of volumes"); + sflite_log_error("Error: could not parse number of volumes"); return EINVAL; } } @@ -78,8 +78,8 @@ int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) printf("Error: number of volumes must be a positive integer"); return EINVAL; } - if (args.nr_vols > VVZ_DEV_MAX_VOLUMES) { - printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", VVZ_DEV_MAX_VOLUMES); + if (args.nr_vols > SFLITE_DEV_MAX_VOLUMES) { + printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", SFLITE_DEV_MAX_VOLUMES); return EINVAL; } @@ -89,13 +89,13 @@ int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) size_t i; for (i = 0; i < args.nr_vols; i++) { // Allocate pwd - pwds[i] = malloc(VVZ_BIGBUFSIZE); + pwds[i] = malloc(SFLITE_BIGBUFSIZE); /* Read it */ printf("Choose password for volume %lu (must not be empty): ", i); - err = vvz_safeReadLine(pwds[i], VVZ_BIGBUFSIZE); + err = sflite_safeReadLine(pwds[i], SFLITE_BIGBUFSIZE); if (err) { - vvz_log_error("Could not read password for volume %lu; error %d", i, err); + sflite_log_error("Could not read password for volume %lu; error %d", i, err); return err; } @@ -103,7 +103,7 @@ int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) pwd_lens[i] = strlen(pwds[i]); /* Check non-empty */ if (pwd_lens[i] == 0) { - vvz_log_error("Password cannot be empty!"); + sflite_log_error("Password cannot be empty!"); return EINVAL; } } @@ -114,5 +114,5 @@ int vvz_cli_init(char *block_device, int num_volumes, int skip_randfill) args.no_randfill = skip_randfill; /* Actually perform the command */ - return vvz_cmd_initVolumes(&args); + return sflite_cmd_initVolumes(&args); } diff --git a/vuvuzela-userland/src/cli/open.c b/shufflecake-userland-lite/src/cli/open.c similarity index 87% rename from vuvuzela-userland/src/cli/open.c rename to shufflecake-userland-lite/src/cli/open.c index 3cfe4dd..bc6d70b 100644 --- a/vuvuzela-userland/src/cli/open.c +++ b/shufflecake-userland-lite/src/cli/open.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/input.h" #include "utils/log.h" @@ -45,10 +45,10 @@ * * @return Error code, 0 on success */ -int vvz_cli_open(char *block_device) +int sflite_cli_open(char *block_device) { // Requires: block_device is a correct block device path - vvz_cmd_OpenArgs args; - char pwd[VVZ_BIGBUFSIZE]; + sflite_cmd_OpenArgs args; + char pwd[SFLITE_BIGBUFSIZE]; size_t pwd_len; int err; @@ -56,16 +56,16 @@ int vvz_cli_open(char *block_device) /* Gather password */ printf("Enter the password for the most secret volume you want to open: "); - err = vvz_safeReadPassphrase(pwd, VVZ_BIGBUFSIZE); + err = sflite_safeReadPassphrase(pwd, SFLITE_BIGBUFSIZE); if (err) { - vvz_log_error("Could not read password; error %d", err); + sflite_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ pwd_len = strlen(pwd); /* Check non-empty */ if (pwd_len == 0) { - vvz_log_error("Password cannot be empty!"); + sflite_log_error("Password cannot be empty!"); return EINVAL; } /* Assign them */ @@ -73,5 +73,5 @@ int vvz_cli_open(char *block_device) args.pwd_len = pwd_len; /* Actually perform the command */ - return vvz_cmd_openVolumes(&args); + return sflite_cmd_openVolumes(&args); } diff --git a/vuvuzela-userland/src/cli/testpwd.c b/shufflecake-userland-lite/src/cli/testpwd.c similarity index 83% rename from vuvuzela-userland/src/cli/testpwd.c rename to shufflecake-userland-lite/src/cli/testpwd.c index 48cf710..4bc5695 100644 --- a/vuvuzela-userland/src/cli/testpwd.c +++ b/shufflecake-userland-lite/src/cli/testpwd.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/input.h" #include "utils/log.h" @@ -45,12 +45,12 @@ * * @return Error code, 0 on success */ -int vvz_cli_testPwd(char *block_device) +int sflite_cli_testPwd(char *block_device) { // Requires: block_device is a correct block device path - vvz_cmd_OpenArgs args; - vvz_DmbCell dmb_cell; -// char bdev_path[VVZ_BDEV_PATH_MAX_LEN + 2]; - char pwd[VVZ_BIGBUFSIZE]; + sflite_cmd_OpenArgs args; + sflite_DmbCell dmb_cell; +// char bdev_path[SFLITE_BDEV_PATH_MAX_LEN + 2]; + char pwd[SFLITE_BIGBUFSIZE]; size_t pwd_len; int err; @@ -58,9 +58,9 @@ int vvz_cli_testPwd(char *block_device) /* Gather password */ printf("Enter the password you want to test: "); - err = vvz_safeReadPassphrase(pwd, VVZ_BIGBUFSIZE); + err = sflite_safeReadPassphrase(pwd, SFLITE_BIGBUFSIZE); if (err) { - vvz_log_error("Could not read password; error %d", err); + sflite_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -70,14 +70,14 @@ int vvz_cli_testPwd(char *block_device) args.pwd_len = pwd_len; /* Actually perform the command */ - err = vvz_cmd_testPwd(&args, &dmb_cell); + err = sflite_cmd_testPwd(&args, &dmb_cell); if (err) { - vvz_log_error("Could not test password; error %d", err); + sflite_log_error("Could not test password; error %d", err); return err; } /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= VVZ_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= SFLITE_DEV_MAX_VOLUMES) { printf("This password does not unlock any volume.\n"); } else { printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); diff --git a/vuvuzela-userland/src/commands/change_pwd.c b/shufflecake-userland-lite/src/commands/change_pwd.c similarity index 91% rename from vuvuzela-userland/src/commands/change_pwd.c rename to shufflecake-userland-lite/src/commands/change_pwd.c index a56b3dc..dcac991 100644 --- a/vuvuzela-userland/src/commands/change_pwd.c +++ b/shufflecake-userland-lite/src/commands/change_pwd.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/log.h" @@ -51,8 +51,8 @@ * * @return Error code, 0 on success */ -int vvz_cmd_changePwd(vvz_cmd_ChangePwdArgs *args) +int sflite_cmd_changePwd(sflite_cmd_ChangePwdArgs *args) { /* Delegate entirely to the function reading the DMB */ - return vvz_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); + return sflite_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); } diff --git a/vuvuzela-userland/src/commands/close.c b/shufflecake-userland-lite/src/commands/close.c similarity index 72% rename from vuvuzela-userland/src/commands/close.c rename to shufflecake-userland-lite/src/commands/close.c index e14ee21..eff361d 100644 --- a/vuvuzela-userland/src/commands/close.c +++ b/shufflecake-userland-lite/src/commands/close.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/crypto.h" #include "utils/string.h" #include "utils/file.h" @@ -61,18 +61,18 @@ static int _closeVolumes(char **labels, size_t nr_vols); * * @return Error code, 0 on success */ -int vvz_cmd_closeVolumes(char *bdev_path) +int sflite_cmd_closeVolumes(char *bdev_path) { - char *labels[VVZ_DEV_MAX_VOLUMES]; + char *labels[SFLITE_DEV_MAX_VOLUMES]; size_t nr_vols; int err; /* Allocate labels */ size_t i; - for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) { - labels[i] = malloc(VVZ_MAX_VOL_NAME_LEN + 1); + for (i = 0; i < SFLITE_DEV_MAX_VOLUMES; i++) { + labels[i] = malloc(SFLITE_MAX_VOL_NAME_LEN + 1); if (!labels[1]) { - vvz_log_error("Could not allocate volume label %lu", i); + sflite_log_error("Could not allocate volume label %lu", i); return ENOMEM; // Do not free the ones already allocated } } @@ -80,14 +80,14 @@ int vvz_cmd_closeVolumes(char *bdev_path) /* Read them */ err = _buildVolumesList(bdev_path, labels, &nr_vols); if (err) { - vvz_log_error("Could not read volume list from sysfs; error %d", err); + sflite_log_error("Could not read volume list from sysfs; error %d", err); goto out; } /* Close the volumes (in reverse order of opening) */ err = _closeVolumes(labels, nr_vols); if (err) { - vvz_log_error("Could not close volumes; error %d", err); + sflite_log_error("Could not close volumes; error %d", err); goto out; } @@ -96,7 +96,7 @@ int vvz_cmd_closeVolumes(char *bdev_path) out: - for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) { + for (i = 0; i < SFLITE_DEV_MAX_VOLUMES; i++) { free(labels[i]); } return err; @@ -111,57 +111,57 @@ out: static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols) { char *bdev_name; - char devid_path[VVZ_BIGBUFSIZE]; + char devid_path[SFLITE_BIGBUFSIZE]; char *str_devid; size_t dev_id; - char nrvolumes_path[VVZ_BIGBUFSIZE]; + char nrvolumes_path[SFLITE_BIGBUFSIZE]; char *str_nrvolumes; /* Get device name as : */ - bdev_name = vvz_disk_getDeviceName(bdev_path); + bdev_name = sflite_disk_getDeviceName(bdev_path); if(!bdev_name) { - vvz_log_error("Could not allocate device name"); + sflite_log_error("Could not allocate device name"); return ENOMEM; } /* Build path to sysfs file containing device ID */ - sprintf(devid_path, "%s/%s/%s", VVZ_SYSFS_BDEVS_DIR, bdev_name, VVZ_SYSFS_DEVID_FILENAME); + sprintf(devid_path, "%s/%s/%s", SFLITE_SYSFS_BDEVS_DIR, bdev_name, SFLITE_SYSFS_DEVID_FILENAME); /* Build path to sysfs file containing number of open volumes */ - sprintf(nrvolumes_path, "%s/%s/%s", VVZ_SYSFS_BDEVS_DIR, bdev_name, VVZ_SYSFS_OPENVOLUMES_FILENAME); + sprintf(nrvolumes_path, "%s/%s/%s", SFLITE_SYSFS_BDEVS_DIR, bdev_name, SFLITE_SYSFS_OPENVOLUMES_FILENAME); /* Read the device ID */ - str_devid = vvz_readFile(devid_path); + str_devid = sflite_readFile(devid_path); if (!str_devid) { - vvz_log_error("Could not read file %s", devid_path); + sflite_log_error("Could not read file %s", devid_path); return EBADF; } /* Parse the device ID */ if (sscanf(str_devid, "%lu", &dev_id) != 1) { - vvz_log_error("Could not parse device ID:\n%s", str_devid); + sflite_log_error("Could not parse device ID:\n%s", str_devid); return EBADF; } /* Read the number of volumes */ - str_nrvolumes = vvz_readFile(nrvolumes_path); + str_nrvolumes = sflite_readFile(nrvolumes_path); if (!str_nrvolumes) { - vvz_log_error("Could not read file %s", nrvolumes_path); + sflite_log_error("Could not read file %s", nrvolumes_path); return EBADF; } /* Parse the number of volumes */ if (sscanf(str_nrvolumes, "%lu", nr_vols) != 1) { - vvz_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); + sflite_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); return EBADF; } /* Just to be sure */ - if (*nr_vols > VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); + if (*nr_vols > SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); return EBADF; } /* Build labels */ size_t i; for (i = 0; i < *nr_vols; i++) { - sprintf(labels[i], "vvz_%lu_%lu", dev_id, i); + sprintf(labels[i], "sflc_%lu_%lu", dev_id, i); } return 0; @@ -176,12 +176,12 @@ static int _closeVolumes(char **labels, size_t nr_vols) /* Eazy peazy */ int i; for (i = nr_vols-1; i >= 0; i--) { - err = vvz_ops_closeVolume(labels[i]); + err = sflite_ops_closeVolume(labels[i]); if (err) { - vvz_log_error("Could not close volume %s; error %d", labels[i], err); + sflite_log_error("Could not close volume %s; error %d", labels[i], err); return err; } - vvz_log_debug("Closed volume %s", labels[i]); + sflite_log_debug("Closed volume %s", labels[i]); printf("Closed volume /dev/mapper/%s\n", labels[i]); } diff --git a/vuvuzela-userland/src/commands/init.c b/shufflecake-userland-lite/src/commands/init.c similarity index 69% rename from vuvuzela-userland/src/commands/init.c rename to shufflecake-userland-lite/src/commands/init.c index 592eb3c..41a6de8 100644 --- a/vuvuzela-userland/src/commands/init.c +++ b/shufflecake-userland-lite/src/commands/init.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -42,9 +42,9 @@ *****************************************************/ /* The device is randomised in chunks of 1024 blocks (arbitrary number) */ -#define VVZ_BLOCKS_IN_RAND_CHUNK 1024 +#define SFLITE_BLOCKS_IN_RAND_CHUNK 1024 /* That's 4 MiB */ -#define VVZ_RAND_CHUNK_SIZE (VVZ_BLOCKS_IN_RAND_CHUNK * VVZ_BLOCK_SIZE) +#define SFLITE_RAND_CHUNK_SIZE (SFLITE_BLOCKS_IN_RAND_CHUNK * SFLITE_BLOCK_SIZE) /***************************************************** @@ -72,36 +72,36 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); * * @return Error code, 0 on success */ -int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args) +int sflite_cmd_initVolumes(sflite_cmd_InitArgs *args) { - vvz_Dmb dmb; - vvz_Vmb vmb; + sflite_Dmb dmb; + sflite_Vmb vmb; int64_t dev_size; size_t nr_slices; int err; /* Sanity check */ - if (args->nr_vols > VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("Cannot create %lu volumes on a single device", args->nr_vols); + if (args->nr_vols > SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("Cannot create %lu volumes on a single device", args->nr_vols); return EINVAL; } /* Get device size */ - dev_size = vvz_disk_getSize(args->bdev_path); + dev_size = sflite_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; - vvz_log_error("Could not get device size for %s; error %d", args->bdev_path, err); + sflite_log_error("Could not get device size for %s; error %d", args->bdev_path, err); return err; } /* Convert to number of slices */ - nr_slices = vvz_disk_maxSlices(dev_size); - vvz_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); + nr_slices = sflite_disk_maxSlices(dev_size); + sflite_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); /* Fill disk with random bytes, if requested */ if (!args->no_randfill) { err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); if (err) { - vvz_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); + sflite_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); return err; } } @@ -111,16 +111,16 @@ int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args) /* Sample the VMB keys */ size_t i; for (i = 0; i < dmb.nr_vols; i++) { - err = vvz_rand_getStrongBytes(dmb.vmb_keys[i], VVZ_STANDARD_KEYLEN); + err = sflite_rand_getStrongBytes(dmb.vmb_keys[i], SFLITE_STANDARD_KEYLEN); if (err) { - vvz_log_error("Could not sample VMB key number %lu; error %d", i , err); + sflite_log_error("Could not sample VMB key number %lu; error %d", i , err); return err; } } /* And write (encrypted) to disk */ - err = vvz_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); + err = sflite_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); if (err) { - vvz_log_error("Could not create DMB and write it to disk; error %d", err); + sflite_log_error("Could not create DMB and write it to disk; error %d", err); return err; } @@ -129,15 +129,15 @@ int vvz_cmd_initVolumes(vvz_cmd_InitArgs *args) for (i = 0; i < args->nr_vols; i++) { /* This volume's prev_vmb_key */ if (i > 0) { - memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], VVZ_STANDARD_KEYLEN); + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLITE_STANDARD_KEYLEN); } /* Sample this volume's VEK */ - vvz_rand_getStrongBytes(vmb.volume_key, VVZ_AESXTS_KEYLEN); + sflite_rand_getStrongBytes(vmb.volume_key, SFLITE_AESXTS_KEYLEN); /* Write complete volume header (VMB + PM) */ - err = vvz_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); + err = sflite_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); if (err) { - vvz_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); + sflite_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); return err; } } @@ -158,9 +158,9 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) int err; /* Allocate chunk */ - rand_chunk = malloc(VVZ_RAND_CHUNK_SIZE); + rand_chunk = malloc(SFLITE_RAND_CHUNK_SIZE); if (!rand_chunk) { - vvz_log_error("Could not allocate %d bytes for chunk of random data", VVZ_RAND_CHUNK_SIZE); + sflite_log_error("Could not allocate %d bytes for chunk of random data", SFLITE_RAND_CHUNK_SIZE); return ENOMEM; } @@ -169,20 +169,20 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) uint64_t sector = 0; while (blocks_remaining > 0) { uint64_t blocks_to_write = - (blocks_remaining > VVZ_BLOCKS_IN_RAND_CHUNK) ? VVZ_BLOCKS_IN_RAND_CHUNK : blocks_remaining; - uint64_t bytes_to_write = blocks_to_write * VVZ_BLOCK_SIZE; + (blocks_remaining > SFLITE_BLOCKS_IN_RAND_CHUNK) ? SFLITE_BLOCKS_IN_RAND_CHUNK : blocks_remaining; + uint64_t bytes_to_write = blocks_to_write * SFLITE_BLOCK_SIZE; /* Sample random bytes */ - err = vvz_rand_getWeakBytes(rand_chunk, bytes_to_write); + err = sflite_rand_getWeakBytes(rand_chunk, bytes_to_write); if (err) { - vvz_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); + sflite_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); goto out; } /* Write on disk */ - err = vvz_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); + err = sflite_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); if (err) { - vvz_log_error("Could not write random bytes on disk; error %d", err); + sflite_log_error("Could not write random bytes on disk; error %d", err); goto out; } diff --git a/vuvuzela-userland/src/commands/open.c b/shufflecake-userland-lite/src/commands/open.c similarity index 74% rename from vuvuzela-userland/src/commands/open.c rename to shufflecake-userland-lite/src/commands/open.c index 6b789bd..11ecddd 100644 --- a/vuvuzela-userland/src/commands/open.c +++ b/shufflecake-userland-lite/src/commands/open.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/crypto.h" #include "utils/disk.h" #include "utils/file.h" @@ -63,33 +63,33 @@ static int _getNextDevId(size_t *next_dev_id); * * @return Error code (also if no volume could be opened), 0 on success */ -int vvz_cmd_openVolumes(vvz_cmd_OpenArgs *args) +int sflite_cmd_openVolumes(sflite_cmd_OpenArgs *args) { int64_t dev_size; size_t nr_slices; - vvz_DmbCell dmb_cell; - vvz_Vmb vmbs[VVZ_DEV_MAX_VOLUMES]; + sflite_DmbCell dmb_cell; + sflite_Vmb vmbs[SFLITE_DEV_MAX_VOLUMES]; size_t dev_id; int err; /* Get number of slices */ - dev_size = vvz_disk_getSize(args->bdev_path); + dev_size = sflite_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; - vvz_log_error("Could not read device size for %s; error %d", args->bdev_path, err); + sflite_log_error("Could not read device size for %s; error %d", args->bdev_path, err); return err; } - nr_slices = vvz_disk_maxSlices(dev_size); + nr_slices = sflite_disk_maxSlices(dev_size); /* Find volume opened by the pwd */ - err = vvz_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); + err = sflite_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); if (err) { - vvz_log_error("Could not read DMB; error %d", err); + sflite_log_error("Could not read DMB; error %d", err); return err; } /* Was there one? */ - if (dmb_cell.vol_idx >= VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("The provided password opens no volume on the device"); + if (dmb_cell.vol_idx >= SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("The provided password opens no volume on the device"); return EINVAL; } printf("Password is correct! Opening volumes...\n"); @@ -108,9 +108,9 @@ int vvz_cmd_openVolumes(vvz_cmd_OpenArgs *args) } /* Read and unlock VMB */ - err = vvz_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); + err = sflite_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); if (err) { - vvz_log_error("Could not read VMB %d on device %s; error %d", + sflite_log_error("Could not read VMB %d on device %s; error %d", i, args->bdev_path, err); return err; } @@ -119,23 +119,23 @@ int vvz_cmd_openVolumes(vvz_cmd_OpenArgs *args) /* Get the ID that will be assigned to the block device */ err = _getNextDevId(&dev_id); if (err) { - vvz_log_error("Could not get next device ID; error %d", err); + sflite_log_error("Could not get next device ID; error %d", err); return err; } - vvz_log_debug("Next device ID is %lu", dev_id); + sflite_log_debug("Next device ID is %lu", dev_id); /* Open volumes "in order" */ for (i = 0; i <= dmb_cell.vol_idx; i++) { - err = vvz_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); + err = sflite_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); if (err) { - vvz_log_error("Could not open volume %d; error %d. " + sflite_log_error("Could not open volume %d; error %d. " "Previous volumes on the device might have already " "been opened, it's recommended you close them", i, err); return err; } - vvz_log_debug("Successfully opened volume %d with VMB key", i); - printf("Opened volume /dev/mapper/vvz_%lu_%d\n", dev_id, i); + sflite_log_debug("Successfully opened volume %d with VMB key", i); + printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); } return 0; @@ -153,21 +153,21 @@ static int _getNextDevId(size_t *next_dev_id) int err; /* Read sysfs entry */ - str_nextdevid = vvz_readFile(VVZ_SYSFS_NEXTDEVID); + str_nextdevid = sflite_readFile(SFLITE_SYSFS_NEXTDEVID); if (!str_nextdevid) { - vvz_log_error("Could not read sysfs entry %s", VVZ_SYSFS_NEXTDEVID); + sflite_log_error("Could not read sysfs entry %s", SFLITE_SYSFS_NEXTDEVID); return EINVAL; } /* Parse integer */ if (sscanf(str_nextdevid, "%lu", next_dev_id) != 1) { - vvz_log_error("Error parsing content of file %s", VVZ_SYSFS_NEXTDEVID); + sflite_log_error("Error parsing content of file %s", SFLITE_SYSFS_NEXTDEVID); err = EINVAL; goto err_devid; } /* Sanity check */ - if (*next_dev_id >= VVZ_TOT_MAX_DEVICES) { - vvz_log_error("There are already %d open devices, this is the maximum allowed", VVZ_TOT_MAX_DEVICES); + if (*next_dev_id >= SFLITE_TOT_MAX_DEVICES) { + sflite_log_error("There are already %d open devices, this is the maximum allowed", SFLITE_TOT_MAX_DEVICES); err = E2BIG; goto err_devid; } diff --git a/vuvuzela-userland/src/commands/test_pwd.c b/shufflecake-userland-lite/src/commands/test_pwd.c similarity index 91% rename from vuvuzela-userland/src/commands/test_pwd.c rename to shufflecake-userland-lite/src/commands/test_pwd.c index 1d011c7..09cd5d3 100644 --- a/vuvuzela-userland/src/commands/test_pwd.c +++ b/shufflecake-userland-lite/src/commands/test_pwd.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/log.h" @@ -52,8 +52,8 @@ * * @return Error code, 0 on success */ -int vvz_cmd_testPwd(vvz_cmd_OpenArgs *args, vvz_DmbCell *dmb_cell) +int sflite_cmd_testPwd(sflite_cmd_OpenArgs *args, sflite_DmbCell *dmb_cell) { /* Delegate entirely to the function reading the DMB */ - return vvz_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); + return sflite_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); } diff --git a/vuvuzela-userland/src/header/device_master_block.c b/shufflecake-userland-lite/src/header/device_master_block.c similarity index 64% rename from vuvuzela-userland/src/header/device_master_block.c rename to shufflecake-userland-lite/src/header/device_master_block.c index a6522d6..0e6ce22 100644 --- a/vuvuzela-userland/src/header/device_master_block.c +++ b/shufflecake-userland-lite/src/header/device_master_block.c @@ -60,21 +60,21 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool * * @return The error code, 0 on success */ -int vvz_dmb_seal(vvz_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) +int sflite_dmb_seal(sflite_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) { char *salt; int err; /* Sanity check */ - if (dmb->nr_vols > VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); + if (dmb->nr_vols > SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); return EINVAL; } /* Randomise whole block */ - err = vvz_rand_getWeakBytes(disk_block, VVZ_BLOCK_SIZE); + err = sflite_rand_getWeakBytes(disk_block, SFLITE_BLOCK_SIZE); if (err) { - vvz_log_error("Could not randomise DMB; error %d", err); + sflite_log_error("Could not randomise DMB; error %d", err); return err; } @@ -84,12 +84,12 @@ int vvz_dmb_seal(vvz_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) /* Loop over all VMB keys to encrypt them */ size_t i; for (i = 0; i < dmb->nr_vols; i++) { - char *dmb_cell = (salt + VVZ_ARGON_SALTLEN) + (i * VVZ_DMB_CELL_SIZE); + char *dmb_cell = (salt + SFLITE_ARGON_SALTLEN) + (i * SFLITE_DMB_CELL_SIZE); /* Encrypt it */ err = _encryptVmbKeyWithPwd(salt, pwds[i], pwd_lens[i], dmb->vmb_keys[i], dmb_cell); if (err) { - vvz_log_error("Could not encrypt VMB key number %lu; error %d", i, err); + sflite_log_error("Could not encrypt VMB key number %lu; error %d", i, err); return err; } } @@ -106,50 +106,50 @@ int vvz_dmb_seal(vvz_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) * @param pwd_len Its length * * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= VVZ_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vol_idx Its index (>= SFLITE_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int vvz_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, vvz_DmbCell *dmb_cell) +int sflite_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflite_DmbCell *dmb_cell) { // KDF salt char *salt; // The KDF-derived key - char kek[VVZ_STANDARD_KEYLEN]; + char kek[SFLITE_STANDARD_KEYLEN]; // The unlocked VMB key - char vmb_key[VVZ_STANDARD_KEYLEN]; + char vmb_key[SFLITE_STANDARD_KEYLEN]; // Error code int err; /* Derive KEK once and for all */ salt = disk_block; - err = vvz_argon2id_derive(pwd, pwd_len, salt, kek); + err = sflite_argon2id_derive(pwd, pwd_len, salt, kek); if (err) { - vvz_log_error("Could not perform KDF: error %d", err); + sflite_log_error("Could not perform KDF: error %d", err); goto bad_kdf; } - vvz_log_debug("Successfully derived key-encryption-key with KDF"); + sflite_log_debug("Successfully derived key-encryption-key with KDF"); /* Init dmb->vol_idx to invalid */ - dmb_cell->vol_idx = VVZ_DEV_MAX_VOLUMES; + dmb_cell->vol_idx = SFLITE_DEV_MAX_VOLUMES; /* Try all DMB cells */ size_t i; - for (i = 0; i < VVZ_DEV_MAX_VOLUMES; i++) { - char *enc_dmb_cell = (salt + VVZ_ARGON_SALTLEN) + (i * VVZ_DMB_CELL_SIZE); + for (i = 0; i < SFLITE_DEV_MAX_VOLUMES; i++) { + char *enc_dmb_cell = (salt + SFLITE_ARGON_SALTLEN) + (i * SFLITE_DMB_CELL_SIZE); bool match; /* Try to decrypt this one */ err = _decryptVmbKeyWithPwd(enc_dmb_cell, kek, vmb_key, &match); if (err) { - vvz_log_error("Error decrypting DMB cell number %lu; error %d", i, err); + sflite_log_error("Error decrypting DMB cell number %lu; error %d", i, err); goto bad_decrypt; } /* If MAC matched, mark it, but don't break from the loop (timing attacks) */ if (match) { - vvz_log_debug("The provided password unlocks volume %lu", i); + sflite_log_debug("The provided password unlocks volume %lu", i); dmb_cell->vol_idx = i; - memcpy(dmb_cell->vmb_key, vmb_key, VVZ_STANDARD_KEYLEN); + memcpy(dmb_cell->vmb_key, vmb_key, SFLITE_STANDARD_KEYLEN); } } @@ -160,7 +160,7 @@ int vvz_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, vvz_DmbCell *dmb bad_decrypt: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, VVZ_STANDARD_KEYLEN); + memset(kek, 0, SFLITE_STANDARD_KEYLEN); return err; } @@ -174,28 +174,28 @@ bad_kdf: * * @return Error code, 0 on success */ -int vvz_dmb_setCell(char *disk_block, vvz_DmbCell *dmb_cell, char *pwd, size_t pwd_len) +int sflite_dmb_setCell(char *disk_block, sflite_DmbCell *dmb_cell, char *pwd, size_t pwd_len) { char *salt; char *enc_dmb_cell; int err; /* Sanity check */ - if (dmb_cell->vol_idx >= VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + if (dmb_cell->vol_idx >= SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); return EINVAL; } /* Pointers inside DMB */ salt = disk_block; - enc_dmb_cell = (salt + VVZ_ARGON_SALTLEN) + (dmb_cell->vol_idx * VVZ_DMB_CELL_SIZE); + enc_dmb_cell = (salt + SFLITE_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLITE_DMB_CELL_SIZE); /* Encrypt with KDF-derived key */ err = _encryptVmbKeyWithPwd(salt, pwd, pwd_len, dmb_cell->vmb_key, enc_dmb_cell); if (err) { - vvz_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); + sflite_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); return err; } - vvz_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); + sflite_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); return 0; } @@ -210,36 +210,36 @@ static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vm { // Pointers inside the block char *iv = dmb_cell; - char *enc_vmb_key = iv + VVZ_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + VVZ_STANDARD_KEYLEN; + char *enc_vmb_key = iv + SFLITE_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + SFLITE_STANDARD_KEYLEN; // Key-encryption-key derived from KDF - char kek[VVZ_STANDARD_KEYLEN]; + char kek[SFLITE_STANDARD_KEYLEN]; // Error code int err; /* Derive KEK */ - err = vvz_argon2id_derive(pwd, pwd_len, salt, kek); + err = sflite_argon2id_derive(pwd, pwd_len, salt, kek); if (err) { - vvz_log_error("Could not perform KDF: error %d", err); + sflite_log_error("Could not perform KDF: error %d", err); goto bad_kdf; } - vvz_log_debug("Successfully derived key-encryption-key with KDF"); + sflite_log_debug("Successfully derived key-encryption-key with KDF"); /* Sample VMB_IV */ - err = vvz_rand_getWeakBytes(iv, VVZ_AESGCM_PADDED_IVLEN); + err = sflite_rand_getWeakBytes(iv, SFLITE_AESGCM_PADDED_IVLEN); if (err) { - vvz_log_error("Could not sample prologue IV: error %d", err); + sflite_log_error("Could not sample prologue IV: error %d", err); goto bad_sample_iv; } - vvz_log_debug("Successfully sampled prologue IV"); + sflite_log_debug("Successfully sampled prologue IV"); /* Encrypt the VMB key */ - err = vvz_aes256gcm_encrypt(kek, vmb_key, VVZ_STANDARD_KEYLEN, iv, enc_vmb_key, mac); + err = sflite_aes256gcm_encrypt(kek, vmb_key, SFLITE_STANDARD_KEYLEN, iv, enc_vmb_key, mac); if (err) { - vvz_log_error("Could not encrypt the VMB key: error %d", err); + sflite_log_error("Could not encrypt the VMB key: error %d", err); goto bad_encrypt; } - vvz_log_debug("Successfully encrypted VMB key with key-encryption-key"); + sflite_log_debug("Successfully encrypted VMB key with key-encryption-key"); // No prob err = 0; @@ -249,7 +249,7 @@ bad_encrypt: bad_sample_iv: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, VVZ_STANDARD_KEYLEN); + memset(kek, 0, SFLITE_STANDARD_KEYLEN); return err; } @@ -258,18 +258,18 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool { // Pointers inside the block char *iv = dmb_cell; - char *enc_vmb_key = iv + VVZ_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + VVZ_STANDARD_KEYLEN; + char *enc_vmb_key = iv + SFLITE_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + SFLITE_STANDARD_KEYLEN; // Error code int err; /* Decrypt the VMB key */ - err = vvz_aes256gcm_decrypt(kek, enc_vmb_key, VVZ_STANDARD_KEYLEN, mac, iv, vmb_key, match); + err = sflite_aes256gcm_decrypt(kek, enc_vmb_key, SFLITE_STANDARD_KEYLEN, mac, iv, vmb_key, match); if (err) { - vvz_log_error("Error while decrypting VMB key: error %d", err); + sflite_log_error("Error while decrypting VMB key: error %d", err); return err; } - vvz_log_debug("Decrypted VMB key: MAC match = %d", *match); + sflite_log_debug("Decrypted VMB key: MAC match = %d", *match); return 0; } diff --git a/vuvuzela-userland/src/header/position_map.c b/shufflecake-userland-lite/src/header/position_map.c similarity index 80% rename from vuvuzela-userland/src/header/position_map.c rename to shufflecake-userland-lite/src/header/position_map.c index 4abdab3..1059378 100644 --- a/vuvuzela-userland/src/header/position_map.c +++ b/shufflecake-userland-lite/src/header/position_map.c @@ -31,7 +31,7 @@ #include #include "header.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/crypto.h" #include "utils/math.h" #include "utils/log.h" @@ -49,42 +49,42 @@ * position map as well. * * @return The memory buffer containing the position map */ -void *vvz_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) +void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) { - char pmb[VVZ_BLOCK_SIZE]; - char iv[VVZ_AESXTS_IVLEN]; + char pmb[SFLITE_BLOCK_SIZE]; + char iv[SFLITE_AESXTS_IVLEN]; void *epm; size_t nr_pmbs; uint64_t pblk_num; int err; // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) - nr_pmbs = ceil(nr_slices, VVZ_SLICE_IDX_PER_BLOCK); + nr_pmbs = ceil(nr_slices, SFLITE_SLICE_IDX_PER_BLOCK); // Allocate EPM - epm = malloc(nr_pmbs * VVZ_BLOCK_SIZE); + epm = malloc(nr_pmbs * SFLITE_BLOCK_SIZE); if (!epm) { - vvz_log_error("Could not malloc EPM"); + sflite_log_error("Could not malloc EPM"); return NULL; } // Fill cleartext PMB with 0xFF - memset(pmb, VVZ_EPM_FILLER, VVZ_BLOCK_SIZE); + memset(pmb, SFLITE_EPM_FILLER, SFLITE_BLOCK_SIZE); // First physical block number - pblk_num = vvz_pmStartBlock(vol_idx, nr_slices); + pblk_num = sflite_pmStartBlock(vol_idx, nr_slices); // Loop to encrypt each PMB int i; for (i = 0; i < nr_pmbs; i++) { // Set IV - memset(iv, 0, VVZ_AESXTS_IVLEN); + memset(iv, 0, SFLITE_AESXTS_IVLEN); *((uint64_t*)iv) = htole64(pblk_num); // Encrypt - err = vvz_aes256xts_encrypt(volume_key, pmb, VVZ_BLOCK_SIZE, iv, - epm + i*VVZ_BLOCK_SIZE); + err = sflite_aes256xts_encrypt(volume_key, pmb, SFLITE_BLOCK_SIZE, iv, + epm + i*SFLITE_BLOCK_SIZE); if (err) { - vvz_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); + sflite_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); free(epm); return NULL; } diff --git a/vuvuzela-userland/src/header/volume_master_block.c b/shufflecake-userland-lite/src/header/volume_master_block.c similarity index 67% rename from vuvuzela-userland/src/header/volume_master_block.c rename to shufflecake-userland-lite/src/header/volume_master_block.c index 72c36b5..e44963b 100644 --- a/vuvuzela-userland/src/header/volume_master_block.c +++ b/shufflecake-userland-lite/src/header/volume_master_block.c @@ -41,10 +41,10 @@ *****************************************************/ /* Serialise the VMB before encrypting it */ -static void _serialiseVmb(vvz_Vmb *vmb, char *clear_vmb); +static void _serialiseVmb(sflite_Vmb *vmb, char *clear_vmb); /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, vvz_Vmb *vmb); +static int _deserialiseVmb(char *clear_vmb, sflite_Vmb *vmb); /***************************************************** @@ -61,44 +61,44 @@ static int _deserialiseVmb(char *clear_vmb, vvz_Vmb *vmb); * * @return The error code, 0 on success */ -int vvz_vmb_seal(vvz_Vmb *vmb, char *vmb_key, char *disk_block) +int sflite_vmb_seal(sflite_Vmb *vmb, char *vmb_key, char *disk_block) { // Pointers inside the block char *iv = disk_block; - char *enc_vmb = iv + VVZ_AESCTR_IVLEN; + char *enc_vmb = iv + SFLITE_AESCTR_IVLEN; // Serialised VMB (dynamically allocated), to be encrypted char *clear_vmb; // Error code int err; /* Allocate large buffer on the heap */ - clear_vmb = malloc(VVZ_CLEAR_VMB_LEN); + clear_vmb = malloc(SFLITE_CLEAR_VMB_LEN); if (!clear_vmb) { - vvz_log_error("Could not allocate %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); + sflite_log_error("Could not allocate %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); err = ENOMEM; goto bad_clear_alloc; } - vvz_log_debug("Successfully allocated %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); + sflite_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); /* Serialise the struct */ _serialiseVmb(vmb, clear_vmb); - vvz_log_debug("Serialised VMB struct"); + sflite_log_debug("Serialised VMB struct"); /* Sample VMB IV */ - err = vvz_rand_getWeakBytes(iv, VVZ_AESGCM_PADDED_IVLEN); + err = sflite_rand_getWeakBytes(iv, SFLITE_AESGCM_PADDED_IVLEN); if (err) { - vvz_log_error("Could not sample VMB IV: error %d", err); + sflite_log_error("Could not sample VMB IV: error %d", err); goto bad_sample_iv; } - vvz_log_debug("Successfully sampled VMB IV"); + sflite_log_debug("Successfully sampled VMB IV"); /* Encrypt the VMB */ - err = vvz_aes256ctr_encrypt(vmb_key, clear_vmb, VVZ_CLEAR_VMB_LEN, iv, enc_vmb); + err = sflite_aes256ctr_encrypt(vmb_key, clear_vmb, SFLITE_CLEAR_VMB_LEN, iv, enc_vmb); if (err) { - vvz_log_error("Could not encrypt VMB: error %d", err); + sflite_log_error("Could not encrypt VMB: error %d", err); goto bad_encrypt; } - vvz_log_debug("Successfully encrypted VMB"); + sflite_log_debug("Successfully encrypted VMB"); // No prob err = 0; @@ -107,7 +107,7 @@ int vvz_vmb_seal(vvz_Vmb *vmb, char *vmb_key, char *disk_block) bad_encrypt: bad_sample_iv: /* Always wipe and free the cleartext VMB, even on success */ - memset(clear_vmb, 0, VVZ_CLEAR_VMB_LEN); + memset(clear_vmb, 0, SFLITE_CLEAR_VMB_LEN); free(clear_vmb); bad_clear_alloc: return err; @@ -123,40 +123,40 @@ bad_clear_alloc: * * @return An error code, 0 on success */ -int vvz_vmb_unseal(char *disk_block, char *vmb_key, vvz_Vmb *vmb) +int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflite_Vmb *vmb) { // Pointers inside the block char *iv = disk_block; - char *enc_vmb = iv + VVZ_AESCTR_IVLEN; + char *enc_vmb = iv + SFLITE_AESCTR_IVLEN; // Decrypted VMB (dynamically allocated), to be deserialised char *clear_vmb; // Error code int err; /* Allocate large buffer on the heap */ - clear_vmb = malloc(VVZ_CLEAR_VMB_LEN); + clear_vmb = malloc(SFLITE_CLEAR_VMB_LEN); if (!clear_vmb) { - vvz_log_error("Could not allocate %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); + sflite_log_error("Could not allocate %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); err = ENOMEM; goto bad_clear_alloc; } - vvz_log_debug("Successfully allocated %d bytes for VMB cleartext", VVZ_CLEAR_VMB_LEN); + sflite_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); /* Decrypt the VMB */ - err = vvz_aes256ctr_decrypt(vmb_key, enc_vmb, VVZ_CLEAR_VMB_LEN, iv, clear_vmb); + err = sflite_aes256ctr_decrypt(vmb_key, enc_vmb, SFLITE_CLEAR_VMB_LEN, iv, clear_vmb); if (err) { - vvz_log_error("Error while decrypting VMB: error %d", err); + sflite_log_error("Error while decrypting VMB: error %d", err); goto bad_decrypt; } - vvz_log_debug("Successfully decrypted VMB"); + sflite_log_debug("Successfully decrypted VMB"); /* Deserialise the struct */ err = _deserialiseVmb(clear_vmb, vmb); if (err) { - vvz_log_error("Error while deserialising VMB: error %d", err); + sflite_log_error("Error while deserialising VMB: error %d", err); goto bad_deserialise; } - vvz_log_debug("Deserialised VMB struct"); + sflite_log_debug("Deserialised VMB struct"); // No prob err = 0; @@ -165,7 +165,7 @@ int vvz_vmb_unseal(char *disk_block, char *vmb_key, vvz_Vmb *vmb) bad_deserialise: bad_decrypt: /* Always wipe and free the VMB cleartext, even on success */ - memset(clear_vmb, 0, VVZ_CLEAR_VMB_LEN); + memset(clear_vmb, 0, SFLITE_CLEAR_VMB_LEN); free(clear_vmb); bad_clear_alloc: return err; @@ -177,18 +177,18 @@ bad_clear_alloc: *****************************************************/ /* Serialise the payload before encrypting it */ -static void _serialiseVmb(vvz_Vmb *vmb, char *clear_vmb) +static void _serialiseVmb(sflite_Vmb *vmb, char *clear_vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + VVZ_AESXTS_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + VVZ_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + SFLITE_AESXTS_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLITE_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(p_vol_key, vmb->volume_key, VVZ_AESXTS_KEYLEN); + memcpy(p_vol_key, vmb->volume_key, SFLITE_AESXTS_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(p_prev_vmb_key, vmb->prev_vmb_key, VVZ_STANDARD_KEYLEN); + memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLITE_STANDARD_KEYLEN); /* Write the number of slices (network byte order) */ *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); @@ -200,18 +200,18 @@ static void _serialiseVmb(vvz_Vmb *vmb, char *clear_vmb) /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, vvz_Vmb *vmb) +static int _deserialiseVmb(char *clear_vmb, sflite_Vmb *vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + VVZ_AESXTS_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + VVZ_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + SFLITE_AESXTS_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLITE_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(vmb->volume_key, p_vol_key, VVZ_AESXTS_KEYLEN); + memcpy(vmb->volume_key, p_vol_key, SFLITE_AESXTS_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(vmb->prev_vmb_key, p_prev_vmb_key, VVZ_STANDARD_KEYLEN); + memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLITE_STANDARD_KEYLEN); /* Read number of slices (network byte order) */ vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); diff --git a/vuvuzela-userland/src/main.c b/shufflecake-userland-lite/src/main.c similarity index 97% rename from vuvuzela-userland/src/main.c rename to shufflecake-userland-lite/src/main.c index 08a4b12..50d86e7 100644 --- a/vuvuzela-userland/src/main.c +++ b/shufflecake-userland-lite/src/main.c @@ -39,6 +39,6 @@ int main(int argc, char **argv) { - return vvz_cli_dispatch(argc, argv); + return sflite_cli_dispatch(argc, argv); } diff --git a/vuvuzela-userland/src/operations/devmapper.c b/shufflecake-userland-lite/src/operations/devmapper.c similarity index 76% rename from vuvuzela-userland/src/operations/devmapper.c rename to shufflecake-userland-lite/src/operations/devmapper.c index 4e54af2..1d0ebae 100644 --- a/vuvuzela-userland/src/operations/devmapper.c +++ b/shufflecake-userland-lite/src/operations/devmapper.c @@ -33,7 +33,7 @@ #include "header.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/string.h" @@ -46,7 +46,7 @@ *****************************************************/ /** - * Build parameter list for ctor in dm_vvz, and send DM ioctl to create + * Build parameter list for ctor in dm_sflite, and send DM ioctl to create * virtual block device. * * @param bdev_path The path to the underlying device @@ -56,35 +56,35 @@ * * @return Error code, 0 on success */ -int vvz_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, vvz_Vmb *vmb) +int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflite_Vmb *vmb) { - char label[VVZ_BIGBUFSIZE]; + char label[SFLITE_BIGBUFSIZE]; char *hex_key; - char params[VVZ_BIGBUFSIZE]; + char params[SFLITE_BIGBUFSIZE]; uint64_t num_sectors; int err; /* Build volume label */ - sprintf(label, "vvz_%lu_%lu", dev_id, vol_idx); + sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); /* Get the hex version of the volume's data section key */ - hex_key = vvz_toHex(vmb->volume_key, VVZ_AESXTS_KEYLEN); + hex_key = sflite_toHex(vmb->volume_key, SFLITE_AESXTS_KEYLEN); if (!hex_key) { - vvz_log_error("Could not encode volume key to hexadecimal"); + sflite_log_error("Could not encode volume key to hexadecimal"); err = ENOMEM; goto err_hexkey; } /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vmb->nr_slices) * VVZ_SLICE_SCALE * VVZ_BLOCK_SCALE; + num_sectors = ((uint64_t) vmb->nr_slices) * SFLITE_SLICE_SCALE * SFLITE_BLOCK_SCALE; /* Build param list */ - sprintf(params, "%lu %s %lu %lu %s", dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); + sprintf(params, "%d %lu %s %lu %lu %s", SFLC_MODE_LITE, dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); /* Issue ioctl */ - err = vvz_dm_create(label, num_sectors, params); + err = sflite_dm_create(label, num_sectors, params); if (err) { - vvz_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); + sflite_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); goto err_dmcreate; } err = 0; @@ -105,8 +105,8 @@ err_hexkey: * * @return Error code, 0 on success */ -int vvz_ops_closeVolume(char *label) +int sflite_ops_closeVolume(char *label) { /* Issue ioctl */ - return vvz_dm_destroy(label); + return sflite_dm_destroy(label); } diff --git a/vuvuzela-userland/src/operations/dmb.c b/shufflecake-userland-lite/src/operations/dmb.c similarity index 67% rename from vuvuzela-userland/src/operations/dmb.c rename to shufflecake-userland-lite/src/operations/dmb.c index b15e583..31569e7 100644 --- a/vuvuzela-userland/src/operations/dmb.c +++ b/shufflecake-userland-lite/src/operations/dmb.c @@ -33,7 +33,7 @@ #include "header.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -54,30 +54,30 @@ * * @return Error code, 0 on success */ -int vvz_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, vvz_Dmb *dmb) +int sflite_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflite_Dmb *dmb) { /* On-disk DMB */ - char enc_dmb[VVZ_BLOCK_SIZE]; + char enc_dmb[SFLITE_BLOCK_SIZE]; /* Error code */ int err; /* Sanity check */ - if (dmb->nr_vols > VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); + if (dmb->nr_vols > SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); return EINVAL; } /* Seal DMB */ - err = vvz_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); + err = sflite_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); if (err) { - vvz_log_error("Coul dnot seal DMB; error %d", err); + sflite_log_error("Coul dnot seal DMB; error %d", err); return err; } /* Write it to disk (at sector 0) */ - err = vvz_disk_writeBlock(bdev_path, 0, enc_dmb); + err = sflite_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { - vvz_log_error("Could not write DMB to disk; error %d", err); + sflite_log_error("Could not write DMB to disk; error %d", err); return err; } @@ -93,26 +93,26 @@ int vvz_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, vvz_Dmb *dm * @param pwd_len Its length * * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= VVZ_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vol_idx Its index (>= SFLITE_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int vvz_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, vvz_DmbCell *dmb) +int sflite_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflite_DmbCell *dmb) { - char enc_dmb[VVZ_BLOCK_SIZE]; + char enc_dmb[SFLITE_BLOCK_SIZE]; int err; /* Read DMB from disk (at sector 0) */ - err = vvz_disk_readBlock(bdev_path, 0, enc_dmb); + err = sflite_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { - vvz_log_error("Could not read DMB from disk; error %d", err); + sflite_log_error("Could not read DMB from disk; error %d", err); return err; } /* Unseal it */ - err = vvz_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); + err = sflite_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); if (err) { - vvz_log_error("Could not unseal DMB; error %d", err); + sflite_log_error("Could not unseal DMB; error %d", err); return err; } @@ -129,35 +129,35 @@ int vvz_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, vvz_DmbCell *dmb * * @return Error code, 0 on success */ -int vvz_ops_rewriteDmbCell(char *bdev_path, vvz_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) +int sflite_ops_rewriteDmbCell(char *bdev_path, sflite_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) { - char enc_dmb[VVZ_BLOCK_SIZE]; + char enc_dmb[SFLITE_BLOCK_SIZE]; int err; /* Sanity check */ - if (dmb_cell->vol_idx >= VVZ_DEV_MAX_VOLUMES) { - vvz_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + if (dmb_cell->vol_idx >= SFLITE_DEV_MAX_VOLUMES) { + sflite_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); return EINVAL; } /* Read DMB from disk (at sector 0) */ - err = vvz_disk_readBlock(bdev_path, 0, enc_dmb); + err = sflite_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { - vvz_log_error("Could not read DMB from disk; error %d", err); + sflite_log_error("Could not read DMB from disk; error %d", err); return err; } /* Update the relevant cell */ - err = vvz_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); + err = sflite_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); if (err) { - vvz_log_error("Could not update DMB cell; error %d", err); + sflite_log_error("Could not update DMB cell; error %d", err); return err; } /* Write it to disk (at sector 0) */ - err = vvz_disk_writeBlock(bdev_path, 0, enc_dmb); + err = sflite_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { - vvz_log_error("Could not write DMB to disk; error %d", err); + sflite_log_error("Could not write DMB to disk; error %d", err); return err; } diff --git a/vuvuzela-userland/src/operations/volume_header.c b/shufflecake-userland-lite/src/operations/volume_header.c similarity index 71% rename from vuvuzela-userland/src/operations/volume_header.c rename to shufflecake-userland-lite/src/operations/volume_header.c index 9c5e611..40e0fda 100644 --- a/vuvuzela-userland/src/operations/volume_header.c +++ b/shufflecake-userland-lite/src/operations/volume_header.c @@ -33,7 +33,7 @@ #include "header.h" #include "header.h" #include "operations.h" -#include "utils/vvz.h" +#include "utils/sflite.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -53,42 +53,42 @@ * * @return Error code, 0 on success */ -int vvz_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, vvz_Vmb *vmb, size_t vol_idx) +int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflite_Vmb *vmb, size_t vol_idx) { - char enc_vmb[VVZ_BLOCK_SIZE]; + char enc_vmb[SFLITE_BLOCK_SIZE]; void *epm; uint64_t sector; int err; // Encrypt VMB - err = vvz_vmb_seal(vmb, vmb_key, enc_vmb); + err = sflite_vmb_seal(vmb, vmb_key, enc_vmb); if (err) { - vvz_log_error("Could not seal VMB; error %d", err); + sflite_log_error("Could not seal VMB; error %d", err); goto out; } // Write it to disk sector = 1 + vol_idx; - err = vvz_disk_writeBlock(bdev_path, sector, enc_vmb); + err = sflite_disk_writeBlock(bdev_path, sector, enc_vmb); if (err) { - vvz_log_error("Could not write VMB to disk; error %d", err); + sflite_log_error("Could not write VMB to disk; error %d", err); goto out; } // Create encrypted empty position map - epm = vvz_epm_create(vmb->nr_slices, vol_idx, vmb->volume_key); + epm = sflite_epm_create(vmb->nr_slices, vol_idx, vmb->volume_key); if (!epm) { - vvz_log_error("Could not create encrypted empty position map."); + sflite_log_error("Could not create encrypted empty position map."); err = ENOMEM; goto out; } // Write to disk - sector = vvz_pmStartBlock(vol_idx, vmb->nr_slices); - err = vvz_disk_writeManyBlocks(bdev_path, sector, epm, - ceil(vmb->nr_slices, VVZ_SLICE_IDX_PER_BLOCK)); + sector = sflite_pmStartBlock(vol_idx, vmb->nr_slices); + err = sflite_disk_writeManyBlocks(bdev_path, sector, epm, + ceil(vmb->nr_slices, SFLITE_SLICE_IDX_PER_BLOCK)); if (err) { - vvz_log_error("Could not write encrypted PosMap; error %d", err); + sflite_log_error("Could not write encrypted PosMap; error %d", err); } free(epm); @@ -110,30 +110,30 @@ out: * * @return Error code, 0 on success */ -int vvz_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, vvz_Vmb *vmb) +int sflite_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflite_Vmb *vmb) { - char enc_vmb[VVZ_BLOCK_SIZE]; + char enc_vmb[SFLITE_BLOCK_SIZE]; uint64_t sector; int err; /* Read encrypted VMB from disk */ sector = 1 + vol_idx; - err = vvz_disk_readBlock(bdev_path, sector, enc_vmb); + err = sflite_disk_readBlock(bdev_path, sector, enc_vmb); if (err) { - vvz_log_error("Could not read VMB from disk; error %d", err); + sflite_log_error("Could not read VMB from disk; error %d", err); return err; } /* Unseal it */ - err = vvz_vmb_unseal(enc_vmb, vmb_key, vmb); + err = sflite_vmb_unseal(enc_vmb, vmb_key, vmb); if (err) { - vvz_log_error("Could not unseal VMB; error %d", err); + sflite_log_error("Could not unseal VMB; error %d", err); return err; } /* Compare the number of slices */ if (nr_slices != vmb->nr_slices) { - vvz_log_error("Incompatible header size: the device size was different when the volumes" + sflite_log_error("Incompatible header size: the device size was different when the volumes" "were created. Did you resize the device %s since last time?", bdev_path); return EINVAL; } diff --git a/vuvuzela-userland/src/utils/crypto.c b/shufflecake-userland-lite/src/utils/crypto.c similarity index 66% rename from vuvuzela-userland/src/utils/crypto.c rename to shufflecake-userland-lite/src/utils/crypto.c index 6f93c4a..d7331e1 100644 --- a/vuvuzela-userland/src/utils/crypto.c +++ b/shufflecake-userland-lite/src/utils/crypto.c @@ -44,7 +44,7 @@ * *@return The error code (0 on success) */ -int vvz_rand_getStrongBytes(char *buf, size_t buflen) +int sflite_rand_getStrongBytes(char *buf, size_t buflen) { gcry_randomize(buf, buflen, GCRY_VERY_STRONG_RANDOM); return 0; @@ -61,7 +61,7 @@ int vvz_rand_getStrongBytes(char *buf, size_t buflen) * *@return The error code (0 on success) */ -int vvz_rand_getWeakBytes(char *buf, size_t buflen) +int sflite_rand_getWeakBytes(char *buf, size_t buflen) { gcry_create_nonce(buf, buflen); return 0; @@ -81,7 +81,7 @@ int vvz_rand_getWeakBytes(char *buf, size_t buflen) * *@return The error code (0 on success) */ -int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +int sflite_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -89,26 +89,26 @@ int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); if (err) { - vvz_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + sflite_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); goto bad_open; } - vvz_log_debug("Successfully instantiated AES256-CTR cipher handle"); + sflite_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); if (err) { - vvz_log_error("Could not set AES key: error %d", err); + sflite_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - vvz_log_debug("Successfully set the AES key"); + sflite_log_debug("Successfully set the AES key"); // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, VVZ_AESCTR_IVLEN); + err = gcry_cipher_setctr(hd, iv, SFLITE_AESCTR_IVLEN); if (err) { - vvz_log_error("Could not set AES-CTR IV: error %d", err); + sflite_log_error("Could not set AES-CTR IV: error %d", err); goto bad_setctr; } - vvz_log_debug("Successfully set the IV"); + sflite_log_debug("Successfully set the IV"); // Encrypt if (ct == NULL) { // In-place @@ -119,10 +119,10 @@ int vvz_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct } // Error check if (err) { - vvz_log_error("Could not encrypt: error %d", err); + sflite_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - vvz_log_debug("Successfully encrypted"); + sflite_log_debug("Successfully encrypted"); // No prob? err = 0; @@ -149,7 +149,7 @@ bad_open: * *@return The error code (0 on success) */ -int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) +int sflite_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -157,26 +157,26 @@ int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); if (err) { - vvz_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + sflite_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); goto bad_open; } - vvz_log_debug("Successfully instantiated AES256-CTR cipher handle"); + sflite_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); if (err) { - vvz_log_error("Could not set AES key: error %d", err); + sflite_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - vvz_log_debug("Successfully set AES key"); + sflite_log_debug("Successfully set AES key"); // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, VVZ_AESCTR_IVLEN); + err = gcry_cipher_setctr(hd, iv, SFLITE_AESCTR_IVLEN); if (err) { - vvz_log_error("Could not set AES-CTR IV: error %d", err); + sflite_log_error("Could not set AES-CTR IV: error %d", err); goto bad_setctr; } - vvz_log_debug("Successfully set IV"); + sflite_log_debug("Successfully set IV"); // Decrypt if (pt == NULL) { // In-place @@ -187,10 +187,10 @@ int vvz_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt } // Error check if (err) { - vvz_log_error("Could not decrypt: error %d", err); + sflite_log_error("Could not decrypt: error %d", err); goto bad_decrypt; } - vvz_log_debug("Successfully decrypted"); + sflite_log_debug("Successfully decrypted"); // No prob err = 0; @@ -219,7 +219,7 @@ bad_open: * * @return The error code (0 on success) */ -int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +int sflite_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -227,26 +227,26 @@ int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_XTS, GCRY_CIPHER_SECURE); if (err) { - vvz_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); + sflite_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); goto bad_open; } - vvz_log_debug("Successfully instantiated AES256-XTS cipher handle"); + sflite_log_debug("Successfully instantiated AES256-XTS cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, VVZ_AESXTS_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLITE_AESXTS_KEYLEN); if (err) { - vvz_log_error("Could not set AES-XTS key: error %d", err); + sflite_log_error("Could not set AES-XTS key: error %d", err); goto bad_setkey; } - vvz_log_debug("Successfully set the AES-XTS key"); + sflite_log_debug("Successfully set the AES-XTS key"); // Set the IV (not a counter, as per Gcrypt docs) - err = gcry_cipher_setiv(hd, iv, VVZ_AESXTS_IVLEN); + err = gcry_cipher_setiv(hd, iv, SFLITE_AESXTS_IVLEN); if (err) { - vvz_log_error("Could not set AES-XTS IV: error %d", err); + sflite_log_error("Could not set AES-XTS IV: error %d", err); goto bad_setiv; } - vvz_log_debug("Successfully set the IV"); + sflite_log_debug("Successfully set the IV"); // Encrypt if (ct == NULL) { // In-place @@ -257,10 +257,10 @@ int vvz_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct } // Error check if (err) { - vvz_log_error("Could not encrypt: error %d", err); + sflite_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - vvz_log_debug("Successfully encrypted"); + sflite_log_debug("Successfully encrypted"); // No prob? err = 0; @@ -289,7 +289,7 @@ bad_open: * *@return The error code (0 on success) */ -int vvz_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) +int sflite_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -297,42 +297,42 @@ int vvz_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); if (err) { - vvz_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + sflite_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); goto bad_open; } - vvz_log_debug("Successfully instantiated AES256-GCM cipher handle"); + sflite_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); if (err) { - vvz_log_error("Could not set AES key: error %d", err); + sflite_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - vvz_log_debug("Successfully set the AES key"); + sflite_log_debug("Successfully set the AES key"); // Set the IV - err = gcry_cipher_setiv(hd, iv, VVZ_AESGCM_IVLEN); + err = gcry_cipher_setiv(hd, iv, SFLITE_AESGCM_IVLEN); if (err) { - vvz_log_error("Could not set AES-GCM IV: error %d", err); + sflite_log_error("Could not set AES-GCM IV: error %d", err); goto bad_setiv; } - vvz_log_debug("Successfully set the IV"); + sflite_log_debug("Successfully set the IV"); // Encrypt err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); if (err) { - vvz_log_error("Could not encrypt: error %d", err); + sflite_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - vvz_log_debug("Successfully encrypted"); + sflite_log_debug("Successfully encrypted"); // Get MAC - err = gcry_cipher_gettag(hd, tag, VVZ_AESGCM_TAGLEN); + err = gcry_cipher_gettag(hd, tag, SFLITE_AESGCM_TAGLEN); if (err) { - vvz_log_error("Could not get MAC: error %d", err); + sflite_log_error("Could not get MAC: error %d", err); goto bad_gettag; } - vvz_log_debug("Successfully gotten MAC"); + sflite_log_debug("Successfully gotten MAC"); // No prob? err = 0; @@ -364,7 +364,7 @@ bad_open: * *@return The error code (0 on success) */ -int vvz_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) +int sflite_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -372,52 +372,52 @@ int vvz_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *i // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); if (err) { - vvz_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + sflite_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); goto bad_open; } - vvz_log_debug("Successfully instantiated AES256-GCM cipher handle"); + sflite_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, VVZ_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); if (err) { - vvz_log_error("Could not set AES key: error %d", err); + sflite_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - vvz_log_debug("Successfully set AES key"); + sflite_log_debug("Successfully set AES key"); // Set the IV - err = gcry_cipher_setiv(hd, iv, VVZ_AESGCM_IVLEN); + err = gcry_cipher_setiv(hd, iv, SFLITE_AESGCM_IVLEN); if (err) { - vvz_log_error("Could not set AES-GCM IV: error %d", err); + sflite_log_error("Could not set AES-GCM IV: error %d", err); goto bad_setiv; } - vvz_log_debug("Successfully set IV"); + sflite_log_debug("Successfully set IV"); // Decrypt err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); if (err) { - vvz_log_error("Could not decrypt: error %d", err); + sflite_log_error("Could not decrypt: error %d", err); goto bad_decrypt; } - vvz_log_debug("Successfully decrypted"); + sflite_log_debug("Successfully decrypted"); // Check MAC - err = gcry_cipher_checktag(hd, tag, VVZ_AESGCM_TAGLEN); + err = gcry_cipher_checktag(hd, tag, SFLITE_AESGCM_TAGLEN); if (gcry_err_code(err) == GPG_ERR_CHECKSUM) { // Undo decryption - memset(pt, VVZ_AESGCM_POISON_PT, ct_len); + memset(pt, SFLITE_AESGCM_POISON_PT, ct_len); // Flag it *match = false; } else if (err) { - vvz_log_error("Could not check MAC: error %d", err); + sflite_log_error("Could not check MAC: error %d", err); goto bad_checktag; } else { // Flag MAC verification success *match = true; } - vvz_log_debug("Successfully checked MAC: match = %d", *match); + sflite_log_debug("Successfully checked MAC: match = %d", *match); // No prob, whether MAC verified or not err = 0; @@ -444,11 +444,11 @@ bad_open: * * @return The error code (0 on success) */ -int vvz_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) +int sflite_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) { gcry_kdf_hd_t hd; const unsigned long argon_params[4] = - {VVZ_STANDARD_KEYLEN, VVZ_ARGON_T, VVZ_ARGON_M, VVZ_ARGON_P}; + {SFLITE_STANDARD_KEYLEN, SFLITE_ARGON_T, SFLITE_ARGON_M, SFLITE_ARGON_P}; gcry_error_t err; // Instantiate Argon2id handle @@ -456,31 +456,31 @@ int vvz_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) &hd, GCRY_KDF_ARGON2, GCRY_KDF_ARGON2ID, argon_params, 4, pwd, pwd_len, - salt, VVZ_ARGON_SALTLEN, + salt, SFLITE_ARGON_SALTLEN, NULL, 0, /* Optional secret value K */ NULL, 0 /* Optional associated data X */ ); if (err) { - vvz_log_error("Could not open Argon2id handle: error %d", err); + sflite_log_error("Could not open Argon2id handle: error %d", err); goto bad_open; } - vvz_log_debug("Successfully opened Argon2id handle"); + sflite_log_debug("Successfully opened Argon2id handle"); // Run the computation err = gcry_kdf_compute(hd, NULL); if (err) { - vvz_log_error("Could not run Argon2id computation: error %d", err); + sflite_log_error("Could not run Argon2id computation: error %d", err); goto bad_compute; } - vvz_log_debug("Successfully run Argon2id computation"); + sflite_log_debug("Successfully run Argon2id computation"); // Finalise hash - err = gcry_kdf_final(hd, VVZ_STANDARD_KEYLEN, hash); + err = gcry_kdf_final(hd, SFLITE_STANDARD_KEYLEN, hash); if (err) { - vvz_log_error("Could not finalise Argon2id hash: error %d", err); + sflite_log_error("Could not finalise Argon2id hash: error %d", err); goto bad_final; } - vvz_log_debug("Successfully finalised Argon2id hash"); + sflite_log_debug("Successfully finalised Argon2id hash"); // All in order err = 0; diff --git a/vuvuzela-userland/src/utils/disk.c b/shufflecake-userland-lite/src/utils/disk.c similarity index 74% rename from vuvuzela-userland/src/utils/disk.c rename to shufflecake-userland-lite/src/utils/disk.c index 8b35caa..79f2be2 100644 --- a/vuvuzela-userland/src/utils/disk.c +++ b/shufflecake-userland-lite/src/utils/disk.c @@ -56,14 +56,14 @@ * * @return A string version of the device ID */ -char *vvz_disk_getDeviceName(char *bdev_path) +char *sflite_disk_getDeviceName(char *bdev_path) { struct stat sb; char *dev_name; if (stat(bdev_path, &sb) != 0) return NULL; - dev_name = malloc(VVZ_BIGBUFSIZE); + dev_name = malloc(SFLITE_BIGBUFSIZE); if (!dev_name) return NULL; @@ -80,7 +80,7 @@ char *vvz_disk_getDeviceName(char *bdev_path) * * @return true iff it's a block device */ -bool vvz_disk_isBlockDevice(char *path) +bool sflite_disk_isBlockDevice(char *path) { struct stat path_stat; if (stat(path, &path_stat) != 0) { @@ -96,7 +96,7 @@ bool vvz_disk_isBlockDevice(char *path) * * @return The size (in 4096-byte sectors) of the disk, or -errno if error */ -int64_t vvz_disk_getSize(char * bdev_path) +int64_t sflite_disk_getSize(char * bdev_path) { int fd; uint64_t size_bytes; @@ -105,24 +105,24 @@ int64_t vvz_disk_getSize(char * bdev_path) /* Open file */ fd = open(bdev_path, O_RDONLY); if (fd < 0) { - vvz_log_error("Could not open file %s", bdev_path); + sflite_log_error("Could not open file %s", bdev_path); perror("Cause: "); ret = -errno; goto bad_open; } - vvz_log_debug("Opened file %s", bdev_path); + sflite_log_debug("Opened file %s", bdev_path); /* Get size in bytes */ if (ioctl(fd, BLKGETSIZE64, &size_bytes) < 0) { - vvz_log_error("Could not ioctl file %s", bdev_path); + sflite_log_error("Could not ioctl file %s", bdev_path); perror("Cause: "); ret = -errno; goto bad_ioctl; } - vvz_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); + sflite_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); - /* Compute size in VVZ sectors */ - ret = (size_bytes / VVZ_BLOCK_SIZE); + /* Compute size in SFLITE sectors */ + ret = (size_bytes / SFLITE_BLOCK_SIZE); bad_ioctl: close(fd); @@ -140,7 +140,7 @@ bad_open: * * @return The error code (0 on success) */ -int vvz_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) +int sflite_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) { int fd; int err; @@ -148,29 +148,29 @@ int vvz_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) /* Open file */ fd = open(bdev_path, O_RDONLY); if (fd < 0) { - vvz_log_error("Could not open file %s", bdev_path); + sflite_log_error("Could not open file %s", bdev_path); perror("Cause: "); err = errno; goto bad_open; } - vvz_log_debug("Opened file %s", bdev_path); + sflite_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * VVZ_BLOCK_SIZE, SEEK_SET) < 0) { - vvz_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + if (lseek(fd, sector * SFLITE_BLOCK_SIZE, SEEK_SET) < 0) { + sflite_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_lseek; } - vvz_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + sflite_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Read in a loop */ - size_t bytes_to_read = VVZ_BLOCK_SIZE; + size_t bytes_to_read = SFLITE_BLOCK_SIZE; while (bytes_to_read > 0) { /* Read syscall */ ssize_t bytes_read = read(fd, buf, bytes_to_read); if (bytes_read < 0) { - vvz_log_error("Could not read file %s at sector %lu", bdev_path, sector); + sflite_log_error("Could not read file %s at sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_read; @@ -178,7 +178,7 @@ int vvz_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) /* Partial read? No problem just log */ if (bytes_read < bytes_to_read) { - vvz_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", + sflite_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", bdev_path, sector, bytes_read, bytes_to_read); } @@ -209,7 +209,7 @@ bad_open: * * @return The error code (0 on success) */ -int vvz_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) +int sflite_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) { int fd; int err; @@ -217,29 +217,29 @@ int vvz_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size /* Open file */ fd = open(bdev_path, O_WRONLY); if (fd < 0) { - vvz_log_error("Could not open file %s", bdev_path); + sflite_log_error("Could not open file %s", bdev_path); perror("Cause: "); err = errno; goto bad_open; } - vvz_log_debug("Opened file %s", bdev_path); + sflite_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * VVZ_BLOCK_SIZE, SEEK_SET) < 0) { - vvz_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + if (lseek(fd, sector * SFLITE_BLOCK_SIZE, SEEK_SET) < 0) { + sflite_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_lseek; } - vvz_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + sflite_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Write in a loop */ - size_t bytes_to_write = VVZ_BLOCK_SIZE * num_sectors; + size_t bytes_to_write = SFLITE_BLOCK_SIZE * num_sectors; while (bytes_to_write > 0) { /* Write syscall */ ssize_t bytes_written = write(fd, buf, bytes_to_write); if (bytes_written < 0) { - vvz_log_red("Could not write file %s at sector %lu", bdev_path, sector); + sflite_log_red("Could not write file %s at sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_write; @@ -247,7 +247,7 @@ int vvz_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size /* Partial write? No problem just log */ if (bytes_written < bytes_to_write) { - vvz_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", + sflite_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", bdev_path, sector, bytes_written, bytes_to_write); } diff --git a/vuvuzela-userland/src/utils/dm.c b/shufflecake-userland-lite/src/utils/dm.c similarity index 75% rename from vuvuzela-userland/src/utils/dm.c rename to shufflecake-userland-lite/src/utils/dm.c index 31e3f14..da6f259 100644 --- a/vuvuzela-userland/src/utils/dm.c +++ b/shufflecake-userland-lite/src/utils/dm.c @@ -35,6 +35,7 @@ #include #include "utils/dm.h" +#include "utils/sflite.h" #include "utils/log.h" @@ -53,7 +54,7 @@ * * @return The error code (0 on success) */ -int vvz_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) +int sflite_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) { struct dm_task *dmt; uint32_t cookie = 0; @@ -64,60 +65,60 @@ int vvz_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) char * dup_virt_dev_name = strdup(virt_dev_name); char * dup_params = strdup(params); - vvz_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); + sflite_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); /* Instantiate the DM task (with the CREATE ioctl command) */ if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) { - vvz_log_error("Cannot create dm_task"); + sflite_log_error("Cannot create dm_task"); err = 1; goto dup_free; } - vvz_log_debug("Successfully created dm_task"); + sflite_log_debug("Successfully created dm_task"); /* Set the name of the target device (to be created) */ if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - vvz_log_error("Cannot set device name"); + sflite_log_error("Cannot set device name"); err = 2; goto out; } - vvz_log_debug("Successfully set device name"); + sflite_log_debug("Successfully set device name"); /* State that it is a Shufflecake device, pass the start and size, and the * constructor parameters */ - if (!dm_task_add_target(dmt, 0, num_sectors, VVZ_DM_TARGET_NAME, dup_params)) { - vvz_log_error("Cannot add DM target and parameters"); + if (!dm_task_add_target(dmt, 0, num_sectors, SFLC_DM_TARGET_NAME, dup_params)) { + sflite_log_error("Cannot add DM target and parameters"); err = 3; goto out; } - vvz_log_debug("Successfully added DM target and parameters"); + sflite_log_debug("Successfully added DM target and parameters"); /* Say that we want a new node under /dev/mapper */ if (!dm_task_set_add_node(dmt, DM_ADD_NODE_ON_CREATE)) { - vvz_log_error("Cannot add /dev/mapper node"); + sflite_log_error("Cannot add /dev/mapper node"); err = 4; goto out; } - vvz_log_debug("Successfully set the ADD_NODE flag"); + sflite_log_debug("Successfully set the ADD_NODE flag"); /* Get a cookie (request ID, basically) to wait for task completion */ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - vvz_log_error("Cannot get cookie"); + sflite_log_error("Cannot get cookie"); err = 5; goto out; } - vvz_log_debug("Successfully got a cookie"); + sflite_log_debug("Successfully got a cookie"); /* Run the task */ if (!dm_task_run(dmt)) { - vvz_log_error("Cannot issue ioctl"); + sflite_log_error("Cannot issue ioctl"); err = 6; goto out; } - vvz_log_debug("Successfully run DM task"); + sflite_log_debug("Successfully run DM task"); /* Wait for completion */ dm_udev_wait(cookie); - vvz_log_debug("Task completed"); + sflite_log_debug("Task completed"); // No prob err = 0; @@ -139,7 +140,7 @@ dup_free: * * @return error code (0 on success) */ -int vvz_dm_destroy(char * virt_dev_name) +int sflite_dm_destroy(char * virt_dev_name) { struct dm_task *dmt; uint32_t cookie = 0; @@ -149,47 +150,47 @@ int vvz_dm_destroy(char * virt_dev_name) /* Just to be sure, let's get it on the heap */ char * dup_virt_dev_name = strdup(virt_dev_name); - vvz_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); + sflite_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); /* Instantiate the DM task (with the REMOVE ioctl command) */ if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) { - vvz_log_error("Cannot create dm_task"); + sflite_log_error("Cannot create dm_task"); err = 1; goto dup_free; } - vvz_log_debug("Successfully created dm_task"); + sflite_log_debug("Successfully created dm_task"); /* Set the name of the target device (to be closed) */ if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - vvz_log_error("Cannot set device name"); + sflite_log_error("Cannot set device name"); err = 2; goto out; } - vvz_log_debug("Successfully set device name"); + sflite_log_debug("Successfully set device name"); /* Get a cookie (request ID, basically) to wait for task completion */ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - vvz_log_error("Cannot set cookie"); + sflite_log_error("Cannot set cookie"); err = 3; goto out; } - vvz_log_debug("Successfully got a cookie"); + sflite_log_debug("Successfully got a cookie"); /* Needed for some reason */ dm_task_retry_remove(dmt); - vvz_log_debug("Successful retry_remove"); + sflite_log_debug("Successful retry_remove"); /* Run the task */ if (!dm_task_run(dmt)) { - vvz_log_error("Cannot issue ioctl"); + sflite_log_error("Cannot issue ioctl"); err = 4; goto out; } - vvz_log_debug("Successfully run task"); + sflite_log_debug("Successfully run task"); /* Wait for completion */ dm_udev_wait(cookie); - vvz_log_debug("Task completed"); + sflite_log_debug("Task completed"); // No prob err = 0; diff --git a/vuvuzela-userland/src/utils/file.c b/shufflecake-userland-lite/src/utils/file.c similarity index 92% rename from vuvuzela-userland/src/utils/file.c rename to shufflecake-userland-lite/src/utils/file.c index 84b13ff..82c7472 100644 --- a/vuvuzela-userland/src/utils/file.c +++ b/shufflecake-userland-lite/src/utils/file.c @@ -38,7 +38,7 @@ *****************************************************/ /* Reads the entire content of a file in a malloc-ed string */ -char *vvz_readFile(char *path) +char *sflite_readFile(char *path) { int filesize; FILE *fp; @@ -47,7 +47,7 @@ char *vvz_readFile(char *path) /* Open file */ fp = fopen(path, "r"); if (fp == NULL) { - vvz_log_error("Could not open file %s", path); + sflite_log_error("Could not open file %s", path); perror("Reason: "); goto bad_fopen; } @@ -60,7 +60,7 @@ char *vvz_readFile(char *path) /* Allocate */ content = malloc(filesize + 1); if (content == NULL) { - vvz_log_error("Could not malloc %d bytes for file content", filesize); + sflite_log_error("Could not malloc %d bytes for file content", filesize); goto bad_malloc; } diff --git a/vuvuzela-userland/src/utils/input.c b/shufflecake-userland-lite/src/utils/input.c similarity index 93% rename from vuvuzela-userland/src/utils/input.c rename to shufflecake-userland-lite/src/utils/input.c index 8a7b776..5a0e9ac 100644 --- a/vuvuzela-userland/src/utils/input.c +++ b/shufflecake-userland-lite/src/utils/input.c @@ -41,13 +41,13 @@ *****************************************************/ /* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int vvz_safeReadLine(char *buf, size_t bufsize) +int sflite_safeReadLine(char *buf, size_t bufsize) { size_t len; /* Read from stdin */ if (fgets(buf, bufsize, stdin) == NULL) { - vvz_log_error("Could not read from stdin"); + sflite_log_error("Could not read from stdin"); return EBADFD; } @@ -62,7 +62,7 @@ int vvz_safeReadLine(char *buf, size_t bufsize) /* Reads a password/passphrase in a secure way (no echo) */ -int vvz_safeReadPassphrase(char *buf, size_t bufsize) +int sflite_safeReadPassphrase(char *buf, size_t bufsize) { size_t len; struct termios old, new; @@ -79,7 +79,7 @@ int vvz_safeReadPassphrase(char *buf, size_t bufsize) if (fgets(buf, bufsize, stdin) == NULL) { // If reading the password failed, ensure echoing is turned back on tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); - vvz_log_error("Could not read from stdin"); + sflite_log_error("Could not read from stdin"); return EBADFD; } diff --git a/vuvuzela-userland/src/utils/string.c b/shufflecake-userland-lite/src/utils/string.c similarity index 92% rename from vuvuzela-userland/src/utils/string.c rename to shufflecake-userland-lite/src/utils/string.c index 555a127..86d735f 100644 --- a/vuvuzela-userland/src/utils/string.c +++ b/shufflecake-userland-lite/src/utils/string.c @@ -38,7 +38,7 @@ *****************************************************/ /* Malloc's the buffer for the hex string */ -char *vvz_toHex(char *buf, size_t len) +char *sflite_toHex(char *buf, size_t len) { unsigned char *u = (unsigned char *) buf; char *hex; @@ -46,7 +46,7 @@ char *vvz_toHex(char *buf, size_t len) /* Allocate buffer */ hex = malloc((len * 2) + 1); if (!hex) { - vvz_log_error("Could not allocate buffer for hex string"); + sflite_log_error("Could not allocate buffer for hex string"); return NULL; } @@ -61,7 +61,7 @@ char *vvz_toHex(char *buf, size_t len) } -void vvz_str_replaceAll(char * str, char old, char new) +void sflite_str_replaceAll(char * str, char old, char new) { int i; for (i = 0; str[i] != '\0'; i++) { diff --git a/vuvuzela-userland/test/crypto/test_aes256ctr.c b/shufflecake-userland-lite/test/crypto/test_aes256ctr.c similarity index 88% rename from vuvuzela-userland/test/crypto/test_aes256ctr.c rename to shufflecake-userland-lite/test/crypto/test_aes256ctr.c index 356cd15..ce2676b 100644 --- a/vuvuzela-userland/test/crypto/test_aes256ctr.c +++ b/shufflecake-userland-lite/test/crypto/test_aes256ctr.c @@ -56,10 +56,10 @@ char *test_aes256ctr_encrypt_inplace() char iv[] = AES256CTR_TEST_IV; int err; - vvz_log_blue("Testing AES256-CTR encryption in-place"); + sflite_log_blue("Testing AES256-CTR encryption in-place"); // Encrypt in-place - err = vvz_aes256ctr_encrypt(key, msg, msg_len, iv, NULL); + err = sflite_aes256ctr_encrypt(key, msg, msg_len, iv, NULL); // Check error mu_assert("Error while encrypting", !err); @@ -73,7 +73,7 @@ char *test_aes256ctr_encrypt_inplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } @@ -87,10 +87,10 @@ char *test_aes256ctr_encrypt_outofplace() char iv[] = AES256CTR_TEST_IV; int err; - vvz_log_blue("Testing AES256-CTR encryption out-of-place"); + sflite_log_blue("Testing AES256-CTR encryption out-of-place"); // Encrypt out-of-place - err = vvz_aes256ctr_encrypt(key, msg, msg_len, iv, ct); + err = sflite_aes256ctr_encrypt(key, msg, msg_len, iv, ct); // Check error mu_assert("Error while encrypting", !err); @@ -107,7 +107,7 @@ char *test_aes256ctr_encrypt_outofplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } @@ -120,10 +120,10 @@ char *test_aes256ctr_decrypt_inplace() char iv[] = AES256CTR_TEST_IV; int err; - vvz_log_blue("Testing AES256-CTR decryption in-place"); + sflite_log_blue("Testing AES256-CTR decryption in-place"); // Decrypt in-place - err = vvz_aes256ctr_decrypt(key, msg, msg_len, iv, NULL); + err = sflite_aes256ctr_decrypt(key, msg, msg_len, iv, NULL); // Check error mu_assert("Error while decrypting", !err); @@ -137,7 +137,7 @@ char *test_aes256ctr_decrypt_inplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } @@ -151,10 +151,10 @@ char *test_aes256ctr_decrypt_outofplace() char iv[] = AES256CTR_TEST_IV; int err; - vvz_log_blue("Testing AES256-CTR decryption out-of-place"); + sflite_log_blue("Testing AES256-CTR decryption out-of-place"); // Decrypt out-of-place - err = vvz_aes256ctr_decrypt(key, msg, msg_len, iv, pt); + err = sflite_aes256ctr_decrypt(key, msg, msg_len, iv, pt); // Check error mu_assert("Error while decrypting", !err); @@ -171,7 +171,7 @@ char *test_aes256ctr_decrypt_outofplace() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } diff --git a/vuvuzela-userland/test/crypto/test_aes256ctr.h b/shufflecake-userland-lite/test/crypto/test_aes256ctr.h similarity index 100% rename from vuvuzela-userland/test/crypto/test_aes256ctr.h rename to shufflecake-userland-lite/test/crypto/test_aes256ctr.h diff --git a/vuvuzela-userland/test/crypto/test_aes256gcm.c b/shufflecake-userland-lite/test/crypto/test_aes256gcm.c similarity index 87% rename from vuvuzela-userland/test/crypto/test_aes256gcm.c rename to shufflecake-userland-lite/test/crypto/test_aes256gcm.c index dfc8dfd..da5458a 100644 --- a/vuvuzela-userland/test/crypto/test_aes256gcm.c +++ b/shufflecake-userland-lite/test/crypto/test_aes256gcm.c @@ -56,20 +56,20 @@ char *test_aes256gcm_encrypt() char key[] = AES256GCM_TEST_KEY; char iv[] = AES256GCM_TEST_IV; char ct[sizeof(pt)]; - char tag[VVZ_AESGCM_TAGLEN]; + char tag[SFLITE_AESGCM_TAGLEN]; int err; - vvz_log_blue("Testing AES256-GCM encryption"); + sflite_log_blue("Testing AES256-GCM encryption"); // Encrypt - err = vvz_aes256gcm_encrypt(key, pt, pt_len, iv, ct, tag); + err = sflite_aes256gcm_encrypt(key, pt, pt_len, iv, ct, tag); // Check error mu_assert("Error while encrypting", !err); // Check outcome mu_assert("Ciphertext mismatch", memcmp(ct, CT, pt_len) == 0); - mu_assert("MAC mismatch", memcmp(tag, TAG, VVZ_AESGCM_TAGLEN) == 0); + mu_assert("MAC mismatch", memcmp(tag, TAG, SFLITE_AESGCM_TAGLEN) == 0); // Check key untouched mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); @@ -77,7 +77,7 @@ char *test_aes256gcm_encrypt() // Check IV untouched mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } @@ -93,10 +93,10 @@ char *test_aes256gcm_decrypt_good() char pt[sizeof(ct)]; int err; - vvz_log_blue("Testing AES256-GCM decryption with the proper MAC"); + sflite_log_blue("Testing AES256-GCM decryption with the proper MAC"); // Decrypt - err = vvz_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); + err = sflite_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); // Check error mu_assert("Error while decrypting", !err); @@ -114,7 +114,7 @@ char *test_aes256gcm_decrypt_good() // Check MAC untouched mu_assert("MAC changed", memcmp(tag, TAG, sizeof(tag)) == 0); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } @@ -130,13 +130,13 @@ char *test_aes256gcm_decrypt_fail() char pt[sizeof(ct)]; int err; - vvz_log_blue("Testing AES256-GCM decryption without the proper MAC"); + sflite_log_blue("Testing AES256-GCM decryption without the proper MAC"); // Corrupt the MAC tag[0] += 1; // Decrypt - err = vvz_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); + err = sflite_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); // Check error mu_assert("Error while decrypting", !err); @@ -154,7 +154,7 @@ char *test_aes256gcm_decrypt_fail() mu_assert("Tail of MAC changed", memcmp(tag+1, TAG+1, sizeof(tag)-1) == 0); mu_assert("Head of MAC changed", tag[0] == TAG[0]+1); - vvz_log_green("OK"); + sflite_log_green("OK"); return NULL; } diff --git a/vuvuzela-userland/test/crypto/test_aes256gcm.h b/shufflecake-userland-lite/test/crypto/test_aes256gcm.h similarity index 100% rename from vuvuzela-userland/test/crypto/test_aes256gcm.h rename to shufflecake-userland-lite/test/crypto/test_aes256gcm.h diff --git a/vuvuzela-userland/test/crypto/test_argon2id.c b/shufflecake-userland-lite/test/crypto/test_argon2id.c similarity index 84% rename from vuvuzela-userland/test/crypto/test_argon2id.c rename to shufflecake-userland-lite/test/crypto/test_argon2id.c index 7a26ab9..b50bf3e 100644 --- a/vuvuzela-userland/test/crypto/test_argon2id.c +++ b/shufflecake-userland-lite/test/crypto/test_argon2id.c @@ -39,7 +39,7 @@ * CONSTANT VARIABLES * *****************************************************/ -char SALT[VVZ_ARGON_SALTLEN+1] = "Poor Petrol Pump"; +char SALT[SFLITE_ARGON_SALTLEN+1] = "Poor Petrol Pump"; /***************************************************** @@ -48,17 +48,17 @@ char SALT[VVZ_ARGON_SALTLEN+1] = "Poor Petrol Pump"; char *test_argon2id() { - char pwd[VVZ_BIGBUFSIZE]; - char key[VVZ_STANDARD_KEYLEN]; + char pwd[SFLITE_BIGBUFSIZE]; + char key[SFLITE_STANDARD_KEYLEN]; int err; - vvz_log_blue("Testing Argon2id interactively with a fixed salt"); + sflite_log_blue("Testing Argon2id interactively with a fixed salt"); // Loop until user breaks out while (true) { /* Collect password */ printf("Choose password to hash (empty to skip): "); - err = vvz_safeReadLine(pwd, VVZ_BIGBUFSIZE); + err = sflite_safeReadLine(pwd, SFLITE_BIGBUFSIZE); mu_assert("Could not read password", !err); /* Check if empty */ @@ -67,15 +67,15 @@ char *test_argon2id() } /* Hash it */ - err = vvz_argon2id_derive(pwd, strlen(pwd), SALT, key); + err = sflite_argon2id_derive(pwd, strlen(pwd), SALT, key); mu_assert("Could not hash password", !err); /* Print it */ printf("Salt used ASCII: \"%s\". Hex:\n", SALT); - vvz_log_hex(SALT, VVZ_ARGON_SALTLEN); + sflite_log_hex(SALT, SFLITE_ARGON_SALTLEN); printf("Argon2id hash (m = %d, t = %d, p = %d):\n", - VVZ_ARGON_M, VVZ_ARGON_T, VVZ_ARGON_P); - vvz_log_hex(key, VVZ_STANDARD_KEYLEN); + SFLITE_ARGON_M, SFLITE_ARGON_T, SFLITE_ARGON_P); + sflite_log_hex(key, SFLITE_STANDARD_KEYLEN); printf("Go check the result online\n\n"); } diff --git a/vuvuzela-userland/test/crypto/test_argon2id.h b/shufflecake-userland-lite/test/crypto/test_argon2id.h similarity index 100% rename from vuvuzela-userland/test/crypto/test_argon2id.h rename to shufflecake-userland-lite/test/crypto/test_argon2id.h diff --git a/vuvuzela-userland/test/main.c b/shufflecake-userland-lite/test/main.c similarity index 94% rename from vuvuzela-userland/test/main.c rename to shufflecake-userland-lite/test/main.c index ee4e805..1f3a506 100644 --- a/vuvuzela-userland/test/main.c +++ b/shufflecake-userland-lite/test/main.c @@ -49,10 +49,10 @@ int main() char *result = all_tests(); if (result != NULL) { - vvz_log_red("\nTEST FAILED: %s", result); + sflite_log_red("\nTEST FAILED: %s", result); } else { - vvz_log_green("\nALL TESTS PASSED"); + sflite_log_green("\nALL TESTS PASSED"); } return result != NULL; @@ -65,7 +65,7 @@ int main() static char *all_tests() { - vvz_log_yellow("Running crypto tests"); + sflite_log_yellow("Running crypto tests"); mu_run_test(test_aes256ctr_encrypt_inplace); mu_run_test(test_aes256ctr_encrypt_outofplace); mu_run_test(test_aes256ctr_decrypt_inplace); diff --git a/vuvuzela-userland/test/minunit.h b/shufflecake-userland-lite/test/minunit.h similarity index 100% rename from vuvuzela-userland/test/minunit.h rename to shufflecake-userland-lite/test/minunit.h diff --git a/vuvuzela-userland/include/vvz_constants.h b/vuvuzela-userland/include/vvz_constants.h deleted file mode 120000 index 5c10997..0000000 --- a/vuvuzela-userland/include/vvz_constants.h +++ /dev/null @@ -1 +0,0 @@ -../../dm-vvz/vvz_constants.h \ No newline at end of file From bec7c7765de1ad5bc4e5e7aec3d1ce419e8b327c Mon Sep 17 00:00:00 2001 From: = Date: Sat, 3 Aug 2024 22:42:38 +0200 Subject: [PATCH 61/75] Update legacy to current version --- shufflecake-userland-legacy/Makefile.sources | 6 +- .../include/{cli => }/cli.h | 26 +- .../include/{commands => }/commands.h | 28 +- .../device_master_block.h => header.h} | 96 +++++-- .../include/header/position_map.h | 76 ------ .../include/header/volume_master_block.h | 87 ------ .../{actions/volume.h => operations.h} | 70 ++--- .../include/utils/sflc.h | 4 +- .../src/actions/create_vol.c | 136 ---------- .../src/actions/open.c | 252 ------------------ .../src/actions/open_vol.c | 155 ----------- .../src/cli/changepwd.c | 112 ++++++++ shufflecake-userland-legacy/src/cli/close.c | 4 +- .../src/cli/dispatch.c | 77 ++++-- shufflecake-userland-legacy/src/cli/init.c | 13 +- shufflecake-userland-legacy/src/cli/open.c | 25 +- .../actions/device.h => src/cli/testpwd.c} | 72 +++-- .../close.c => commands/change_pwd.c} | 23 +- .../src/commands/close.c | 16 +- .../src/commands/init.c | 56 ++-- .../src/commands/open.c | 187 ++++++------- .../close_vol.c => commands/test_pwd.c} | 24 +- .../src/header/device_master_block.c | 58 +++- .../src/header/position_map.c | 2 +- .../src/header/volume_master_block.c | 14 +- shufflecake-userland-legacy/src/main.c | 2 +- .../src/operations/devmapper.c | 111 ++++++++ .../src/{actions => operations}/dmb.c | 76 ++++-- .../create.c => operations/volume_header.c} | 96 ++++--- shufflecake-userland-legacy/src/utils/input.c | 3 + .../test/actions/test_actions.h | 39 --- .../test/actions/test_all_actions.c | 128 --------- .../test/actions/test_create.c | 100 ------- .../test/commands/test_commands.h | 36 --- .../test/commands/test_init.c | 87 ------ 35 files changed, 814 insertions(+), 1483 deletions(-) rename shufflecake-userland-legacy/include/{cli => }/cli.h (78%) rename shufflecake-userland-legacy/include/{commands => }/commands.h (83%) rename shufflecake-userland-legacy/include/{header/device_master_block.h => header.h} (50%) delete mode 100644 shufflecake-userland-legacy/include/header/position_map.h delete mode 100644 shufflecake-userland-legacy/include/header/volume_master_block.h rename shufflecake-userland-legacy/include/{actions/volume.h => operations.h} (60%) delete mode 100644 shufflecake-userland-legacy/src/actions/create_vol.c delete mode 100644 shufflecake-userland-legacy/src/actions/open.c delete mode 100644 shufflecake-userland-legacy/src/actions/open_vol.c create mode 100644 shufflecake-userland-legacy/src/cli/changepwd.c rename shufflecake-userland-legacy/{include/actions/device.h => src/cli/testpwd.c} (52%) rename shufflecake-userland-legacy/src/{actions/close.c => commands/change_pwd.c} (78%) rename shufflecake-userland-legacy/src/{actions/close_vol.c => commands/test_pwd.c} (78%) create mode 100644 shufflecake-userland-legacy/src/operations/devmapper.c rename shufflecake-userland-legacy/src/{actions => operations}/dmb.c (64%) rename shufflecake-userland-legacy/src/{actions/create.c => operations/volume_header.c} (61%) delete mode 100644 shufflecake-userland-legacy/test/actions/test_actions.h delete mode 100644 shufflecake-userland-legacy/test/actions/test_all_actions.c delete mode 100644 shufflecake-userland-legacy/test/actions/test_create.c delete mode 100644 shufflecake-userland-legacy/test/commands/test_commands.h delete mode 100644 shufflecake-userland-legacy/test/commands/test_init.c diff --git a/shufflecake-userland-legacy/Makefile.sources b/shufflecake-userland-legacy/Makefile.sources index ce6de04..0e2a80b 100644 --- a/shufflecake-userland-legacy/Makefile.sources +++ b/shufflecake-userland-legacy/Makefile.sources @@ -29,9 +29,9 @@ PROJ_SRCS := $(addprefix utils/,crypto.c disk.c dm.c file.c string.c input.c) PROJ_SRCS += $(addprefix header/,position_map.c volume_master_block.c device_master_block.c) -PROJ_SRCS += $(addprefix actions/,create_vol.c open_vol.c close_vol.c dmb.c) -PROJ_SRCS += $(addprefix commands/,init.c open.c close.c) -PROJ_SRCS += $(addprefix cli/,dispatch.c init.c open.c close.c) +PROJ_SRCS += $(addprefix operations/,volume_header.c devmapper.c dmb.c) +PROJ_SRCS += $(addprefix commands/,init.c open.c close.c test_pwd.c change_pwd.c) +PROJ_SRCS += $(addprefix cli/,dispatch.c init.c open.c close.c testpwd.c changepwd.c) PROJ_SRCS += main.c PROJ_ROOT := src diff --git a/shufflecake-userland-legacy/include/cli/cli.h b/shufflecake-userland-legacy/include/cli.h similarity index 78% rename from shufflecake-userland-legacy/include/cli/cli.h rename to shufflecake-userland-legacy/include/cli.h index fcca9c2..838f618 100644 --- a/shufflecake-userland-legacy/include/cli/cli.h +++ b/shufflecake-userland-legacy/include/cli.h @@ -21,20 +21,24 @@ * If not, see . */ -#ifndef _CLI_CLI_H_ -#define _CLI_CLI_H_ +#ifndef _CLI_H_ +#define _CLI_H_ /***************************************************** * CONSTANTS * *****************************************************/ -/* Subcommand to create volumes */ -#define SFLC_CLI_INITCMD "init" -/* Subcommand to open volumes */ -#define SFLC_CLI_OPENCMD "open" -/* Subcommand to close volumes */ -#define SFLC_CLI_CLOSECMD "close" +/* Action to create volumes */ +#define SFLC_CLI_INITACT "init" +/* Action to open volumes */ +#define SFLC_CLI_OPENACT "open" +/* Action to close volumes */ +#define SFLC_CLI_CLOSEACT "close" +/* Action to test password */ +#define SFLC_CLI_TESTPWDACT "testpwd" +/* Action to change password */ +#define SFLC_CLI_CHANGEPWDACT "changepwd" /***************************************************** @@ -50,8 +54,12 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill); int sflc_cli_open(char *block_device); /* Close volumes */ int sflc_cli_close(char *block_device); +/* Test password */ +int sflc_cli_testPwd(char *block_device); +/* Change password */ +int sflc_cli_changePwd(char *block_device); -#endif /* _CLI_CLI_H_ */ +#endif /* _CLI_H_ */ diff --git a/shufflecake-userland-legacy/include/commands/commands.h b/shufflecake-userland-legacy/include/commands.h similarity index 83% rename from shufflecake-userland-legacy/include/commands/commands.h rename to shufflecake-userland-legacy/include/commands.h index 959c1a4..68a14ac 100644 --- a/shufflecake-userland-legacy/include/commands/commands.h +++ b/shufflecake-userland-legacy/include/commands.h @@ -21,8 +21,8 @@ * If not, see . */ -#ifndef _COMMANDS_COMMANDS_H_ -#define _COMMANDS_COMMANDS_H_ +#ifndef _COMMANDS_H_ +#define _COMMANDS_H_ /***************************************************** @@ -33,6 +33,8 @@ #include #include +#include "header.h" + /***************************************************** * CONSTANTS * @@ -73,6 +75,20 @@ typedef struct } sflc_cmd_OpenArgs; +typedef struct +{ + /* Underlying block device */ + char *bdev_path; + + /* Content of the DMB cell */ + sflc_DmbCell *dmb_cell; + + /* The new password */ + char *new_pwd; + size_t new_pwd_len; + +} sflc_cmd_ChangePwdArgs; + /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * @@ -87,5 +103,11 @@ int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args); /* Close all volumes on the device (reads the list from sysfs) */ int sflc_cmd_closeVolumes(char *bdev_path); +/* Tests which volume is unlocked by the given password */ +int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell); -#endif /* _COMMANDS_COMMANDS_H_ */ +/* Changes the specified volume's password */ +int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args); + + +#endif /* _COMMANDS_H_ */ diff --git a/shufflecake-userland-legacy/include/header/device_master_block.h b/shufflecake-userland-legacy/include/header.h similarity index 50% rename from shufflecake-userland-legacy/include/header/device_master_block.h rename to shufflecake-userland-legacy/include/header.h index 235323f..869b868 100644 --- a/shufflecake-userland-legacy/include/header/device_master_block.h +++ b/shufflecake-userland-legacy/include/header.h @@ -21,12 +21,8 @@ * If not, see . */ -/* - * Defines the Device Master Block (DMB) and related functionalities - */ - -#ifndef _HEADER_DEVICE_MASTER_BLOCK_H_ -#define _HEADER_DEVICE_MASTER_BLOCK_H_ +#ifndef _HEADER_H_ +#define _HEADER_H_ /***************************************************** @@ -36,7 +32,6 @@ #include #include -#include "utils/disk.h" #include "utils/crypto.h" @@ -45,22 +40,29 @@ *****************************************************/ /* The DMB contains one IV + one VMB key + one MAC for each volume */ -#define SFLC_DMB_CELL (SFLC_AESGCM_PADDED_IVLEN + SFLC_CRYPTO_KEYLEN + SFLC_AESGCM_TAGLEN) +#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_CRYPTO_KEYLEN + SFLC_AESGCM_TAGLEN) /* Let us enforce that the one DMB can fit cells for all volumes */ -#if SFLC_SCRYPT_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL) > SFLC_SECTOR_SIZE +#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL) > SFLC_SECTOR_SIZE #error "Invalid combination of parameters: probably SFLC_DEV_MAX_VOLUMES is too big" #endif +// The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) +#define SFLC_CLEAR_VMB_LEN (SFLC_SECTOR_SIZE - \ + SFLC_AESGCM_PADDED_IVLEN - \ + SFLC_AESGCM_TAGLEN) + + + /***************************************************** * STRUCTS * *****************************************************/ /** - * The on-disk master block of a volume contains lots of crypto stuff + * The on-disk master block of a device contains lots of crypto stuff * (a KDF salt, IVs, MACs...) used to properly hide the VMB keys. - * This struct only contains such useful info. + * This struct only contains such useful info, in the clear. */ typedef struct { // Each volume's VMB key @@ -69,7 +71,8 @@ typedef struct { // How many of these need actually be encrypted size_t nr_vols; -} sflc_CompleteDeviceMasterBlock; +} sflc_Dmb; + /** * When unsealing a DMB, only one VMB key can be unlocked with a password. @@ -82,7 +85,54 @@ typedef struct { // The index of the volume opened by this VMB key size_t vol_idx; -} sflc_PartialDeviceMasterBlock; +} sflc_DmbCell; + + +/** + * The on-disk master block of a volume contains crypto stuff + * (an IV) used to properly hide the useful info. This struct + * only contains the useful info, in the clear. + */ +typedef struct { + // The key that encrypts the volume's data section + char volume_key[SFLC_CRYPTO_KEYLEN]; + + // The key that encrypts the previous volume's master block + char prev_vmb_key[SFLC_CRYPTO_KEYLEN]; + + // The total number of logical slices virtually available to this volume + size_t nr_slices; + +} sflc_Vmb; + + +/** + * This struct represents an encrypted empty position map. + * On-disk, the layout interleaves one IV block with 256 PosMap blocks (each + * encrypted by an IV in the IV block). Many such "runs" can be concatenated, + * until the position map is big enough to index the desired number of slices. + * The last "run" might be incomplete, in that it could have less than 256 + * PosMap blocks, if not all of them are needed. + * In the struct, there are as many IV blocks as there are PosMapBlock arrays + * (equal to the number of "runs"). The m-th IV of the n-th IV block encrypts + * the m-th block of the n-th array. The PosMapBlocks in an array are stored + * contiguously in RAM, so a PosMapBlock array is just a char array of length + * multiple of 4096. All the arrays are full (256 PosMapBlocks, 1 MiB) except + * for the last one, which may hold fewer blocks. + */ +typedef struct { + // The number of PosMapBlock arrays (and of IV blocks) + size_t nr_arrays; + + // The sequence of IV blocks + char **iv_blocks; + // The sequence of (encrypted) PosMapBlock arrays + char **pmb_arrays; + + // The number of PosMapBlocks in the last array + size_t nr_last_pmbs; + +} sflc_EncPosMap; /***************************************************** @@ -90,10 +140,22 @@ typedef struct { *****************************************************/ /* "Encrypt" each VMB key with its pwd, so the DMB is ready to be written on-disk */ -int sflc_dmb_seal(sflc_CompleteDeviceMasterBlock *dmb, char **pwds, size_t *pwd_lens, char *disk_block); - +int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); /* "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF) */ -int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_PartialDeviceMasterBlock *dmb); +int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); +/* Re-encrypt the content of a single DMB cell */ +int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len); -#endif /* _HEADER_DEVICE_MASTER_BLOCK_H_ */ +/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ +int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block); +/* "Decrypt" a VMB coming from the disk, directly using its key */ +int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); + + +/* Create an encrypted empty position map for the given number of slices (allocates memory) */ +int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm); + + + +#endif /* _HEADER_H_ */ diff --git a/shufflecake-userland-legacy/include/header/position_map.h b/shufflecake-userland-legacy/include/header/position_map.h deleted file mode 100644 index c927944..0000000 --- a/shufflecake-userland-legacy/include/header/position_map.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Helpers to encrypt an empty position map - */ - -#ifndef _HEADER_POSITION_MAP_H_ -#define _HEADER_POSITION_MAP_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - - -/***************************************************** - * STRUCTS * - *****************************************************/ - -/** - * This struct represents an encrypted empty position map. - * There are as many IV blocks as there are PosMapBlock arrays. - * The m-th IV of the n-th IV block encrypts the m-th block of the n-th array. - * The PosMapBlocks in an array are contiguous, so a PosMapBlock array is just - * a char array of length multiple of 4096. - * All the arrays are full (256 PosMapBlocks, 1 MiB) except for the last one, - * which may hold fewer blocks. - */ -typedef struct { - // The number of PosMapBlock arrays (and of IV blocks) - size_t nr_arrays; - - // The sequence of IV blocks - char **iv_blocks; - // The sequence of (encrypted) PosMapBlock arrays - char **pmb_arrays; - - // The number of PosMapBlocks in the last array - size_t nr_last_pmbs; - -} sflc_EncPosMap; - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Create an encrypted empty position map for the given number of slices (allocates memory) */ -int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm); - - -#endif /* _HEADER_POSITION_MAP_H_ */ diff --git a/shufflecake-userland-legacy/include/header/volume_master_block.h b/shufflecake-userland-legacy/include/header/volume_master_block.h deleted file mode 100644 index 12cbc84..0000000 --- a/shufflecake-userland-legacy/include/header/volume_master_block.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Defines the Volume Master Block (VMB) and related functionalities - */ - -#ifndef _HEADER_VOLUME_MASTER_BLOCK_H_ -#define _HEADER_VOLUME_MASTER_BLOCK_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "utils/disk.h" -#include "utils/crypto.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -// The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) -#define SFLC_CLEAR_VMB_LEN (SFLC_SECTOR_SIZE - \ - SFLC_AESGCM_PADDED_IVLEN - \ - SFLC_AESGCM_TAGLEN) - - - -/***************************************************** - * STRUCTS * - *****************************************************/ - -/** - * The on-disk master block of a volume contains crypto stuff - * (IVs, MACs...) used to properly hide the useful - * info. This struct only contains the useful info. - */ -typedef struct { - // The key that encrypts the volume's data section - char volume_key[SFLC_CRYPTO_KEYLEN]; - - // The key that encrypts the previous volume's master block - char prev_vmb_key[SFLC_CRYPTO_KEYLEN]; - - // The total number of logical slices virtually available to this volume - uint32_t nr_slices; - -} sflc_VolumeMasterBlock; - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ -int sflc_vmb_seal(sflc_VolumeMasterBlock *vmb, char *vmb_key, char *disk_block); - -/* "Decrypt" a VMB coming from the disk, directly using its key */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_VolumeMasterBlock *vmb); - - -#endif /* _HEADER_VOLUME_MASTER_BLOCK_H_ */ diff --git a/shufflecake-userland-legacy/include/actions/volume.h b/shufflecake-userland-legacy/include/operations.h similarity index 60% rename from shufflecake-userland-legacy/include/actions/volume.h rename to shufflecake-userland-legacy/include/operations.h index 30aed5b..8de9ab6 100644 --- a/shufflecake-userland-legacy/include/actions/volume.h +++ b/shufflecake-userland-legacy/include/operations.h @@ -21,12 +21,8 @@ * If not, see . */ -/* - * Defines the Volume - */ - -#ifndef _ACTION_VOLUME_H_ -#define _ACTION_VOLUME_H_ +#ifndef _OPERATIONS_H_ +#define _OPERATIONS_H_ /***************************************************** @@ -36,47 +32,11 @@ #include #include -#include "utils/disk.h" +#include "header.h" #include "utils/crypto.h" #include "utils/math.h" -/***************************************************** - * CONSTANTS * - *****************************************************/ - - -/***************************************************** - * STRUCTS * - *****************************************************/ - -/** - * Struct representing a volume. - * The functions in this module take a partially-filled struct in input - * and fill some more fields in it as part of their output. - */ -typedef struct { - // Keys - char vmb_key[SFLC_CRYPTO_KEYLEN]; - char volume_key[SFLC_CRYPTO_KEYLEN]; - char prev_vmb_key[SFLC_CRYPTO_KEYLEN]; - - // Number of slices - size_t nr_slices; - - // ID of the underlying block device - size_t dev_id; - // Index of this volume in the underlying block device - size_t vol_idx; - - // Underlying block device - char *bdev_path; - // Volume name under /dev/mapper/ - char label[SFLC_MAX_VOL_NAME_LEN + 1]; - -} sflc_Volume; - - /***************************************************** * INLINE FUNCTIONS * *****************************************************/ @@ -94,9 +54,9 @@ static inline size_t sflc_volHeaderSize(size_t nr_slices) } // Position of the VMB for the given volume -static inline uint64_t sflc_vmbPosition(sflc_Volume *vol) +static inline uint64_t sflc_vmbPosition(size_t vol_idx, size_t nr_slices) { - return 1 + ((uint64_t) vol->vol_idx) * ((uint64_t) sflc_volHeaderSize(vol->nr_slices)); + return 1 + ((uint64_t) vol_idx) * ((uint64_t) sflc_volHeaderSize(nr_slices)); } @@ -104,13 +64,21 @@ static inline uint64_t sflc_vmbPosition(sflc_Volume *vol) * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* Writes a volume header (VMB+PM) on-disk */ -int sflc_act_createVolume(sflc_Volume *vol); +/* Encrypts and writes the DMB to disk */ +int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb); +/* Reads the DMB from disk and outputs the unlocked VMB key */ +int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); +/* Reads the DMB from disk, changes the relevant DMB cell, and writes it back */ +int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); -/* Read a VMB from disk and issue a DM ioctl to create the appropriate virtual device */ -int sflc_act_openVolume(sflc_Volume *vol); +/* Encrypts and writes a volume header (VMB+PM) on-disk */ +int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx); +/* Reads a VMB from disk and unlocks it */ +int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb); +/* Build parameter list for ctor in dm_sflc, and send DM ioctl to create virtual block device */ +int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb); /* Close the volume via the appropriate ioctl to DM */ -int sflc_act_closeVolume(char *label); +int sflc_ops_closeVolume(char *label); -#endif /* _ACTION_VOLUME_H_ */ +#endif /* _OPERATIONS_H_ */ diff --git a/shufflecake-userland-legacy/include/utils/sflc.h b/shufflecake-userland-legacy/include/utils/sflc.h index 83ee0f6..e8135e4 100644 --- a/shufflecake-userland-legacy/include/utils/sflc.h +++ b/shufflecake-userland-legacy/include/utils/sflc.h @@ -22,7 +22,7 @@ */ /* - * Miscellaneous constants that must match with the definitions in the Kernel module + * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflc_constans.h */ #ifndef _UTILS_SFLC_H_ @@ -51,7 +51,7 @@ /* Max total number of open devices at any given time */ #define SFLC_TOT_MAX_DEVICES 1024 -/* A volume name is sflc-- */ +/* A volume name is sflc__ */ #define SFLC_MAX_VOL_NAME_LEN 15 /* A slice index is represented over 32 bits */ diff --git a/shufflecake-userland-legacy/src/actions/create_vol.c b/shufflecake-userland-legacy/src/actions/create_vol.c deleted file mode 100644 index 8cbc755..0000000 --- a/shufflecake-userland-legacy/src/actions/create_vol.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include - -#include "header/position_map.h" -#include "header/volume_master_block.h" -#include "actions/volume.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Writes a volume header (VMB+PM) on-disk. Also fills the struct's volume_key field. - * Some of the fields in the struct are input, some are output. - * - * @param vol->vmb_key The key to decrypt the VMB - * @param vol->prev_vmb_key The previous volume's VMB key - * @param vol->nr_slices The number of logical slices of the volume(s) - * @param vol->vol_idx The index of the volume within the device - * @param vol->bdev_path The underlying block device to write the volume header - * - * @output vol->volume_key This volume's data section key - * - * @unused vol->label - * @unused vol->dev_id - * - * @return Error code, 0 on success - */ -int sflc_act_createVolume(sflc_Volume *vol) -{ - sflc_VolumeMasterBlock vmb; - char enc_vmb[SFLC_SECTOR_SIZE]; - sflc_EncPosMap epm; - uint64_t sector; - int err; - - // Sample keys - sflc_rand_getWeakBytes(vol->volume_key, SFLC_CRYPTO_KEYLEN); - - // Fill VMB - memcpy(vmb.volume_key, vol->volume_key, SFLC_CRYPTO_KEYLEN); - memcpy(vmb.prev_vmb_key, vol->prev_vmb_key, SFLC_CRYPTO_KEYLEN); - vmb.nr_slices = vol->nr_slices; - - // Encrypt it - err = sflc_vmb_seal(&vmb, vol->vmb_key, enc_vmb); - if (err) { - sflc_log_error("Could not seal VMB; error %d", err); - goto out; - } - - // Write it to disk - sector = sflc_vmbPosition(vol); - err = sflc_disk_writeSector(vol->bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not write VMB to disk; error %d", err); - goto out; - } - sector += 1; - - // Create encrypted empty position map - err = sflc_epm_create(vol->nr_slices, vol->volume_key, &epm); - if (err) { - sflc_log_error("Could not create encrypted empty position map; error %d", err); - goto out; - } - - // Loop over PMB arrays to write it to disk - int i; - for (i = 0; i < epm.nr_arrays; i++) { - char *iv_block = epm.iv_blocks[i]; - char *pmb_array = epm.pmb_arrays[i]; - size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); - - // First write the IV block - err = sflc_disk_writeSector(vol->bdev_path, sector, iv_block); - if (err) { - sflc_log_error("Could not write IV block to disk; error %d", err); - goto out; - } - sector += 1; - - // Then the whole PMB array - err = sflc_disk_writeManySectors(vol->bdev_path, sector, pmb_array, nr_pmbs); - if (err) { - sflc_log_error("Could not write PMB array to disk; error %d", err); - goto out; - } - sector += nr_pmbs; - - // Free them both - free(iv_block); - free(pmb_array); - } - - // Free containers - free(epm.iv_blocks); - free(epm.pmb_arrays); - - -out: - return err; -} diff --git a/shufflecake-userland-legacy/src/actions/open.c b/shufflecake-userland-legacy/src/actions/open.c deleted file mode 100644 index 405a14a..0000000 --- a/shufflecake-userland-legacy/src/actions/open.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include - -#include "header/volume_master_block.h" -#include "actions/volume.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/file.h" -#include "utils/string.h" -#include "utils/dm.h" -#include "utils/log.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Open the volume through the appropriate ioctl */ -static int _openVolume(sflc_Volume *vol); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Check if the password is correct for this volume. - * - * @param pwd The password - * @param pwd_len The password length - * @param vol_idx The index of the volume in the device - * @param bdev_path The path to the underlying device - * @param nr_slices The number of logical slices for this device / volumes - * - * @output match A boolean containing the answer - * - * @return Error code, 0 on success - */ -int sflc_act_checkPwd(sflc_Volume *vol, bool *match) -{ - char enc_vmb[SFLC_SECTOR_SIZE]; - uint64_t sector; - int err; - - /* Read encrypted VMB from disk */ - sector = sflc_vmbPosition(vol); - err = sflc_disk_readSector(vol->bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not read VMB from disk; error %d", err); - return err; - } - - /* Try unsealing it */ - return sflc_vmb_tryUnsealWithPwd(enc_vmb, vol->pwd, vol->pwd_len, match); -} - - -/** - * Read a VMB from disk and issue a DM ioctl to create the appropriate virtual device - * - * @param pwd The password - * @param pwd_len The password length - * @param dev_id The ID of the underlying block device - * @param vol_idx The index of the volume within the device - * @param bdev_path The path to the underlying device - * @param nr_slices The number of logical slices for this device / volumes - * - * @output vmb_key This volume's VMB key - * @output volume_key This volume's data section key - * @output prev_vmb_key The previous volume's VMB key - * @output label The volume's name under /dev/mapper/ - * - * @return Error code, 0 on success - */ -int sflc_act_openVolumeWithPwd(sflc_Volume *vol) -{ - sflc_VolumeMasterBlock vmb; - char enc_vmb[SFLC_SECTOR_SIZE]; - uint64_t sector; - int err; - - /* Read encrypted VMB from disk */ - sector = sflc_vmbPosition(vol); - err = sflc_disk_readSector(vol->bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not read VMB from disk; error %d", err); - return err; - } - - /* Unseal it */ - err = sflc_vmb_unsealWithPwd(enc_vmb, vol->pwd, vol->pwd_len, &vmb); - if (err) { - sflc_log_error("Could not unseal VMB; error %d", err); - return err; - } - - /* Compare the number of slices */ - if (vol->nr_slices != vmb.nr_slices) { - sflc_log_error("Incompatible header size: the device size was different when the volumes" - "were created. Did you resize the device %s since last time?", vol->bdev_path); - return EINVAL; - } - /* Copy the keys over to the Volume struct */ - memcpy(vol->vmb_key, vmb.vmb_key, SFLC_CRYPTO_KEYLEN); - memcpy(vol->volume_key, vmb.volume_key, SFLC_CRYPTO_KEYLEN); - memcpy(vol->prev_vmb_key, vmb.prev_vmb_key, SFLC_CRYPTO_KEYLEN); - /* Build volume label */ - sprintf(vol->label, "sflc-%lu-%lu", vol->dev_id, vol->vol_idx); - - /* Actually open the volume */ - err = _openVolume(vol); - if (err) { - sflc_log_error("Could not open volume; error %d", err); - return err; - } - - return 0; -} - - -/** - * Read a VMB from disk and issue a DM ioctl to create the appropriate virtual device - * - * @param vmb_key The key encrypting this volume's VMB payload - * @param dev_id The ID of the underlying block device - * @param vol_idx The index of the volume within the device - * @param bdev_path The path to the underlying device - * @param nr_slices The number of logical slices for this device / volumes - * - * @output volume_key This volume's data section key - * @output prev_vmb_key The previous volume's VMB key - * @output vol_id The volume's unique numeric ID - * @output label The volume's name under /dev/mapper/ - * - * @return Error code, 0 on success - */ -int sflc_act_openVolumeWithKey(sflc_Volume *vol) -{ - sflc_VolumeMasterBlock vmb; - char enc_vmb[SFLC_SECTOR_SIZE]; - uint64_t sector; - int err; - - /* Read encrypted VMB from disk */ - sector = sflc_vmbPosition(vol); - err = sflc_disk_readSector(vol->bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not read VMB from disk; error %d", err); - return err; - } - - /* Unseal it */ - err = sflc_vmb_unsealWithKey(enc_vmb, vol->vmb_key, &vmb); - if (err) { - sflc_log_error("Could not unseal VMB; error %d", err); - return err; - } - - /* Compare the number of slices */ - if (vol->nr_slices != vmb.nr_slices) { - sflc_log_error("Incompatible header size: the device size was different when the volumes" - "were created. Did you resize the device %s since last time?", vol->bdev_path); - return EINVAL; - } - /* Copy the keys over to the Volume struct */ - memcpy(vol->vmb_key, vmb.vmb_key, SFLC_CRYPTO_KEYLEN); - memcpy(vol->volume_key, vmb.volume_key, SFLC_CRYPTO_KEYLEN); - memcpy(vol->prev_vmb_key, vmb.prev_vmb_key, SFLC_CRYPTO_KEYLEN); - /* Build volume label */ - sprintf(vol->label, "sflc-%lu-%lu", vol->dev_id, vol->vol_idx); - - /* Actually open the volume */ - err = _openVolume(vol); - if (err) { - sflc_log_error("Could not open volume; error %d", err); - return err; - } - - return 0; -} - - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Open the volume through the appropriate ioctl */ -static int _openVolume(sflc_Volume *vol) -{ - char *hex_key; - char params[SFLC_BIGBUFSIZE]; - uint64_t num_sectors; - int err; - - /* Get the hex version of the volume's data section key */ - hex_key = sflc_toHex(vol->volume_key, SFLC_CRYPTO_KEYLEN); - if (!hex_key) { - sflc_log_error("Could not encode volume key to hexadecimal"); - err = ENOMEM; - goto err_hexkey; - } - - /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vol->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; - - /* Build param list */ - sprintf(params, "%s %lu %lu %s", vol->bdev_path, vol->vol_idx, vol->nr_slices, hex_key); - - /* Issue ioctl */ - err = sflc_dm_create(vol->label, num_sectors, params); - if (err) { - sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); - goto err_dmcreate; - } - err = 0; - - -err_dmcreate: - free(hex_key); -err_hexkey: - return err; -} diff --git a/shufflecake-userland-legacy/src/actions/open_vol.c b/shufflecake-userland-legacy/src/actions/open_vol.c deleted file mode 100644 index 6cffe87..0000000 --- a/shufflecake-userland-legacy/src/actions/open_vol.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include - -#include "header/volume_master_block.h" -#include "actions/volume.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/file.h" -#include "utils/string.h" -#include "utils/dm.h" -#include "utils/log.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Open the volume through the appropriate ioctl */ -static int _openVolume(sflc_Volume *vol); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Read a VMB from disk and issue a DM ioctl to create the appropriate virtual device - * - * @param vol->vmb_key The key encrypting this volume's VMB - * @param vol->dev_id The ID of the underlying block device - * @param vol->vol_idx The index of the volume within the device - * @param vol->bdev_path The path to the underlying device - * @param vol->nr_slices The number of logical slices for this device / volumes - * - * @output vol->volume_key This volume's data section key - * @output vol->prev_vmb_key The previous volume's VMB key - * @output vol->label The volume's name under /dev/mapper/ - * - * @return Error code, 0 on success - */ -int sflc_act_openVolume(sflc_Volume *vol) -{ - sflc_VolumeMasterBlock vmb; - char enc_vmb[SFLC_SECTOR_SIZE]; - uint64_t sector; - int err; - - /* Read encrypted VMB from disk */ - sector = sflc_vmbPosition(vol); - err = sflc_disk_readSector(vol->bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not read VMB from disk; error %d", err); - return err; - } - - /* Unseal it */ - err = sflc_vmb_unseal(enc_vmb, vol->vmb_key, &vmb); - if (err) { - sflc_log_error("Could not unseal VMB; error %d", err); - return err; - } - - /* Compare the number of slices */ - if (vol->nr_slices != vmb.nr_slices) { - sflc_log_error("Incompatible header size: the device size was different when the volumes" - "were created. Did you resize the device %s since last time?", vol->bdev_path); - return EINVAL; - } - /* Copy the keys over to the Volume struct */ - memcpy(vol->volume_key, vmb.volume_key, SFLC_CRYPTO_KEYLEN); - memcpy(vol->prev_vmb_key, vmb.prev_vmb_key, SFLC_CRYPTO_KEYLEN); - /* Build volume label */ - sprintf(vol->label, "sflc_%lu_%lu", vol->dev_id, vol->vol_idx); - - /* Actually open the volume */ - err = _openVolume(vol); - if (err) { - sflc_log_error("Could not open volume; error %d", err); - return err; - } - - return 0; -} - - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Open the volume through the appropriate ioctl */ -static int _openVolume(sflc_Volume *vol) -{ - char *hex_key; - char params[SFLC_BIGBUFSIZE]; - uint64_t num_sectors; - int err; - - /* Get the hex version of the volume's data section key */ - hex_key = sflc_toHex(vol->volume_key, SFLC_CRYPTO_KEYLEN); - if (!hex_key) { - sflc_log_error("Could not encode volume key to hexadecimal"); - err = ENOMEM; - goto err_hexkey; - } - - /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vol->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; - - /* Build param list */ - sprintf(params, "%s %lu %lu %s", vol->bdev_path, vol->vol_idx, vol->nr_slices, hex_key); - - /* Issue ioctl */ - err = sflc_dm_create(vol->label, num_sectors, params); - if (err) { - sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); - goto err_dmcreate; - } - err = 0; - - -err_dmcreate: - free(hex_key); -err_hexkey: - return err; -} diff --git a/shufflecake-userland-legacy/src/cli/changepwd.c b/shufflecake-userland-legacy/src/cli/changepwd.c new file mode 100644 index 0000000..de37779 --- /dev/null +++ b/shufflecake-userland-legacy/src/cli/changepwd.c @@ -0,0 +1,112 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* + * Change volume password + * + * @return Error code, 0 on success + */ +int sflc_cli_changePwd(char *block_device) +{ // Requires: block_device is a correct block device path + sflc_cmd_OpenArgs open_args; + sflc_cmd_ChangePwdArgs change_pwd_args; + sflc_DmbCell dmb_cell; + char old_pwd[SFLC_BIGBUFSIZE]; + size_t old_pwd_len; + char new_pwd[SFLC_BIGBUFSIZE]; + size_t new_pwd_len; + int err; + + open_args.bdev_path = block_device; + + /* Gather password */ + printf("Enter the password you want to change: "); + err = sflc_safeReadPassphrase(old_pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + old_pwd_len = strlen(old_pwd); + /* Assign fields */ + open_args.pwd = old_pwd; + open_args.pwd_len = old_pwd_len; + + /* Test the password */ + err = sflc_cmd_testPwd(&open_args, &dmb_cell); + if (err) { + sflc_log_error("Could not test password; error %d", err); + return err; + } + + /* Does this password open any volumes? */ + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + printf("This password does not unlock any volume.\n"); + return 0; + } + + /* Gather new password (no secure shell) */ + printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); + printf("Choose new password for volume %lu: ", dmb_cell.vol_idx); + err = sflc_safeReadLine(new_pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read new password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + new_pwd_len = strlen(new_pwd); + + /* Assign fields */ + change_pwd_args.bdev_path = block_device; + change_pwd_args.dmb_cell = &dmb_cell; + change_pwd_args.new_pwd = new_pwd; + change_pwd_args.new_pwd_len = new_pwd_len; + + /* Change password */ + err = sflc_cmd_changePwd(&change_pwd_args); + if (err) { + sflc_log_error("Could not change password; error %d", err); + return err; + } + printf("Password changed successfully.\n"); + return err; +} diff --git a/shufflecake-userland-legacy/src/cli/close.c b/shufflecake-userland-legacy/src/cli/close.c index 3f37f35..fdbaa28 100644 --- a/shufflecake-userland-legacy/src/cli/close.c +++ b/shufflecake-userland-legacy/src/cli/close.c @@ -29,8 +29,8 @@ #include #include -#include "cli/cli.h" -#include "commands/commands.h" +#include "cli.h" +#include "commands.h" #include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" diff --git a/shufflecake-userland-legacy/src/cli/dispatch.c b/shufflecake-userland-legacy/src/cli/dispatch.c index 1273ba7..01da250 100644 --- a/shufflecake-userland-legacy/src/cli/dispatch.c +++ b/shufflecake-userland-legacy/src/cli/dispatch.c @@ -31,7 +31,7 @@ #include #include -#include "cli/cli.h" +#include "cli.h" #include "utils/sflc.h" #include "utils/disk.h" #include "utils/log.h" @@ -56,14 +56,16 @@ const char *argp_program_bug_address = ""; * TYPES * *****************************************************/ -enum sflc_cli_command { - SFLC_CMD_INIT, - SFLC_CMD_OPEN, - SFLC_CMD_CLOSE +enum sflc_cli_action { + SFLC_ACT_INIT, + SFLC_ACT_OPEN, + SFLC_ACT_CLOSE, + SFLC_ACT_TESTPWD, + SFLC_ACT_CHANGEPWD }; struct sflc_cli_arguments { - enum sflc_cli_command cmd; + enum sflc_cli_action act; char *block_device; int num_volumes; bool skip_randfill; @@ -82,8 +84,30 @@ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state); *****************************************************/ /* Doc strings */ -static char args_doc[] = "COMMAND "; -static char doc[] = "Shufflecake is a plausible deniability (hidden storage) layer for Linux.\nSee official website at for more info.\nPossible values for COMMAND are:\n\n\tinit:\tInitialise a block device for Shufflecake use, formatting\n\t\theaders with provided passwords and overwriting with random\n\t\tdata. WARNING: THIS WILL ERASE THE CONTENT OF THE DEVICE.\n\n\topen:\tOpen a hierarchy of Shufflecake volumes within a device by\n\t\tasking a single user password. Virtual devices will appear\n\t\tin /dev/mapper. Notice: freshly created device must be\n\t\tuser-formatted and mounted in order to be used.\n\n\tclose:\tClose all open Shufflecake volumes supported by given\n\t\tdevice.\n\nPossible options are:"; +static char args_doc[] = "ACTION "; +static char doc[] = + "Shufflecake is a plausible deniability (hidden storage) layer for Linux.\n" + "See official website at for more info.\n" + "Possible values for mandatory ACTION are:\n\n" + + "\tinit:\t\tInitialise a block device for Shufflecake use, formatting\n" + "\t\t\theaders with provided passwords and overwriting with random\n" + "\t\t\tdata. WARNING: THIS WILL ERASE THE CONTENT OF THE DEVICE.\n\n" + + "\topen:\t\tOpen a hierarchy of Shufflecake volumes within a device by\n" + "\t\t\tasking a single user password. Virtual devices will appear\n" + "\t\t\tin /dev/mapper. Notice: freshly created device must be\n" + "\t\t\tuser-formatted and mounted in order to be used.\n\n" + + "\tclose:\t\tClose all open Shufflecake volumes supported by given\n" + "\t\t\tdevice.\n\n" + + "\ttestpwd:\tTest whether a given password unlocks any volume within\n" + "\t\t\tthe block device and, if so, show its index.\n\n" + + "\tchangepwd:\tChange the password unlocking a certain volume.\n\n" + + "Possible options are:"; /* Description of each option */ static struct argp_option options[] = { @@ -115,7 +139,7 @@ static struct argp argp = {options, _parseArgpKey, args_doc, doc}; int sflc_cli_dispatch(int argc, char **argv) { struct sflc_cli_arguments arguments; - arguments.cmd = -1; + arguments.act = -1; arguments.block_device = NULL; arguments.num_volumes = 0; arguments.skip_randfill = false; @@ -124,12 +148,12 @@ int sflc_cli_dispatch(int argc, char **argv) { argp_parse(&argp, argc, argv, 0, 0, &arguments); /* Check options consistency */ - if (arguments.num_volumes && arguments.cmd != SFLC_CMD_INIT) { + if (arguments.num_volumes && arguments.act != SFLC_ACT_INIT) { printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); return EINVAL; } /* Check options consistency */ - if (arguments.skip_randfill && arguments.cmd != SFLC_CMD_INIT) { + if (arguments.skip_randfill && arguments.act != SFLC_ACT_INIT) { printf("Error: --skip-randfill can only be combined with `init'.\n"); return EINVAL; } @@ -140,15 +164,21 @@ int sflc_cli_dispatch(int argc, char **argv) { } /* Dispatch to specific command */ - if (arguments.cmd == SFLC_CMD_INIT) { + if (arguments.act == SFLC_ACT_INIT) { return sflc_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); } - if (arguments.cmd == SFLC_CMD_OPEN) { + if (arguments.act == SFLC_ACT_OPEN) { return sflc_cli_open(arguments.block_device); } - if (arguments.cmd == SFLC_CMD_CLOSE) { + if (arguments.act == SFLC_ACT_CLOSE) { return sflc_cli_close(arguments.block_device); } + if (arguments.act == SFLC_ACT_TESTPWD) { + return sflc_cli_testPwd(arguments.block_device); + } + if (arguments.act == SFLC_ACT_CHANGEPWD) { + return sflc_cli_changePwd(arguments.block_device); + } printf("\n"); @@ -168,14 +198,19 @@ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { case ARGP_KEY_ARG: /* We are parsing the command */ if (state->arg_num == 0) { - if (strcmp(arg, "init") == 0) { - arguments->cmd = SFLC_CMD_INIT; - } else if (strcmp(arg, "open") == 0) { - arguments->cmd = SFLC_CMD_OPEN; - } else if (strcmp(arg, "close") == 0) { - arguments->cmd = SFLC_CMD_CLOSE; + if (strcmp(arg, SFLC_CLI_INITACT) == 0) { + arguments->act = SFLC_ACT_INIT; + } else if (strcmp(arg, SFLC_CLI_OPENACT) == 0) { + arguments->act = SFLC_ACT_OPEN; + } else if (strcmp(arg, SFLC_CLI_CLOSEACT) == 0) { + arguments->act = SFLC_ACT_CLOSE; + } else if (strcmp(arg, SFLC_CLI_TESTPWDACT) == 0) { + arguments->act = SFLC_ACT_TESTPWD; + } else if (strcmp(arg, SFLC_CLI_CHANGEPWDACT) == 0) { + arguments->act = SFLC_ACT_CHANGEPWD; } else { - argp_error(state, "Invalid action. Please enter one and only one of: `init', `open', or `close'."); + argp_error(state, "Invalid action. Please enter one and only one of: `%s', `%s', `%s', '%s', or '%s'.", + SFLC_CLI_INITACT, SFLC_CLI_OPENACT, SFLC_CLI_CLOSEACT, SFLC_CLI_TESTPWDACT, SFLC_CLI_CHANGEPWDACT); } /* We are parsing the block device */ } else if (state->arg_num == 1) { diff --git a/shufflecake-userland-legacy/src/cli/init.c b/shufflecake-userland-legacy/src/cli/init.c index 9a129c9..302a96d 100644 --- a/shufflecake-userland-legacy/src/cli/init.c +++ b/shufflecake-userland-legacy/src/cli/init.c @@ -29,8 +29,8 @@ #include #include -#include "cli/cli.h" -#include "commands/commands.h" +#include "cli.h" +#include "commands.h" #include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -88,11 +88,11 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) "volume 0 (the least secret) to volume %lu (the most secret).\n\n", args.nr_vols - 1); size_t i; for (i = 0; i < args.nr_vols; i++) { - // Allocate pwd TODO: USE SECURE INPUT METHOD FOR PASSWORDS + // Allocate pwd pwds[i] = malloc(SFLC_BIGBUFSIZE); /* Read it */ - printf("Choose password for volume %lu: ", i); + printf("Choose password for volume %lu (must not be empty): ", i); err = sflc_safeReadLine(pwds[i], SFLC_BIGBUFSIZE); if (err) { sflc_log_error("Could not read password for volume %lu; error %d", i, err); @@ -101,6 +101,11 @@ int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) /* You can trust the length of strings input this way */ pwd_lens[i] = strlen(pwds[i]); + /* Check non-empty */ + if (pwd_lens[i] == 0) { + sflc_log_error("Password cannot be empty!"); + return EINVAL; + } } /* Assign them */ args.pwds = pwds; diff --git a/shufflecake-userland-legacy/src/cli/open.c b/shufflecake-userland-legacy/src/cli/open.c index e0f10dc..45464c9 100644 --- a/shufflecake-userland-legacy/src/cli/open.c +++ b/shufflecake-userland-legacy/src/cli/open.c @@ -29,8 +29,8 @@ #include #include -#include "cli/cli.h" -#include "commands/commands.h" +#include "cli.h" +#include "commands.h" #include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -48,26 +48,10 @@ int sflc_cli_open(char *block_device) { // Requires: block_device is a correct block device path sflc_cmd_OpenArgs args; -// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; char pwd[SFLC_BIGBUFSIZE]; size_t pwd_len; int err; -// /* Gather (absolute) path to underlying block device */ -// printf("Enter the absolute path to the underlying block device containing the Shufflecake volumes to open: "); -// err = sflc_safeReadLine(bdev_path, SFLC_BDEV_PATH_MAX_LEN + 2); -// if (err) { -// sflc_log_error("Could not read path to underlying block device; error %d", err); -// return err; -// } -// /* Check that it is absolute */ -// if (bdev_path[0] != '/') { -// printf("The path to the block device must be absolute"); -// return EINVAL; -// } -// /* Assign it */ -// args.bdev_path = bdev_path; - args.bdev_path = block_device; /* Gather password */ @@ -79,6 +63,11 @@ int sflc_cli_open(char *block_device) } /* You can trust the length of strings input this way */ pwd_len = strlen(pwd); + /* Check non-empty */ + if (pwd_len == 0) { + sflc_log_error("Password cannot be empty!"); + return EINVAL; + } /* Assign them */ args.pwd = pwd; args.pwd_len = pwd_len; diff --git a/shufflecake-userland-legacy/include/actions/device.h b/shufflecake-userland-legacy/src/cli/testpwd.c similarity index 52% rename from shufflecake-userland-legacy/include/actions/device.h rename to shufflecake-userland-legacy/src/cli/testpwd.c index 8b7188a..550df25 100644 --- a/shufflecake-userland-legacy/include/actions/device.h +++ b/shufflecake-userland-legacy/src/cli/testpwd.c @@ -21,39 +21,67 @@ * If not, see . */ -/* - * Global actions on the device - */ - -#ifndef _ACTION_DEVICE_H_ -#define _ACTION_DEVICE_H_ - - /***************************************************** * INCLUDE SECTION * *****************************************************/ -#include -#include +#include +#include +#include -#include "header/device_master_block.h" -#include "utils/disk.h" -#include "utils/crypto.h" +#include "cli.h" +#include "commands.h" +#include "utils/sflc.h" +#include "utils/input.h" +#include "utils/log.h" /***************************************************** - * CONSTANTS * + * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ +/* + * Test volume password + * + * @return Error code, 0 on success + */ +int sflc_cli_testPwd(char *block_device) +{ // Requires: block_device is a correct block device path + sflc_cmd_OpenArgs args; + sflc_DmbCell dmb_cell; +// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; + char pwd[SFLC_BIGBUFSIZE]; + size_t pwd_len; + int err; -/* Samples VMB keys and writes the corresponding DMB to disk */ -int sflc_act_createAndWriteDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_CompleteDeviceMasterBlock *dmb); + args.bdev_path = block_device; + + /* Gather password */ + printf("Enter the password you want to test: "); + err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); + if (err) { + sflc_log_error("Could not read password; error %d", err); + return err; + } + /* You can trust the length of strings input this way */ + pwd_len = strlen(pwd); + /* Assign them */ + args.pwd = pwd; + args.pwd_len = pwd_len; -/* Reads the DMB from disk and outputs the unlocked VMB key */ -int sflc_act_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_PartialDeviceMasterBlock *dmb); + /* Actually perform the command */ + err = sflc_cmd_testPwd(&args, &dmb_cell); + if (err) { + sflc_log_error("Could not test password; error %d", err); + return err; + } + /* Does this password open any volumes? */ + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + printf("This password does not unlock any volume.\n"); + } else { + printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); + } -#endif /* _ACTION_DEVICE_H_ */ + return 0; +} diff --git a/shufflecake-userland-legacy/src/actions/close.c b/shufflecake-userland-legacy/src/commands/change_pwd.c similarity index 78% rename from shufflecake-userland-legacy/src/actions/close.c rename to shufflecake-userland-legacy/src/commands/change_pwd.c index 008aaf6..2ef64e0 100644 --- a/shufflecake-userland-legacy/src/actions/close.c +++ b/shufflecake-userland-legacy/src/commands/change_pwd.c @@ -26,18 +26,14 @@ *****************************************************/ #include -#include -#include #include -#include +#include -#include "header/volume_master_block.h" -#include "actions/volume.h" +#include "commands.h" +#include "operations.h" #include "utils/sflc.h" #include "utils/crypto.h" #include "utils/file.h" -#include "utils/string.h" -#include "utils/dm.h" #include "utils/log.h" @@ -46,14 +42,17 @@ *****************************************************/ /** - * Close the volume by issuing the appropriate ioctl to the DM. + * Changes the specified volume's password. * - * @param label The only needed parameter: the ID of the volume. + * @param args->bdev_path The underlying block device + * @param args->dmb_cell The DMB cell to re-encrypt + * @param args->new_pwd The new password + * @param args->new_pwd_len Its length * * @return Error code, 0 on success */ -int sflc_act_closeVolume(char *label) +int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args) { - /* Issue ioctl */ - return sflc_dm_destroy(label); + /* Delegate entirely to the function reading the DMB */ + return sflc_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); } diff --git a/shufflecake-userland-legacy/src/commands/close.c b/shufflecake-userland-legacy/src/commands/close.c index 7b364cc..4c180f6 100644 --- a/shufflecake-userland-legacy/src/commands/close.c +++ b/shufflecake-userland-legacy/src/commands/close.c @@ -29,8 +29,8 @@ #include #include -#include "commands/commands.h" -#include "actions/volume.h" +#include "commands.h" +#include "operations.h" #include "utils/sflc.h" #include "utils/crypto.h" #include "utils/string.h" @@ -45,7 +45,7 @@ /* Reads the list of volumes from sysfs */ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols); -/* Close them all */ +/* Close them all (in reverse order of opening) */ static int _closeVolumes(char **labels, size_t nr_vols); @@ -83,7 +83,7 @@ int sflc_cmd_closeVolumes(char *bdev_path) goto out; } - /* Close the volumes */ + /* Close the volumes (in reverse order of opening) */ err = _closeVolumes(labels, nr_vols); if (err) { sflc_log_error("Could not close volumes; error %d", err); @@ -156,15 +156,15 @@ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) } -/* Close them all */ +/* Close them all (in reverse order of opening) */ static int _closeVolumes(char **labels, size_t nr_vols) { int err; /* Eazy peazy */ - size_t i; - for (i = 0; i < nr_vols; i++) { - err = sflc_act_closeVolume(labels[i]); + int i; + for (i = nr_vols-1; i >= 0; i--) { + err = sflc_ops_closeVolume(labels[i]); if (err) { sflc_log_error("Could not close volume %s; error %d", labels[i], err); return err; diff --git a/shufflecake-userland-legacy/src/commands/init.c b/shufflecake-userland-legacy/src/commands/init.c index 8f9212d..cd21b03 100644 --- a/shufflecake-userland-legacy/src/commands/init.c +++ b/shufflecake-userland-legacy/src/commands/init.c @@ -29,10 +29,10 @@ #include #include -#include "commands/commands.h" -#include "actions/device.h" -#include "actions/volume.h" +#include "commands.h" +#include "operations.h" #include "utils/sflc.h" +#include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -52,7 +52,7 @@ *****************************************************/ /* Fill the device with random data */ -static int _fillWithRandom(char *bdev_path, uint64_t dev_size); +static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); /***************************************************** @@ -74,7 +74,8 @@ static int _fillWithRandom(char *bdev_path, uint64_t dev_size); */ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) { - sflc_CompleteDeviceMasterBlock dmb; + sflc_Dmb dmb; + sflc_Vmb vmb; int64_t dev_size; size_t nr_slices; int err; @@ -85,7 +86,7 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) return EINVAL; } - /* Get device info */ + /* Get device size */ dev_size = sflc_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; @@ -96,42 +97,47 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) nr_slices = sflc_disk_maxSlices(dev_size); sflc_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); - /* Fill with random, if needed */ + /* Fill disk with random bytes, if requested */ if (!args->no_randfill) { - err = _fillWithRandom(args->bdev_path, (uint64_t) dev_size); + err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); if (err) { sflc_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); return err; } } - /* Create the DMB and write it to disk */ + /* Fill the DMB */ dmb.nr_vols = args->nr_vols; - err = sflc_act_createAndWriteDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); + /* Sample the VMB keys */ + size_t i; + for (i = 0; i < dmb.nr_vols; i++) { + err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_CRYPTO_KEYLEN); + if (err) { + sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); + return err; + } + } + /* And write (encrypted) to disk */ + err = sflc_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); if (err) { sflc_log_error("Could not create DMB and write it to disk; error %d", err); return err; } - /* Common fields for all the volumes */ - sflc_Volume vol; - vol.bdev_path = args->bdev_path; - vol.nr_slices = nr_slices; - /* Create each of the volumes */ - size_t i; + /* Write the volume headers */ + vmb.nr_slices = nr_slices; for (i = 0; i < args->nr_vols; i++) { - /* This volume's vmb_key and prev_vmb_key */ - memcpy(vol.vmb_key, dmb.vmb_keys[i], SFLC_CRYPTO_KEYLEN); + /* This volume's prev_vmb_key */ if (i > 0) { - memcpy(vol.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_CRYPTO_KEYLEN); + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_CRYPTO_KEYLEN); } - /* This volume's index */ - vol.vol_idx = i; + /* Sample this volume's VEK */ + sflc_rand_getStrongBytes(vmb.volume_key, SFLC_CRYPTO_KEYLEN); - /* Create volume */ - err = sflc_act_createVolume(&vol); + /* Write complete volume header (VMB + PM) */ + err = sflc_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); if (err) { - sflc_log_error("Error creating volume %lu on device %s; error %d", i, args->bdev_path, err); + sflc_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); return err; } } @@ -146,7 +152,7 @@ int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) *****************************************************/ /* Fill the device with random data */ -static int _fillWithRandom(char *bdev_path, uint64_t dev_size) +static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) { char *rand_chunk; int err; diff --git a/shufflecake-userland-legacy/src/commands/open.c b/shufflecake-userland-legacy/src/commands/open.c index 7e7b8e0..da0c4f0 100644 --- a/shufflecake-userland-legacy/src/commands/open.c +++ b/shufflecake-userland-legacy/src/commands/open.c @@ -25,29 +25,25 @@ * INCLUDE SECTION * *****************************************************/ +#include #include #include #include -#include "commands/commands.h" -#include "actions/volume.h" -#include "actions/device.h" +#include "commands.h" +#include "operations.h" #include "utils/sflc.h" #include "utils/crypto.h" +#include "utils/disk.h" #include "utils/file.h" #include "utils/log.h" +#include "utils/string.h" /***************************************************** * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -/* Finds the volume opened by the given pwd */ -static int _findVolumeByPwd(sflc_cmd_OpenArgs *args, size_t nr_slices, size_t *vol_idx, char *vmb_key); - -/* Opens the indicated volume and the previous ones with the VMB keys */ -static int _openVolumes(sflc_cmd_OpenArgs *args, size_t nr_slices, size_t vol_idx, char *vmb_key); - /* Read the next device ID in sysfs */ static int _getNextDevId(size_t *next_dev_id); @@ -57,13 +53,15 @@ static int _getNextDevId(size_t *next_dev_id); *****************************************************/ /** - * Open M volumes, from the one whose pwd is provided back up to the first one. - * Scans the device to find the volume that can be opened with the provided - * pwd, opens it, then opens the previous ones with their VMB key. + * Open M volumes, from the first one down to the one whose pwd is provided. + * Scans the DMB cells to find which one is unlocked by the provided pwd; then, + * using the decrypted VMB key, unlocks the M-th VMB; then, iteratively using + * the prev_vmb_key field, unlocks all the previous VMBs; then, using the + * decrypted VMB keys, opens the volumes "in order" from 1 to M. * * @param args->bdev_path The underlying block device - * @param pwd The password - * @param pwd_len The password length + * @param args->pwd The password + * @param args->pwd_len The password length * * @return Error code (also if no volume could be opened), 0 on success */ @@ -71,10 +69,32 @@ int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) { int64_t dev_size; size_t nr_slices; - size_t vol_idx; - char vmb_key[SFLC_CRYPTO_KEYLEN]; + sflc_DmbCell dmb_cell; + sflc_Vmb vmbs[SFLC_DEV_MAX_VOLUMES]; + size_t dev_id; int err; - + char bdev_path_noslash[SFLC_BDEV_PATH_MAX_LEN + 1]; + char opendev_path[SFLC_BIGBUFSIZE]; + DIR* opendev_dir; + + /* Check if device is already opened and abort if so. */ + /* Step 1: rebuild sysfs directory name of device to be checked. */ + /* TODO: this is duplicate code from close.c we might want to modularize it. */ + /* Remove the slashes from the bdev_path (replace with underscores). */ + strcpy(bdev_path_noslash, args->bdev_path); + sflc_str_replaceAll(bdev_path_noslash, '/', '_'); + /* Build sysfs path of opened device */ + sprintf(opendev_path, "%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_path_noslash); + /* Step 2: check if directory exists. */ + opendev_dir = opendir(opendev_path); + if (opendev_dir) { + /* Directory exists. */ + closedir(opendev_dir); + err = EEXIST; + sflc_log_error("Device %s seems to be already open; error %d", args->bdev_path, err); + return err; + } + /* Get number of slices */ dev_size = sflc_disk_getSize(args->bdev_path); if (dev_size < 0) { @@ -85,21 +105,63 @@ int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) nr_slices = sflc_disk_maxSlices(dev_size); /* Find volume opened by the pwd */ - err = _findVolumeByPwd(args, nr_slices, &vol_idx, vmb_key); + err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); if (err) { - sflc_log_error("Could not find volume opened by given password; error %d", err); + sflc_log_error("Could not read DMB; error %d", err); return err; } - /* Was there one? */ - if (vol_idx >= SFLC_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { sflc_log_error("The provided password opens no volume on the device"); return EINVAL; } printf("Password is correct! Opening volumes...\n"); - /* Open volumes */ - return _openVolumes(args, nr_slices, vol_idx, vmb_key); + /* Unlock VMBs "backwards" */ + int i; // Needs sign, because loop ends on i>=0 + for (i = dmb_cell.vol_idx; i >= 0; i--) { + /* Which VMB key to use? */ + char *vmb_key; + if (i == dmb_cell.vol_idx) { + // The one unlocked by pwd + vmb_key = dmb_cell.vmb_key; + } else { + // Or the prev_vmb_key from last iteration + vmb_key = vmbs[i+1].prev_vmb_key; + } + + /* Read and unlock VMB */ + err = sflc_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); + if (err) { + sflc_log_error("Could not read VMB %d on device %s; error %d", + i, args->bdev_path, err); + return err; + } + } + + /* Get the ID that will be assigned to the block device */ + err = _getNextDevId(&dev_id); + if (err) { + sflc_log_error("Could not get next device ID; error %d", err); + return err; + } + sflc_log_debug("Next device ID is %lu", dev_id); + + /* Open volumes "in order" */ + for (i = 0; i <= dmb_cell.vol_idx; i++) { + err = sflc_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); + if (err) { + sflc_log_error("Could not open volume %d; error %d. " + "Previous volumes on the device might have already " + "been opened, it's recommended you close them", + i, err); + return err; + } + sflc_log_debug("Successfully opened volume %d with VMB key", i); + printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); + } + + return 0; } @@ -107,85 +169,6 @@ int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -/* Finds the volume opened by the given pwd */ -int _findVolumeByPwd(sflc_cmd_OpenArgs *args, size_t nr_slices, size_t *vol_idx, char *vmb_key) -{ - sflc_PartialDeviceMasterBlock dmb; - int err; - - /* Delegate entirely to the function reading the DMB */ - err = sflc_act_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb); - if (err) { - sflc_log_error("Could not read DMB; error %d", err); - return err; - } - - /* Check that a volume was found */ - if (dmb.vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Could not unlock any volumes: wrong password supplied"); - return EINVAL; - } - - /* Copy to output parameters */ - *vol_idx = dmb.vol_idx; - memcpy(vmb_key, dmb.vmb_key, SFLC_CRYPTO_KEYLEN); - - return 0; -} - - -/* Opens the indicated volume with the pwd and the previous ones with the VMB key */ -int _openVolumes(sflc_cmd_OpenArgs *args, size_t nr_slices, size_t vol_idx, char *vmb_key) -{ - sflc_Volume vol; - int err; - - /* Input fields to open a volume */ - vol.bdev_path = args->bdev_path; - vol.nr_slices = nr_slices; - /* Get the ID that will be assigned to the block device */ - err = _getNextDevId(&vol.dev_id); - if (err) { - sflc_log_error("Could not get next device ID; error %d", err); - return err; - } - sflc_log_debug("Next device ID is %lu", vol.dev_id); - - /* Open the last one with the provided vmb_key */ - vol.vol_idx = vol_idx; - memcpy(vol.vmb_key, vmb_key, SFLC_CRYPTO_KEYLEN); - err = sflc_act_openVolume(&vol); - if (err) { - sflc_log_error("Could not open volume %lu with pwd; error %d", vol_idx, err); - return err; - } - sflc_log_debug("Successfully opened most secret volume (%lu) with password", vol_idx); - printf("Opened volume /dev/mapper/sflc_%lu_%lu\n", vol.dev_id, vol_idx); - - /* Loop backwards to open the previous ones */ - int i; - for (i = vol_idx-1; i >= 0; i--) { - size_t idx = (size_t) i; // Looping directly with idx would overflow at the "last" iteration - - /* This volume's VMB key was an output of the last openVolume() */ - memcpy(vol.vmb_key, vol.prev_vmb_key, SFLC_CRYPTO_KEYLEN); - - /* Open this volume with VMB key */ - vol.vol_idx = idx; - err = sflc_act_openVolume(&vol); - if (err) { - sflc_log_error("Could not open volume %lu with VMB key; error %d. " - "Some volumes on the device have already been opened, it's recommended you close them", idx, err); - return err; - } - sflc_log_debug("Successfully opened volume %lu with VMB key", idx); - printf("Opened volume /dev/mapper/sflc-%lu-%lu\n", vol.dev_id, idx); - } - - return 0; -} - - /* Read the next device ID in sysfs */ static int _getNextDevId(size_t *next_dev_id) { diff --git a/shufflecake-userland-legacy/src/actions/close_vol.c b/shufflecake-userland-legacy/src/commands/test_pwd.c similarity index 78% rename from shufflecake-userland-legacy/src/actions/close_vol.c rename to shufflecake-userland-legacy/src/commands/test_pwd.c index 008aaf6..f794347 100644 --- a/shufflecake-userland-legacy/src/actions/close_vol.c +++ b/shufflecake-userland-legacy/src/commands/test_pwd.c @@ -26,18 +26,14 @@ *****************************************************/ #include -#include -#include #include -#include +#include -#include "header/volume_master_block.h" -#include "actions/volume.h" +#include "commands.h" +#include "operations.h" #include "utils/sflc.h" #include "utils/crypto.h" #include "utils/file.h" -#include "utils/string.h" -#include "utils/dm.h" #include "utils/log.h" @@ -46,14 +42,18 @@ *****************************************************/ /** - * Close the volume by issuing the appropriate ioctl to the DM. + * Tests which volume is unlocked by the given password * - * @param label The only needed parameter: the ID of the volume. + * @param args->bdev_path The underlying block device + * @param pwd The password + * @param pwd_len The password length + * + * @output dmb_cell The unlocked DMB cell * * @return Error code, 0 on success */ -int sflc_act_closeVolume(char *label) +int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell) { - /* Issue ioctl */ - return sflc_dm_destroy(label); + /* Delegate entirely to the function reading the DMB */ + return sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); } diff --git a/shufflecake-userland-legacy/src/header/device_master_block.c b/shufflecake-userland-legacy/src/header/device_master_block.c index cfcb7c6..cdd1f8c 100644 --- a/shufflecake-userland-legacy/src/header/device_master_block.c +++ b/shufflecake-userland-legacy/src/header/device_master_block.c @@ -29,7 +29,7 @@ #include #include -#include "header/device_master_block.h" +#include "header.h" #include "utils/crypto.h" #include "utils/log.h" @@ -60,7 +60,7 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool * * @return The error code, 0 on success */ -int sflc_dmb_seal(sflc_CompleteDeviceMasterBlock *dmb, char **pwds, size_t *pwd_lens, char *disk_block) +int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) { char *salt; int err; @@ -84,7 +84,7 @@ int sflc_dmb_seal(sflc_CompleteDeviceMasterBlock *dmb, char **pwds, size_t *pwd_ /* Loop over all VMB keys to encrypt them */ size_t i; for (i = 0; i < dmb->nr_vols; i++) { - char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL); + char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); /* Encrypt it */ err = _encryptVmbKeyWithPwd(salt, pwds[i], pwd_lens[i], dmb->vmb_keys[i], dmb_cell); @@ -105,12 +105,12 @@ int sflc_dmb_seal(sflc_CompleteDeviceMasterBlock *dmb, char **pwds, size_t *pwd_ * @param pwd The password locking the VMB key * @param pwd_len Its length * - * @output dmb->vmb_key The unlocked VMB key - * @output dmb->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vmb_key The unlocked VMB key + * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_PartialDeviceMasterBlock *dmb) +int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell) { // KDF salt char *salt; @@ -131,15 +131,15 @@ int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_PartialDev sflc_log_debug("Successfully derived key-encryption-key with KDF"); /* Init dmb->vol_idx to invalid */ - dmb->vol_idx = SFLC_DEV_MAX_VOLUMES; + dmb_cell->vol_idx = SFLC_DEV_MAX_VOLUMES; /* Try all DMB cells */ size_t i; for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { - char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL); + char *enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); bool match; /* Try to decrypt this one */ - err = _decryptVmbKeyWithPwd(dmb_cell, kek, vmb_key, &match); + err = _decryptVmbKeyWithPwd(enc_dmb_cell, kek, vmb_key, &match); if (err) { sflc_log_error("Error decrypting DMB cell number %lu; error %d", i, err); goto bad_decrypt; @@ -148,8 +148,8 @@ int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_PartialDev /* If MAC matched, mark it, but don't break from the loop (timing attacks) */ if (match) { sflc_log_debug("The provided password unlocks volume %lu", i); - dmb->vol_idx = i; - memcpy(dmb->vmb_key, vmb_key, SFLC_CRYPTO_KEYLEN); + dmb_cell->vol_idx = i; + memcpy(dmb_cell->vmb_key, vmb_key, SFLC_CRYPTO_KEYLEN); } } @@ -164,6 +164,42 @@ bad_kdf: return err; } +/** + * Re-encrypt the content of the specified DMB cell. + * + * @param disk_block The on-disk sealed DMB + * @param dmb_cell The DMB cell to re-encrypt + * @param pwd The new password + * @param pwd_len The password's length + * + * @return Error code, 0 on success + */ +int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len) +{ + char *salt; + char *enc_dmb_cell; + int err; + + /* Sanity check */ + if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + return EINVAL; + } + + /* Pointers inside DMB */ + salt = disk_block; + enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLC_DMB_CELL_SIZE); + /* Encrypt with KDF-derived key */ + err = _encryptVmbKeyWithPwd(salt, pwd, pwd_len, dmb_cell->vmb_key, enc_dmb_cell); + if (err) { + sflc_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); + return err; + } + sflc_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); + + return 0; +} + /***************************************************** * PRIVATE FUNCTIONS PROTOTYPES * diff --git a/shufflecake-userland-legacy/src/header/position_map.c b/shufflecake-userland-legacy/src/header/position_map.c index 8f90c4f..f2b8144 100644 --- a/shufflecake-userland-legacy/src/header/position_map.c +++ b/shufflecake-userland-legacy/src/header/position_map.c @@ -29,7 +29,7 @@ #include #include -#include "header/position_map.h" +#include "header.h" #include "utils/sflc.h" #include "utils/crypto.h" #include "utils/math.h" diff --git a/shufflecake-userland-legacy/src/header/volume_master_block.c b/shufflecake-userland-legacy/src/header/volume_master_block.c index 35fd91f..9347582 100644 --- a/shufflecake-userland-legacy/src/header/volume_master_block.c +++ b/shufflecake-userland-legacy/src/header/volume_master_block.c @@ -30,7 +30,7 @@ #include #include // Network byte order -#include "header/volume_master_block.h" +#include "header.h" #include "utils/crypto.h" #include "utils/string.h" #include "utils/log.h" @@ -41,10 +41,10 @@ *****************************************************/ /* Serialise the VMB before encrypting it */ -static void _serialiseVmb(sflc_VolumeMasterBlock *vmb, char *clear_vmb); +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb); /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflc_VolumeMasterBlock *vmb); +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); /***************************************************** @@ -61,7 +61,7 @@ static int _deserialiseVmb(char *clear_vmb, sflc_VolumeMasterBlock *vmb); * * @return The error code, 0 on success */ -int sflc_vmb_seal(sflc_VolumeMasterBlock *vmb, char *vmb_key, char *disk_block) +int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) { // Pointers inside the block char *iv = disk_block; @@ -123,7 +123,7 @@ bad_clear_alloc: * * @return An error code, 0 on success */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_VolumeMasterBlock *vmb) +int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) { // Pointers inside the block char *iv = disk_block; @@ -177,7 +177,7 @@ bad_clear_alloc: *****************************************************/ /* Serialise the payload before encrypting it */ -static void _serialiseVmb(sflc_VolumeMasterBlock *vmb, char *clear_vmb) +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; @@ -200,7 +200,7 @@ static void _serialiseVmb(sflc_VolumeMasterBlock *vmb, char *clear_vmb) /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflc_VolumeMasterBlock *vmb) +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; diff --git a/shufflecake-userland-legacy/src/main.c b/shufflecake-userland-legacy/src/main.c index 8c541b5..737b57e 100644 --- a/shufflecake-userland-legacy/src/main.c +++ b/shufflecake-userland-legacy/src/main.c @@ -30,7 +30,7 @@ * INCLUDE SECTION * *****************************************************/ -#include "cli/cli.h" +#include "cli.h" /***************************************************** diff --git a/shufflecake-userland-legacy/src/operations/devmapper.c b/shufflecake-userland-legacy/src/operations/devmapper.c new file mode 100644 index 0000000..99a66a2 --- /dev/null +++ b/shufflecake-userland-legacy/src/operations/devmapper.c @@ -0,0 +1,111 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include + +#include "header.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/file.h" +#include "utils/string.h" +#include "utils/dm.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Build parameter list for ctor in dm_sflc, and send DM ioctl to create + * virtual block device. + * + * @param bdev_path The path to the underlying device + * @param dev_id The ID of the underlying block device + * @param vol_idx The index of the volume within the device + * @param vmb Volume metadata + * + * @return Error code, 0 on success + */ +int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb) +{ + char label[SFLC_BIGBUFSIZE]; + char *hex_key; + char params[SFLC_BIGBUFSIZE]; + uint64_t num_sectors; + int err; + + /* Build volume label */ + sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); + + /* Get the hex version of the volume's data section key */ + hex_key = sflc_toHex(vmb->volume_key, SFLC_CRYPTO_KEYLEN); + if (!hex_key) { + sflc_log_error("Could not encode volume key to hexadecimal"); + err = ENOMEM; + goto err_hexkey; + } + + /* Get the number of logical 512-byte sectors composing the volume */ + num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; + + /* Build param list */ + sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); + + /* Issue ioctl */ + err = sflc_dm_create(label, num_sectors, params); + if (err) { + sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); + goto err_dmcreate; + } + err = 0; + + +err_dmcreate: + free(hex_key); +err_hexkey: + return err; +} + + +/** + * Close the volume by issuing the appropriate ioctl to the DM. + * + * @param label The only needed parameter: the ID of the volume. + * + * @return Error code, 0 on success + */ +int sflc_ops_closeVolume(char *label) +{ + /* Issue ioctl */ + return sflc_dm_destroy(label); +} diff --git a/shufflecake-userland-legacy/src/actions/dmb.c b/shufflecake-userland-legacy/src/operations/dmb.c similarity index 64% rename from shufflecake-userland-legacy/src/actions/dmb.c rename to shufflecake-userland-legacy/src/operations/dmb.c index f8da871..d529966 100644 --- a/shufflecake-userland-legacy/src/actions/dmb.c +++ b/shufflecake-userland-legacy/src/operations/dmb.c @@ -31,9 +31,10 @@ #include #include -#include "header/device_master_block.h" -#include "actions/device.h" +#include "header.h" +#include "operations.h" #include "utils/sflc.h" +#include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -43,18 +44,17 @@ *****************************************************/ /** - * Samples VMB keys and writes the corresponding DMB to disk. + * Encrypts and writes the DMB to disk. * * @param bdev_path The path to the underlying block device * @param pwds The array of passwords * @param pwd_lens Their lengths * @param dmb->nr_vols * - * @output dmb->vmb_keys * * @return Error code, 0 on success */ -int sflc_act_createAndWriteDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_CompleteDeviceMasterBlock *dmb) +int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb) { /* On-disk DMB */ char enc_dmb[SFLC_SECTOR_SIZE]; @@ -67,17 +67,7 @@ int sflc_act_createAndWriteDmb(char *bdev_path, char **pwds, size_t *pwd_lens, s return EINVAL; } - /* Sample the VMB keys */ - size_t i; - for (i = 0; i < dmb->nr_vols; i++) { - err = sflc_rand_getStrongBytes(dmb->vmb_keys[i], SFLC_CRYPTO_KEYLEN); - if (err) { - sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); - return err; - } - } - - /* Seal it */ + /* Seal DMB */ err = sflc_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); if (err) { sflc_log_error("Coul dnot seal DMB; error %d", err); @@ -102,16 +92,14 @@ int sflc_act_createAndWriteDmb(char *bdev_path, char **pwds, size_t *pwd_lens, s * @param pwd The user-provided password * @param pwd_len Its length * - * @output dmb->vmb_key The unlocked VMB key - * @output dmb->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vmb_key The unlocked VMB key + * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int sflc_act_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_PartialDeviceMasterBlock *dmb) +int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb) { - /* On-disk DMB */ char enc_dmb[SFLC_SECTOR_SIZE]; - /* Error code */ int err; /* Read DMB from disk (at sector 0) */ @@ -131,3 +119,49 @@ int sflc_act_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_PartialDev return 0; } +/** + * Reads the DMB from disk, changes the relevant DMB cell, and writes it back. + * + * @param bdev_path The path to the underlying block device + * @param dmb_cell The index and vmb_key of the DMB cell to re-encrypt + * @param new_pwd The new password of the DMB cell to re-encrypt + * @param new_pwd_len Its length + * + * @return Error code, 0 on success + */ +int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) +{ + char enc_dmb[SFLC_SECTOR_SIZE]; + int err; + + /* Sanity check */ + if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + return EINVAL; + } + + /* Read DMB from disk (at sector 0) */ + err = sflc_disk_readSector(bdev_path, 0, enc_dmb); + if (err) { + sflc_log_error("Could not read DMB from disk; error %d", err); + return err; + } + + /* Update the relevant cell */ + err = sflc_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); + if (err) { + sflc_log_error("Could not update DMB cell; error %d", err); + return err; + } + + /* Write it to disk (at sector 0) */ + err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); + if (err) { + sflc_log_error("Could not write DMB to disk; error %d", err); + return err; + } + + return 0; +} + + diff --git a/shufflecake-userland-legacy/src/actions/create.c b/shufflecake-userland-legacy/src/operations/volume_header.c similarity index 61% rename from shufflecake-userland-legacy/src/actions/create.c rename to shufflecake-userland-legacy/src/operations/volume_header.c index f04486f..1088290 100644 --- a/shufflecake-userland-legacy/src/actions/create.c +++ b/shufflecake-userland-legacy/src/operations/volume_header.c @@ -30,10 +30,11 @@ #include #include -#include "header/position_map.h" -#include "header/volume_master_block.h" -#include "actions/volume.h" +#include "header.h" +#include "header.h" +#include "operations.h" #include "utils/sflc.h" +#include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -43,51 +44,32 @@ *****************************************************/ /** - * Writes a volume header (VMB+PM) on-disk. Also fills the vmb_key and volume_key. - * Some of the fields in the struct are input, some are output. + * Writes a volume header (VMB+PM) on-disk. * - * @param pwd The volume password - * @param pwd_len The password length - * @param prev_vmb_key The previous volume's VMB key - * @param nr_slices The number of logical slices of the volume(s) - * @param vol_idx The index of the volume within the device * @param bdev_path The underlying block device to write the volume header - * - * @output vmb_key This volume's VMB key - * @output volume_key This volume's data section key - * - * @unused label + * @param vmb_key The key to encrypt the VMB + * @param vmb The VMB to encrypt + * @param vol_idx The index of the volume within the device * * @return Error code, 0 on success */ -int sflc_act_createVolume(sflc_Volume *vol) +int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) { - sflc_VolumeMasterBlock vmb; char enc_vmb[SFLC_SECTOR_SIZE]; sflc_EncPosMap epm; uint64_t sector; int err; - // Sample keys - sflc_rand_getWeakBytes(vol->vmb_key, SFLC_CRYPTO_KEYLEN); - sflc_rand_getWeakBytes(vol->volume_key, SFLC_CRYPTO_KEYLEN); - - // Fill VMB - memcpy(vmb.vmb_key, vol->vmb_key, SFLC_CRYPTO_KEYLEN); - memcpy(vmb.volume_key, vol->volume_key, SFLC_CRYPTO_KEYLEN); - memcpy(vmb.prev_vmb_key, vol->prev_vmb_key, SFLC_CRYPTO_KEYLEN); - vmb.nr_slices = vol->nr_slices; - - // Encrypt it - err = sflc_vmb_seal(&vmb, vol->pwd, vol->pwd_len, enc_vmb); + // Encrypt VMB + err = sflc_vmb_seal(vmb, vmb_key, enc_vmb); if (err) { sflc_log_error("Could not seal VMB; error %d", err); goto out; } // Write it to disk - sector = sflc_vmbPosition(vol); - err = sflc_disk_writeSector(vol->bdev_path, sector, enc_vmb); + sector = sflc_vmbPosition(vol_idx, vmb->nr_slices); + err = sflc_disk_writeSector(bdev_path, sector, enc_vmb); if (err) { sflc_log_error("Could not write VMB to disk; error %d", err); goto out; @@ -95,13 +77,13 @@ int sflc_act_createVolume(sflc_Volume *vol) sector += 1; // Create encrypted empty position map - err = sflc_epm_create(vol->nr_slices, vol->volume_key, &epm); + err = sflc_epm_create(vmb->nr_slices, vmb->volume_key, &epm); if (err) { sflc_log_error("Could not create encrypted empty position map; error %d", err); goto out; } - // Loop over PMB arrays to write it to disk + // Loop over PMB arrays to write them to disk int i; for (i = 0; i < epm.nr_arrays; i++) { char *iv_block = epm.iv_blocks[i]; @@ -109,7 +91,7 @@ int sflc_act_createVolume(sflc_Volume *vol) size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); // First write the IV block - err = sflc_disk_writeSector(vol->bdev_path, sector, iv_block); + err = sflc_disk_writeSector(bdev_path, sector, iv_block); if (err) { sflc_log_error("Could not write IV block to disk; error %d", err); goto out; @@ -117,7 +99,7 @@ int sflc_act_createVolume(sflc_Volume *vol) sector += 1; // Then the whole PMB array - err = sflc_disk_writeManySectors(vol->bdev_path, sector, pmb_array, nr_pmbs); + err = sflc_disk_writeManySectors(bdev_path, sector, pmb_array, nr_pmbs); if (err) { sflc_log_error("Could not write PMB array to disk; error %d", err); goto out; @@ -137,3 +119,47 @@ int sflc_act_createVolume(sflc_Volume *vol) out: return err; } + + +/** + * Reads a VMB from disk and unlocks it + * + * @param bdev_path The underlying block device + * @param vmb_key The key to decrypt the VMB + * @param nr_slices The number of slices in the device + * @param vol_idx The index of the volume within the device + * + * @output vmb The decrypted VMB + * + * @return Error code, 0 on success + */ +int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) +{ + char enc_vmb[SFLC_SECTOR_SIZE]; + uint64_t sector; + int err; + + /* Read encrypted VMB from disk */ + sector = sflc_vmbPosition(vol_idx, nr_slices); + err = sflc_disk_readSector(bdev_path, sector, enc_vmb); + if (err) { + sflc_log_error("Could not read VMB from disk; error %d", err); + return err; + } + + /* Unseal it */ + err = sflc_vmb_unseal(enc_vmb, vmb_key, vmb); + if (err) { + sflc_log_error("Could not unseal VMB; error %d", err); + return err; + } + + /* Compare the number of slices */ + if (nr_slices != vmb->nr_slices) { + sflc_log_error("Incompatible header size: the device size was different when the volumes" + "were created. Did you resize the device %s since last time?", bdev_path); + return EINVAL; + } + + return 0; +} diff --git a/shufflecake-userland-legacy/src/utils/input.c b/shufflecake-userland-legacy/src/utils/input.c index 7174ca5..ffc0b02 100644 --- a/shufflecake-userland-legacy/src/utils/input.c +++ b/shufflecake-userland-legacy/src/utils/input.c @@ -92,6 +92,9 @@ int sflc_safeReadPassphrase(char *buf, size_t bufsize) buf[len - 1] = '\0'; } + /* Newline on screen */ + printf("\n"); + return 0; } diff --git a/shufflecake-userland-legacy/test/actions/test_actions.h b/shufflecake-userland-legacy/test/actions/test_actions.h deleted file mode 100644 index aae2e00..0000000 --- a/shufflecake-userland-legacy/test/actions/test_actions.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - - -#ifndef _TEST_ACTIONS_H_ -#define _TEST_ACTIONS_H_ - - -/***************************************************** - * PUBLIC FUNCTIONS DECLARATIONS * - *****************************************************/ - -// Exported test cases - -char *test_vol_create(); - -char *test_vol_allActions(); - -#endif /* _TEST_ACTIONS_H_ */ diff --git a/shufflecake-userland-legacy/test/actions/test_all_actions.c b/shufflecake-userland-legacy/test/actions/test_all_actions.c deleted file mode 100644 index d1b7af7..0000000 --- a/shufflecake-userland-legacy/test/actions/test_all_actions.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "utils/disk.h" -#include "utils/crypto.h" -#include "actions/volume.h" -#include "test_actions.h" -#include "minunit.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define DUMMY_PWD "lolololol" -#define WRONG_PWD "yeyeyeyeye" -#define MAX_BDEV_PATH_LEN 100 - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -char *test_vol_allActions() -{ - sflc_Volume vol; - char bdev_path[MAX_BDEV_PATH_LEN + 1]; - char label[SFLC_MAX_VOL_NAME_LEN + 1]; - int64_t dev_size; - size_t nr_slices; - bool match; - int err; - - sflc_log_blue("Testing all volume operations (needs sudo privileges and dm-sflc loaded)"); - - // Get bdev_path or terminate - printf("Type path of underlying block device (empty to skip test case): "); - fgets(bdev_path, MAX_BDEV_PATH_LEN, stdin); - bdev_path[strlen(bdev_path) - 1] = '\0'; // Discard newline - if (strlen(bdev_path) == 0) { - sflc_log_yellow("Skipping test case"); - return NULL; - } - // Get vol_idx - printf("Type index of volume within the device: "); - scanf("%lu", &vol.vol_idx); - - // Get device info - dev_size = sflc_disk_getSize(bdev_path); - mu_assert("Error reading device size", dev_size > 0); - nr_slices = sflc_disk_maxSlices(dev_size); - sflc_log_yellow("Device has %ld blocks, corresponding to %lu logical slices", dev_size, nr_slices); - - // Fill input fields in volume - vol.bdev_path = bdev_path; - vol.nr_slices = nr_slices; - vol.pwd = DUMMY_PWD; - vol.pwd_len = strlen(DUMMY_PWD); - memset(vol.prev_vmb_key, 0, SFLC_CRYPTO_KEYLEN); - - // Create volume - err = sflc_act_createVolume(&vol); - mu_assert("Error creating volume", !err); - - // Check with the wrong password - vol.pwd = WRONG_PWD; - vol.pwd_len = strlen(WRONG_PWD); - err = sflc_act_checkPwd(&vol, &match); - mu_assert("Error checking wrong volume password", !err); - mu_assert("Wrong password unexpectedly manages to open volume", !match); - - // Check with the right password - vol.pwd = DUMMY_PWD; - vol.pwd_len = strlen(DUMMY_PWD); - err = sflc_act_checkPwd(&vol, &match); - mu_assert("Error checking right volume password", !err); - mu_assert("Correct password doesn't open volume", match); - - // Actually open it (using the pwd) - err = sflc_act_openVolumeWithPwd(&vol); - mu_assert("Error opening volume with password", !err); - - // Close it (hack: label is known) - sprintf(label, "sflc-0-%lu", vol.vol_idx); - err = sflc_act_closeVolume(label); - mu_assert("Error closing volume (opened with pwd)", !err); - - // Open it again (using the key) - err = sflc_act_openVolumeWithKey(&vol); - mu_assert("Error opening volume with key", !err); - - // Close it again - err = sflc_act_closeVolume(label); - mu_assert("Error closing volume (opened with key)", !err); - - sflc_log_green("Test case finished, manually check the results"); - - return NULL; -} diff --git a/shufflecake-userland-legacy/test/actions/test_create.c b/shufflecake-userland-legacy/test/actions/test_create.c deleted file mode 100644 index 3cbc198..0000000 --- a/shufflecake-userland-legacy/test/actions/test_create.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "utils/disk.h" -#include "utils/crypto.h" -#include "actions/volume.h" -#include "test_actions.h" -#include "minunit.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define DUMMY_PWD "lolololol" -#define MAX_BDEV_PATH_LEN 100 - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -char *test_vol_create() -{ - sflc_Volume vol; - char bdev_path[MAX_BDEV_PATH_LEN + 1]; - int64_t dev_size; - size_t nr_slices; - int err; - - sflc_log_blue("Testing volume creation"); - - // Get bdev_path or terminate - printf("Type path of underlying block device (empty to skip test case): "); - fgets(bdev_path, MAX_BDEV_PATH_LEN, stdin); - bdev_path[strlen(bdev_path) - 1] = '\0'; // Discard newline - if (strlen(bdev_path) == 0) { - sflc_log_yellow("Skipping test case"); - return NULL; - } - // Get vol_idx - printf("Type index of volume within the device: "); - scanf("%lu", &vol.vol_idx); - - // Get device info - dev_size = sflc_disk_getSize(bdev_path); - mu_assert("Error reading device size", dev_size > 0); - nr_slices = sflc_disk_maxSlices(dev_size); - sflc_log_yellow("Device has %ld blocks, corresponding to %lu logical slices", dev_size, nr_slices); - - // Fill input fields in volume - vol.bdev_path = bdev_path; - vol.nr_slices = nr_slices; - vol.pwd = DUMMY_PWD; - vol.pwd_len = strlen(DUMMY_PWD); - memset(vol.prev_vmb_key, 0, SFLC_CRYPTO_KEYLEN); - - // Create volume - err = sflc_act_createVolume(&vol); - mu_assert("Error creating volume", !err); - - // Log output keys - sflc_log_yellow("Output vmb_key:"); - sflc_log_hex(vol.vmb_key, SFLC_CRYPTO_KEYLEN); - sflc_log_yellow("Output volume_key:"); - sflc_log_hex(vol.volume_key, SFLC_CRYPTO_KEYLEN); - - sflc_log_green("Test case finished, manually check the results"); - - return NULL; -} diff --git a/shufflecake-userland-legacy/test/commands/test_commands.h b/shufflecake-userland-legacy/test/commands/test_commands.h deleted file mode 100644 index 450f22e..0000000 --- a/shufflecake-userland-legacy/test/commands/test_commands.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _TEST_COMMANDS_H_ -#define _TEST_COMMANDS_H_ - - -/***************************************************** - * PUBLIC FUNCTIONS DECLARATIONS * - *****************************************************/ - -// Exported test cases - -char *test_cmd_init(); - -#endif /* _TEST_COMMANDS_H_ */ diff --git a/shufflecake-userland-legacy/test/commands/test_init.c b/shufflecake-userland-legacy/test/commands/test_init.c deleted file mode 100644 index b60f5d4..0000000 --- a/shufflecake-userland-legacy/test/commands/test_init.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "utils/disk.h" -#include "utils/crypto.h" -#include "commands/commands.h" -#include "test_commands.h" -#include "minunit.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define MAX_BDEV_PATH_LEN 100 -#define MAX_PWD_LEN 40 - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -char *test_cmd_init() -{ - sflc_cmd_InitArgs args; - char bdev_path[MAX_BDEV_PATH_LEN + 2]; - size_t nr_vols; - char pwds[SFLC_DEV_MAX_VOLUMES][MAX_PWD_LEN + 2]; - size_t pwd_lens[SFLC_DEV_MAX_VOLUMES]; - int err; - - sflc_log_blue("Testing volume creation"); - - /* Get bdev_path or terminate */ - printf("Type path of underlying block device (empty to skip test case): "); - err = sflc_safeReadLine(bdev_path, sizeof(bdev_path)); - mu_assert("Could not read path to underlying device", !err); - /* Terminate if empty input */ - if (strlen(bdev_path) == 0) { - sflc_log_yellow("Skipping test case"); - return NULL; - } - args.bdev_path = bdev_path; - - /* Get number of volumes */ - printf("How many volumes do you want to create?"); - mu_assert("Could not read number of volumes", scanf("%u", &nr_vols) == 1); - mu_assert("Number of volumes out of bounds", nr_vols <= SFLC_DEV_MAX_VOLUMES); - - /* Get passwords */ - size_t i; - for (i = 0; ) - - sflc_log_green("Test case finished, manually check the results"); - - return NULL; -} From e8c8cfb74d244aa8c7dc089928f2245314699f4d Mon Sep 17 00:00:00 2001 From: = Date: Sat, 3 Aug 2024 22:52:27 +0200 Subject: [PATCH 62/75] Upgrade legacy to new DM interface --- .../include/utils/sflc.h | 4 ++ .../src/commands/close.c | 72 +++++++++++-------- .../src/operations/devmapper.c | 2 +- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/shufflecake-userland-legacy/include/utils/sflc.h b/shufflecake-userland-legacy/include/utils/sflc.h index e8135e4..326aac8 100644 --- a/shufflecake-userland-legacy/include/utils/sflc.h +++ b/shufflecake-userland-legacy/include/utils/sflc.h @@ -33,6 +33,8 @@ * INCLUDE SECTION * *****************************************************/ +#include + /***************************************************** * CONSTANTS * @@ -78,6 +80,8 @@ #define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" /* Within each bdev's subdir, this file lists its open volumes */ #define SFLC_SYSFS_OPENVOLUMES_FILENAME "volumes" +/* Within each bdev's subdir, this file shows its Shufflecake device ID */ +#define SFLC_SYSFS_DEVID_FILENAME "dev_id" /* TODO: reasonable? */ #define SFLC_BDEV_PATH_MAX_LEN 1024 diff --git a/shufflecake-userland-legacy/src/commands/close.c b/shufflecake-userland-legacy/src/commands/close.c index 4c180f6..73a7605 100644 --- a/shufflecake-userland-legacy/src/commands/close.c +++ b/shufflecake-userland-legacy/src/commands/close.c @@ -35,6 +35,7 @@ #include "utils/crypto.h" #include "utils/string.h" #include "utils/file.h" +#include "utils/disk.h" #include "utils/log.h" @@ -43,7 +44,7 @@ *****************************************************/ /* Reads the list of volumes from sysfs */ -static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols); +static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols); /* Close them all (in reverse order of opening) */ static int _closeVolumes(char **labels, size_t nr_vols); @@ -77,7 +78,7 @@ int sflc_cmd_closeVolumes(char *bdev_path) } /* Read them */ - err = _readVolumesList(bdev_path, labels, &nr_vols); + err = _buildVolumesList(bdev_path, labels, &nr_vols); if (err) { sflc_log_error("Could not read volume list from sysfs; error %d", err); goto out; @@ -106,31 +107,50 @@ out: * PRIVATE FUNCTIONS PROTOTYPES * *****************************************************/ -/* Reads the list of volumes from sysfs */ -static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) +/* Reads from sysfs to build the volumes list */ +static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols) { - char bdev_path_noslash[SFLC_BDEV_PATH_MAX_LEN + 1]; - char openvolumes_path[SFLC_BIGBUFSIZE]; - char *str_openvolumes; + char *bdev_name; + char devid_path[SFLC_BIGBUFSIZE]; + char *str_devid; + size_t dev_id; + char nrvolumes_path[SFLC_BIGBUFSIZE]; + char *str_nrvolumes; - /* Remove the slashes from the bdev_path (replace with underscores) */ - strcpy(bdev_path_noslash, bdev_path); - sflc_str_replaceAll(bdev_path_noslash, '/', '_'); - /* Build path to sysfsy file containing open volumes list */ - sprintf(openvolumes_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_path_noslash, SFLC_SYSFS_OPENVOLUMES_FILENAME); + /* Get device name as : */ + bdev_name = sflc_disk_getDeviceName(bdev_path); + if(!bdev_name) { + sflc_log_error("Could not allocate device name"); + return ENOMEM; + } + /* Build path to sysfs file containing device ID */ + sprintf(devid_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name, SFLC_SYSFS_DEVID_FILENAME); + /* Build path to sysfs file containing number of open volumes */ + sprintf(nrvolumes_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name, SFLC_SYSFS_OPENVOLUMES_FILENAME); - /* Read the sysfs file */ - str_openvolumes = sflc_readFile(openvolumes_path); - if (!str_openvolumes) { - sflc_log_error("Could not read file %s", openvolumes_path); + /* Read the device ID */ + str_devid = sflc_readFile(devid_path); + if (!str_devid) { + sflc_log_error("Could not read file %s", devid_path); + return EBADF; + } + /* Parse the device ID */ + if (sscanf(str_devid, "%lu", &dev_id) != 1) { + sflc_log_error("Could not parse device ID:\n%s", str_devid); return EBADF; } + /* Read the number of volumes */ + str_nrvolumes = sflc_readFile(nrvolumes_path); + if (!str_nrvolumes) { + sflc_log_error("Could not read file %s", nrvolumes_path); + return EBADF; + } /* Parse the number of volumes */ - char *endptr; - *nr_vols = strtoul(str_openvolumes, &endptr, 10); - /* Skip past the number of volumes (lands on a whitespace before the first label) */ - str_openvolumes = endptr; + if (sscanf(str_nrvolumes, "%lu", nr_vols) != 1) { + sflc_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); + return EBADF; + } /* Just to be sure */ if (*nr_vols > SFLC_DEV_MAX_VOLUMES) { @@ -138,18 +158,10 @@ static int _readVolumesList(char *bdev_path, char **labels, size_t *nr_vols) return EBADF; } - /* Read labels */ + /* Build labels */ size_t i; for (i = 0; i < *nr_vols; i++) { - /* Trust the content of the sysfs file */ - if (sscanf(str_openvolumes, " %s", labels[i]) != 1) { - sflc_log_error("Could not read volume label %lu. Sysfs content:\n%s", i, str_openvolumes); - return EBADF; - } - sflc_log_debug("Label %lu to close: %s", i, labels[i]); - - /* Skip past the whitespace and the label */ - str_openvolumes += 1 + strlen(labels[i]); + sprintf(labels[i], "sflc_%lu_%lu", dev_id, i); } return 0; diff --git a/shufflecake-userland-legacy/src/operations/devmapper.c b/shufflecake-userland-legacy/src/operations/devmapper.c index 99a66a2..a1bec5a 100644 --- a/shufflecake-userland-legacy/src/operations/devmapper.c +++ b/shufflecake-userland-legacy/src/operations/devmapper.c @@ -79,7 +79,7 @@ int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; /* Build param list */ - sprintf(params, "%s %lu %lu %s", bdev_path, vol_idx, vmb->nr_slices, hex_key); + sprintf(params, "%d %lu %s %lu %lu %s", SFLC_MODE_LEGACY, dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); /* Issue ioctl */ err = sflc_dm_create(label, num_sectors, params); From 751f54f02804e647c73356d9795e028d0ab20154 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 3 Aug 2024 23:06:33 +0200 Subject: [PATCH 63/75] Everything in order --- shufflecake-userland-legacy/Makefile | 4 +-- .../include/utils/disk.h | 2 ++ .../include/utils/sflc.h | 2 +- shufflecake-userland-legacy/src/utils/disk.c | 26 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/shufflecake-userland-legacy/Makefile b/shufflecake-userland-legacy/Makefile index ee59323..e8598dc 100644 --- a/shufflecake-userland-legacy/Makefile +++ b/shufflecake-userland-legacy/Makefile @@ -61,10 +61,10 @@ DEPS := $(PROJ_DEPS) $(TEST_DEPS) DIRS := $(sort $(dir $(BIN_DIR) $(PROJ_OBJS) $(TEST_OBJS) $(PROJ_DEPS) $(TEST_DEPS))) # The target binaries -MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake +MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake-legacy TEST_BIN := $(TEST_OUT_DIR)/tests # Their symlink -MAIN_LINK := shufflecake +MAIN_LINK := shufflecake-legacy TEST_LINK := tests diff --git a/shufflecake-userland-legacy/include/utils/disk.h b/shufflecake-userland-legacy/include/utils/disk.h index 7666609..16885e3 100644 --- a/shufflecake-userland-legacy/include/utils/disk.h +++ b/shufflecake-userland-legacy/include/utils/disk.h @@ -88,6 +88,8 @@ * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ +char *sflc_disk_getDeviceName(char *bdev_path); + /* Checks whether the given path points to a block device */ bool sflc_disk_isBlockDevice(char *path); diff --git a/shufflecake-userland-legacy/include/utils/sflc.h b/shufflecake-userland-legacy/include/utils/sflc.h index 326aac8..4bab1ba 100644 --- a/shufflecake-userland-legacy/include/utils/sflc.h +++ b/shufflecake-userland-legacy/include/utils/sflc.h @@ -75,7 +75,7 @@ #define SFLC_EPM_FILLER 0xFF /* The sysfs file containing the next available device ID */ -#define SFLC_SYSFS_NEXTDEVID "/sys/devices/sflc/next_dev_id" +#define SFLC_SYSFS_NEXTDEVID "/sys/module/dm_sflc/next_dev_id" /* The sysfs directory containing a subdir for each (underlying) block device */ #define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" /* Within each bdev's subdir, this file lists its open volumes */ diff --git a/shufflecake-userland-legacy/src/utils/disk.c b/shufflecake-userland-legacy/src/utils/disk.c index 2f78598..c37711a 100644 --- a/shufflecake-userland-legacy/src/utils/disk.c +++ b/shufflecake-userland-legacy/src/utils/disk.c @@ -30,11 +30,13 @@ *****************************************************/ #include +#include #include #include #include #include #include +#include #include #include @@ -42,10 +44,34 @@ #include "utils/log.h" + /***************************************************** * PUBLIC FUNCTIONS DEFINITIONS * *****************************************************/ +/** + * Returns a malloc'ed string formatted as : + * + * @param bdev_path The path to the block device + * + * @return A string version of the device ID + */ +char *sflc_disk_getDeviceName(char *bdev_path) +{ + struct stat sb; + char *dev_name; + + if (stat(bdev_path, &sb) != 0) + return NULL; + dev_name = malloc(SFLC_BIGBUFSIZE); + if (!dev_name) + return NULL; + + sprintf(dev_name, "%u:%u", major(sb.st_rdev), minor(sb.st_rdev)); + + return dev_name; +} + /** * Checks whether the given path points to a block device. From 748329c46a55d955a85e44541d96bbced22cbf6b Mon Sep 17 00:00:00 2001 From: = Date: Thu, 22 Aug 2024 23:22:08 +0200 Subject: [PATCH 64/75] Unify utils/ --- .../include/utils/crypto.h | 42 ++--- .../include/utils/disk.h | 25 ++- shufflecake-userland-lite/include/utils/dm.h | 6 +- .../include/utils/file.h | 2 +- .../include/utils/input.h | 6 +- shufflecake-userland-lite/include/utils/log.h | 80 +++++----- .../include/utils/{sflite.h => sflc.h} | 42 ++--- .../include/utils/string.h | 4 +- shufflecake-userland-lite/src/utils/crypto.c | 148 +++++++++--------- shufflecake-userland-lite/src/utils/disk.c | 56 +++---- shufflecake-userland-lite/src/utils/dm.c | 56 +++---- shufflecake-userland-lite/src/utils/file.c | 2 +- shufflecake-userland-lite/src/utils/input.c | 8 +- shufflecake-userland-lite/src/utils/string.c | 6 +- 14 files changed, 246 insertions(+), 237 deletions(-) rename shufflecake-userland-lite/include/utils/{sflite.h => sflc.h} (72%) diff --git a/shufflecake-userland-lite/include/utils/crypto.h b/shufflecake-userland-lite/include/utils/crypto.h index 84be972..8366134 100644 --- a/shufflecake-userland-lite/include/utils/crypto.h +++ b/shufflecake-userland-lite/include/utils/crypto.h @@ -33,7 +33,7 @@ #include #include -#include "utils/sflite.h" +#include "utils/sflc.h" /***************************************************** @@ -41,41 +41,41 @@ *****************************************************/ // Key length, for input into AES-CTR and AES-GCM, and for output from Argon -#define SFLITE_STANDARD_KEYLEN 32 /* bytes */ +#define SFLC_STANDARD_KEYLEN 32 /* bytes */ // Key length for AES-XTS -#define SFLITE_AESXTS_KEYLEN 64 /* bytes */ +#define SFLC_AESXTS_KEYLEN 64 /* bytes */ // IV length for AES-CTR -#define SFLITE_AESCTR_IVLEN 16 /* bytes */ +#define SFLC_AESCTR_IVLEN 16 /* bytes */ // IV length for AES-XTS -#define SFLITE_AESXTS_IVLEN 16 /* bytes */ +#define SFLC_AESXTS_IVLEN 16 /* bytes */ // IV length for AES-GCM -#define SFLITE_AESGCM_IVLEN 12 /* bytes */ +#define SFLC_AESGCM_IVLEN 12 /* bytes */ // IVs occupy 16 bytes on-disk, but only the *FIRST* 12 are used for AES-GCM -#define SFLITE_AESGCM_PADDED_IVLEN 16 /* bytes */ +#define SFLC_AESGCM_PADDED_IVLEN 16 /* bytes */ // MAC length for AES-GCM -#define SFLITE_AESGCM_TAGLEN 16 /* bytes */ +#define SFLC_AESGCM_TAGLEN 16 /* bytes */ // Content of output plaintext upon MAC verification failure -#define SFLITE_AESGCM_POISON_PT 0xFF +#define SFLC_AESGCM_POISON_PT 0xFF /* Argon parameters */ // Argon salt length -#define SFLITE_ARGON_SALTLEN 16 /* bytes */ +#define SFLC_ARGON_SALTLEN 16 /* bytes */ // Argon memory parameter // We assume machines with at least 128 MiB available RAM, so 2^17 kiB -#define SFLITE_ARGON_M (1 << 17) /* kibibytes */ +#define SFLC_ARGON_M (1 << 17) /* kibibytes */ // Argon iterations count // We aim for 1-2 seconds on a low-end laptop or mobile (it's a one-time operation) -#define SFLITE_ARGON_T 3 +#define SFLC_ARGON_T 3 // Argon parallelism parameter (recommended to be 2 * CPU cores) // We assume use even on single core devices -#define SFLITE_ARGON_P 2 +#define SFLC_ARGON_P 2 /***************************************************** @@ -83,26 +83,26 @@ *****************************************************/ /* Get slow, strong random bytes (suited for keys) */ -int sflite_rand_getStrongBytes(char *buf, size_t buflen); +int sflc_rand_getStrongBytes(char *buf, size_t buflen); /* Get fast, weak(er) random bytes (suited for IVs and padding) */ -int sflite_rand_getWeakBytes(char *buf, size_t buflen); +int sflc_rand_getWeakBytes(char *buf, size_t buflen); /* AES256-CTR encryption, does not touch the IV. Set ct = NULL for in-place. */ -int sflite_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-CTR decryption, does not touch the IV. Set pt = NULL for in-place. */ -int sflite_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); +int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); /* AES256-XTS encryption. Set ct = NULL for in-place. * The IV is intepreted as a little-endian "sector number" */ -int sflite_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); +int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); /* AES256-GCM encryption, does not touch the IV */ -int sflite_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); +int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); /* AES256-GCM decryption, does not touch the IV (only decrypts if MAC is valid) */ -int sflite_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); +int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); /* Compute Argon KDF */ -int sflite_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); +int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); #endif /* _UTILS_CRYPTO_H_ */ diff --git a/shufflecake-userland-lite/include/utils/disk.h b/shufflecake-userland-lite/include/utils/disk.h index f2cc8b5..56256c4 100644 --- a/shufflecake-userland-lite/include/utils/disk.h +++ b/shufflecake-userland-lite/include/utils/disk.h @@ -36,7 +36,7 @@ #include #include "utils/math.h" -#include "utils/sflite.h" +#include "utils/sflc.h" /***************************************************** @@ -44,7 +44,7 @@ *****************************************************/ /** - * Max slices for given disk size (in 4096-byte blocks). + * Max slices for given disk size (in 4096-byte blocks). LITE version */ static inline uint32_t sflite_disk_maxSlices(uint64_t size) { uint64_t nr_slices; @@ -67,28 +67,37 @@ static inline uint32_t sflite_disk_maxSlices(uint64_t size) { return nr_slices > SFLITE_MAX_SLICES ? SFLITE_MAX_SLICES : (uint32_t) nr_slices; } +/* LEGACY version */ +#define sfold_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFLC_BLOCKS_PER_PHYS_SLICE) +/* We need this inequality to hold, in order for the previous bound to be true */ +#if SFLC_DEV_MAX_VOLUMES * 2 > SFLC_SLICE_IDX_PER_BLOCK +#error "Invalid combination of parameters, probably SFLC_DEV_MAX_VOLUMES is too big" +#endif + + + /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ /* Returns a malloc'ed string formatted as : */ -char *sflite_disk_getDeviceName(char *bdev_path); +char *sflc_disk_getDeviceName(char *bdev_path); /* Checks whether the given path points to a block device */ -bool sflite_disk_isBlockDevice(char *path); +bool sflc_disk_isBlockDevice(char *path); /* Returns the size in 4096-byte sectors (or < 0 if error) */ -int64_t sflite_disk_getSize(char *bdev_path); +int64_t sflc_disk_getSize(char *bdev_path); /* Reads a single 4096-byte block from the disk */ -int sflite_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); +int sflc_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); /* Writes many 4096-byte blocks to the disk */ -int sflite_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); +int sflc_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); /* Writes a single 4096-byte block to the disk */ -#define sflite_disk_writeBlock(bdev_path, bnum, buf) sflite_disk_writeManyBlocks(bdev_path, bnum, buf, 1) +#define sflc_disk_writeBlock(bdev_path, bnum, buf) sflite_disk_writeManyBlocks(bdev_path, bnum, buf, 1) #endif /* _UTILS_DISK_H_ */ diff --git a/shufflecake-userland-lite/include/utils/dm.h b/shufflecake-userland-lite/include/utils/dm.h index ba27afb..3334852 100644 --- a/shufflecake-userland-lite/include/utils/dm.h +++ b/shufflecake-userland-lite/include/utils/dm.h @@ -35,7 +35,7 @@ #include -#include "utils/sflite.h" +#include "utils/sflc.h" /***************************************************** @@ -48,9 +48,9 @@ *****************************************************/ /* Create a new Shufflecake virtual device (volume) under /dev/mapper */ -int sflite_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); +int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); /* Destroy the virtual device under /dev/mapper */ -int sflite_dm_destroy(char * virt_dev_name); +int sflc_dm_destroy(char * virt_dev_name); #endif /* _UTILS_DM_H_ */ diff --git a/shufflecake-userland-lite/include/utils/file.h b/shufflecake-userland-lite/include/utils/file.h index 2346ee6..fb03078 100644 --- a/shufflecake-userland-lite/include/utils/file.h +++ b/shufflecake-userland-lite/include/utils/file.h @@ -30,7 +30,7 @@ *****************************************************/ /* Malloc's the buffer for the file contents */ -char *sflite_readFile(char *path); +char *sflc_readFile(char *path); #endif /* _UTILS_FILE_H_ */ diff --git a/shufflecake-userland-lite/include/utils/input.h b/shufflecake-userland-lite/include/utils/input.h index 5c54850..52e07fb 100644 --- a/shufflecake-userland-lite/include/utils/input.h +++ b/shufflecake-userland-lite/include/utils/input.h @@ -30,7 +30,7 @@ *****************************************************/ /* Clear a line from stdin, to use after a failed scanf (it didn't actually read input) */ -#define sflite_ignoreLine() scanf("%*[^\n]") +#define sflc_ignoreLine() scanf("%*[^\n]") /***************************************************** @@ -38,9 +38,9 @@ *****************************************************/ /* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int sflite_safeReadLine(char *buf, size_t bufsize); +int sflc_safeReadLine(char *buf, size_t bufsize); /* Reads a password or passphrase (discarding the newline) from stdin in a secure way (no echo) */ -int sflite_safeReadPassphrase(char *buf, size_t bufsize); +int sflc_safeReadPassphrase(char *buf, size_t bufsize); #endif /* _UTILS_INPUT_H_ */ diff --git a/shufflecake-userland-lite/include/utils/log.h b/shufflecake-userland-lite/include/utils/log.h index 5b15ea5..0fd35d7 100644 --- a/shufflecake-userland-lite/include/utils/log.h +++ b/shufflecake-userland-lite/include/utils/log.h @@ -37,29 +37,29 @@ *****************************************************/ // Printf colours (regular text) -#define SFLITE_LOG_BLK "\033[0;30m" -#define SFLITE_LOG_RED "\033[0;31m" -#define SFLITE_LOG_GRN "\033[0;32m" -#define SFLITE_LOG_YEL "\033[0;33m" -#define SFLITE_LOG_BLU "\033[0;34m" -#define SFLITE_LOG_MAG "\033[0;35m" -#define SFLITE_LOG_CYN "\033[0;36m" -#define SFLITE_LOG_WHT "\033[0;37m" +#define SFLC_LOG_BLK "\033[0;30m" +#define SFLC_LOG_RED "\033[0;31m" +#define SFLC_LOG_GRN "\033[0;32m" +#define SFLC_LOG_YEL "\033[0;33m" +#define SFLC_LOG_BLU "\033[0;34m" +#define SFLC_LOG_MAG "\033[0;35m" +#define SFLC_LOG_CYN "\033[0;36m" +#define SFLC_LOG_WHT "\033[0;37m" // Printf colours (bold text) -#define SFLITE_LOG_BBLK "\033[1;30m" -#define SFLITE_LOG_BRED "\033[1;31m" -#define SFLITE_LOG_BGRN "\033[1;32m" -#define SFLITE_LOG_BYEL "\033[1;33m" -#define SFLITE_LOG_BBLU "\033[1;34m" -#define SFLITE_LOG_BMAG "\033[1;35m" -#define SFLITE_LOG_BCYN "\033[1;36m" -#define SFLITE_LOG_BWHT "\033[1;37m" +#define SFLC_LOG_BBLK "\033[1;30m" +#define SFLC_LOG_BRED "\033[1;31m" +#define SFLC_LOG_BGRN "\033[1;32m" +#define SFLC_LOG_BYEL "\033[1;33m" +#define SFLC_LOG_BBLU "\033[1;34m" +#define SFLC_LOG_BMAG "\033[1;35m" +#define SFLC_LOG_BCYN "\033[1;36m" +#define SFLC_LOG_BWHT "\033[1;37m" // Reset colour -#define SFLITE_LOG_RESET "\033[0m" +#define SFLC_LOG_RESET "\033[0m" // Log level: debug implies detailed logs -#ifdef CONFIG_SFLITE_LOG_DEBUG -#define CONFIG_SFLITE_LOG_DETAILED +#ifdef CONFIG_SFLC_LOG_DEBUG +#define CONFIG_SFLC_LOG_DETAILED #endif @@ -68,42 +68,42 @@ *****************************************************/ // Gives the point in the code where it was called -#define sflite_log_detailed(col, ...) do{ \ - printf(SFLITE_LOG_GRN "FUNC " SFLITE_LOG_RESET "%s() " \ - SFLITE_LOG_GRN "FILE " SFLITE_LOG_RESET "%s " \ - SFLITE_LOG_GRN "LINE " SFLITE_LOG_RESET "%d | ", \ +#define sflc_log_detailed(col, ...) do{ \ + printf(SFLC_LOG_GRN "FUNC " SFLC_LOG_RESET "%s() " \ + SFLC_LOG_GRN "FILE " SFLC_LOG_RESET "%s " \ + SFLC_LOG_GRN "LINE " SFLC_LOG_RESET "%d | ", \ __func__, __FILE__, __LINE__); \ - sflite_log_concise(col, __VA_ARGS__); \ + sflc_log_concise(col, __VA_ARGS__); \ }while(0) // Only writes using the given colour -#define sflite_log_concise(col, ...) do{ \ +#define sflc_log_concise(col, ...) do{ \ printf(col); \ printf(__VA_ARGS__); \ - printf(SFLITE_LOG_RESET "\n"); \ + printf(SFLC_LOG_RESET "\n"); \ }while(0) // Maps to one or the other, based on a Makefile switch -#ifdef CONFIG_SFLITE_LOG_DETAILED - #define sflite_log_colour(...) sflite_log_detailed(__VA_ARGS__) +#ifdef CONFIG_SFLC_LOG_DETAILED + #define sflc_log_colour(...) sflc_log_detailed(__VA_ARGS__) #else - #define sflite_log_colour(...) sflite_log_concise(__VA_ARGS__) + #define sflc_log_colour(...) sflc_log_concise(__VA_ARGS__) #endif // Using specific colours -#define sflite_log_green(...) sflite_log_colour(SFLITE_LOG_GRN, __VA_ARGS__) -#define sflite_log_red(...) sflite_log_colour(SFLITE_LOG_RED, __VA_ARGS__) -#define sflite_log_yellow(...) sflite_log_colour(SFLITE_LOG_YEL, __VA_ARGS__) -#define sflite_log_blue(...) sflite_log_colour(SFLITE_LOG_BLU, __VA_ARGS__) -#define sflite_log_normal(...) sflite_log_colour(SFLITE_LOG_RESET, __VA_ARGS__) +#define sflc_log_green(...) sflc_log_colour(SFLC_LOG_GRN, __VA_ARGS__) +#define sflc_log_red(...) sflc_log_colour(SFLC_LOG_RED, __VA_ARGS__) +#define sflc_log_yellow(...) sflc_log_colour(SFLC_LOG_YEL, __VA_ARGS__) +#define sflc_log_blue(...) sflc_log_colour(SFLC_LOG_BLU, __VA_ARGS__) +#define sflc_log_normal(...) sflc_log_colour(SFLC_LOG_RESET, __VA_ARGS__) // With log levels -#define sflite_log_error(...) sflite_log_colour(SFLITE_LOG_RED, "[ERROR] " __VA_ARGS__) -#define sflite_log_warn(...) sflite_log_colour(SFLITE_LOG_MAG, "[WARN] " __VA_ARGS__) -#ifdef CONFIG_SFLITE_LOG_DEBUG - #define sflite_log_debug(...) sflite_log_colour(SFLITE_LOG_CYN, "[DEBUG] " __VA_ARGS__) +#define sflc_log_error(...) sflc_log_colour(SFLC_LOG_RED, "[ERROR] " __VA_ARGS__) +#define sflc_log_warn(...) sflc_log_colour(SFLC_LOG_MAG, "[WARN] " __VA_ARGS__) +#ifdef CONFIG_SFLC_LOG_DEBUG + #define sflc_log_debug(...) sflc_log_colour(SFLC_LOG_CYN, "[DEBUG] " __VA_ARGS__) #else - #define sflite_log_debug(...) + #define sflc_log_debug(...) #endif @@ -112,7 +112,7 @@ *****************************************************/ // Log a hex string -static inline void sflite_log_hex(char *str, size_t len) +static inline void sflc_log_hex(char *str, size_t len) { int i; unsigned char *s = (unsigned char *) str; diff --git a/shufflecake-userland-lite/include/utils/sflite.h b/shufflecake-userland-lite/include/utils/sflc.h similarity index 72% rename from shufflecake-userland-lite/include/utils/sflite.h rename to shufflecake-userland-lite/include/utils/sflc.h index 1dcd963..a43efba 100644 --- a/shufflecake-userland-lite/include/utils/sflite.h +++ b/shufflecake-userland-lite/include/utils/sflc.h @@ -22,11 +22,11 @@ */ /* - * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflite_constans.h + * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflc_constans.h */ -#ifndef _UTILS_SFLITE_H_ -#define _UTILS_SFLITE_H_ +#ifndef _UTILS_SFLC_H_ +#define _UTILS_SFLC_H_ /***************************************************** @@ -48,42 +48,42 @@ /* Sizes */ #define KERNEL_SECTOR_SIZE 512 /* bytes */ -#define SFLITE_BLOCK_SIZE 4096 /* bytes */ -#define SFLITE_BLOCK_SCALE (SFLITE_BLOCK_SIZE / KERNEL_SECTOR_SIZE) -#define SFLITE_SLICE_SCALE 256 /* blocks in a slice */ -#define SFLITE_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ +#define SFLC_BLOCK_SIZE 4096 /* bytes */ +#define SFLC_BLOCK_SCALE (SFLC_BLOCK_SIZE / KERNEL_SECTOR_SIZE) +#define SFLC_SLICE_SCALE 256 /* blocks in a slice */ +#define SFLC_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ /* Max number of volumes in a device */ -#define SFLITE_DEV_MAX_VOLUMES 15 +#define SFLC_DEV_MAX_VOLUMES 15 /* Max total number of open devices at any given time */ -#define SFLITE_TOT_MAX_DEVICES 1024 -/* A volume name is sflite__ */ -#define SFLITE_MAX_VOL_NAME_LEN 15 +#define SFLC_TOT_MAX_DEVICES 1024 +/* A volume name is sflc__ */ +#define SFLC_MAX_VOL_NAME_LEN 15 /* A slice index is represented over 32 bits */ -#define SFLITE_SLICE_IDX_WIDTH 4 /* bytes */ +#define SFLC_SLICE_IDX_WIDTH 4 /* bytes */ /* A position map block contains 1024 slice indices */ -#define SFLITE_SLICE_IDX_PER_BLOCK (SFLITE_BLOCK_SIZE / SFLITE_SLICE_IDX_WIDTH) +#define SFLC_SLICE_IDX_PER_BLOCK (SFLC_BLOCK_SIZE / SFLC_SLICE_IDX_WIDTH) /* A PSI of 0xFFFFFFFF indicates an unassigned LSI */ -#define SFLITE_EPM_FILLER 0xFF +#define SFLC_EPM_FILLER 0xFF /* The sysfs file containing the next available device ID */ -#define SFLITE_SYSFS_NEXTDEVID "/sys/module/dm_sflc/next_dev_id" +#define SFLC_SYSFS_NEXTDEVID "/sys/module/dm_sflc/next_dev_id" /* The sysfs directory containing a subdir for each (underlying) block device */ -#define SFLITE_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" +#define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" /* Within each bdev's subdir, this file shows its number of open volumes */ -#define SFLITE_SYSFS_OPENVOLUMES_FILENAME "volumes" +#define SFLC_SYSFS_OPENVOLUMES_FILENAME "volumes" /* Within each bdev's subdir, this file shows its Shufflecake device ID */ -#define SFLITE_SYSFS_DEVID_FILENAME "dev_id" +#define SFLC_SYSFS_DEVID_FILENAME "dev_id" /* TODO: reasonable? */ -#define SFLITE_BDEV_PATH_MAX_LEN 1024 +#define SFLC_BDEV_PATH_MAX_LEN 1024 /* For when you can't be bothered to upper-bound a buffer size */ -#define SFLITE_BIGBUFSIZE 4096 +#define SFLC_BIGBUFSIZE 4096 -#endif /* _UTILS_SFLITE_H_ */ +#endif /* _UTILS_SFLC_H_ */ diff --git a/shufflecake-userland-lite/include/utils/string.h b/shufflecake-userland-lite/include/utils/string.h index 552ed82..ca42c0e 100644 --- a/shufflecake-userland-lite/include/utils/string.h +++ b/shufflecake-userland-lite/include/utils/string.h @@ -30,10 +30,10 @@ *****************************************************/ /* Malloc's the buffer for the hex string */ -char *sflite_toHex(char *buf, size_t len); +char *sflc_toHex(char *buf, size_t len); /* Replaces all occurrences of character in-place */ -void sflite_str_replaceAll(char *str, char old, char new); +void sflc_str_replaceAll(char *str, char old, char new); #endif /* _UTILS_STRING_H_ */ diff --git a/shufflecake-userland-lite/src/utils/crypto.c b/shufflecake-userland-lite/src/utils/crypto.c index d7331e1..4494dd1 100644 --- a/shufflecake-userland-lite/src/utils/crypto.c +++ b/shufflecake-userland-lite/src/utils/crypto.c @@ -44,7 +44,7 @@ * *@return The error code (0 on success) */ -int sflite_rand_getStrongBytes(char *buf, size_t buflen) +int sflc_rand_getStrongBytes(char *buf, size_t buflen) { gcry_randomize(buf, buflen, GCRY_VERY_STRONG_RANDOM); return 0; @@ -61,7 +61,7 @@ int sflite_rand_getStrongBytes(char *buf, size_t buflen) * *@return The error code (0 on success) */ -int sflite_rand_getWeakBytes(char *buf, size_t buflen) +int sflc_rand_getWeakBytes(char *buf, size_t buflen) { gcry_create_nonce(buf, buflen); return 0; @@ -81,7 +81,7 @@ int sflite_rand_getWeakBytes(char *buf, size_t buflen) * *@return The error code (0 on success) */ -int sflite_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -89,26 +89,26 @@ int sflite_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); if (err) { - sflite_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); goto bad_open; } - sflite_log_debug("Successfully instantiated AES256-CTR cipher handle"); + sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { - sflite_log_error("Could not set AES key: error %d", err); + sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflite_log_debug("Successfully set the AES key"); + sflc_log_debug("Successfully set the AES key"); // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, SFLITE_AESCTR_IVLEN); + err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); if (err) { - sflite_log_error("Could not set AES-CTR IV: error %d", err); + sflc_log_error("Could not set AES-CTR IV: error %d", err); goto bad_setctr; } - sflite_log_debug("Successfully set the IV"); + sflc_log_debug("Successfully set the IV"); // Encrypt if (ct == NULL) { // In-place @@ -119,10 +119,10 @@ int sflite_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char } // Error check if (err) { - sflite_log_error("Could not encrypt: error %d", err); + sflc_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - sflite_log_debug("Successfully encrypted"); + sflc_log_debug("Successfully encrypted"); // No prob? err = 0; @@ -149,7 +149,7 @@ bad_open: * *@return The error code (0 on success) */ -int sflite_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) +int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -157,26 +157,26 @@ int sflite_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); if (err) { - sflite_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); + sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); goto bad_open; } - sflite_log_debug("Successfully instantiated AES256-CTR cipher handle"); + sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { - sflite_log_error("Could not set AES key: error %d", err); + sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflite_log_debug("Successfully set AES key"); + sflc_log_debug("Successfully set AES key"); // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, SFLITE_AESCTR_IVLEN); + err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); if (err) { - sflite_log_error("Could not set AES-CTR IV: error %d", err); + sflc_log_error("Could not set AES-CTR IV: error %d", err); goto bad_setctr; } - sflite_log_debug("Successfully set IV"); + sflc_log_debug("Successfully set IV"); // Decrypt if (pt == NULL) { // In-place @@ -187,10 +187,10 @@ int sflite_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char } // Error check if (err) { - sflite_log_error("Could not decrypt: error %d", err); + sflc_log_error("Could not decrypt: error %d", err); goto bad_decrypt; } - sflite_log_debug("Successfully decrypted"); + sflc_log_debug("Successfully decrypted"); // No prob err = 0; @@ -219,7 +219,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflite_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) +int sflc_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -227,26 +227,26 @@ int sflite_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_XTS, GCRY_CIPHER_SECURE); if (err) { - sflite_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); + sflc_log_error("Could not instantiate AES256-XTS cipher handle: error %d", err); goto bad_open; } - sflite_log_debug("Successfully instantiated AES256-XTS cipher handle"); + sflc_log_debug("Successfully instantiated AES256-XTS cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLITE_AESXTS_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_AESXTS_KEYLEN); if (err) { - sflite_log_error("Could not set AES-XTS key: error %d", err); + sflc_log_error("Could not set AES-XTS key: error %d", err); goto bad_setkey; } - sflite_log_debug("Successfully set the AES-XTS key"); + sflc_log_debug("Successfully set the AES-XTS key"); // Set the IV (not a counter, as per Gcrypt docs) - err = gcry_cipher_setiv(hd, iv, SFLITE_AESXTS_IVLEN); + err = gcry_cipher_setiv(hd, iv, SFLC_AESXTS_IVLEN); if (err) { - sflite_log_error("Could not set AES-XTS IV: error %d", err); + sflc_log_error("Could not set AES-XTS IV: error %d", err); goto bad_setiv; } - sflite_log_debug("Successfully set the IV"); + sflc_log_debug("Successfully set the IV"); // Encrypt if (ct == NULL) { // In-place @@ -257,10 +257,10 @@ int sflite_aes256xts_encrypt(char *key, char *pt, size_t pt_len, char *iv, char } // Error check if (err) { - sflite_log_error("Could not encrypt: error %d", err); + sflc_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - sflite_log_debug("Successfully encrypted"); + sflc_log_debug("Successfully encrypted"); // No prob? err = 0; @@ -289,7 +289,7 @@ bad_open: * *@return The error code (0 on success) */ -int sflite_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) +int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -297,42 +297,42 @@ int sflite_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); if (err) { - sflite_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); goto bad_open; } - sflite_log_debug("Successfully instantiated AES256-GCM cipher handle"); + sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { - sflite_log_error("Could not set AES key: error %d", err); + sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflite_log_debug("Successfully set the AES key"); + sflc_log_debug("Successfully set the AES key"); // Set the IV - err = gcry_cipher_setiv(hd, iv, SFLITE_AESGCM_IVLEN); + err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); if (err) { - sflite_log_error("Could not set AES-GCM IV: error %d", err); + sflc_log_error("Could not set AES-GCM IV: error %d", err); goto bad_setiv; } - sflite_log_debug("Successfully set the IV"); + sflc_log_debug("Successfully set the IV"); // Encrypt err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); if (err) { - sflite_log_error("Could not encrypt: error %d", err); + sflc_log_error("Could not encrypt: error %d", err); goto bad_encrypt; } - sflite_log_debug("Successfully encrypted"); + sflc_log_debug("Successfully encrypted"); // Get MAC - err = gcry_cipher_gettag(hd, tag, SFLITE_AESGCM_TAGLEN); + err = gcry_cipher_gettag(hd, tag, SFLC_AESGCM_TAGLEN); if (err) { - sflite_log_error("Could not get MAC: error %d", err); + sflc_log_error("Could not get MAC: error %d", err); goto bad_gettag; } - sflite_log_debug("Successfully gotten MAC"); + sflc_log_debug("Successfully gotten MAC"); // No prob? err = 0; @@ -364,7 +364,7 @@ bad_open: * *@return The error code (0 on success) */ -int sflite_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) +int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) { gcry_cipher_hd_t hd; gcry_error_t err; @@ -372,52 +372,52 @@ int sflite_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char // Instantiate the handle err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); if (err) { - sflite_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); + sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); goto bad_open; } - sflite_log_debug("Successfully instantiated AES256-GCM cipher handle"); + sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); // Set the key - err = gcry_cipher_setkey(hd, key, SFLITE_STANDARD_KEYLEN); + err = gcry_cipher_setkey(hd, key, SFLC_STANDARD_KEYLEN); if (err) { - sflite_log_error("Could not set AES key: error %d", err); + sflc_log_error("Could not set AES key: error %d", err); goto bad_setkey; } - sflite_log_debug("Successfully set AES key"); + sflc_log_debug("Successfully set AES key"); // Set the IV - err = gcry_cipher_setiv(hd, iv, SFLITE_AESGCM_IVLEN); + err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); if (err) { - sflite_log_error("Could not set AES-GCM IV: error %d", err); + sflc_log_error("Could not set AES-GCM IV: error %d", err); goto bad_setiv; } - sflite_log_debug("Successfully set IV"); + sflc_log_debug("Successfully set IV"); // Decrypt err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); if (err) { - sflite_log_error("Could not decrypt: error %d", err); + sflc_log_error("Could not decrypt: error %d", err); goto bad_decrypt; } - sflite_log_debug("Successfully decrypted"); + sflc_log_debug("Successfully decrypted"); // Check MAC - err = gcry_cipher_checktag(hd, tag, SFLITE_AESGCM_TAGLEN); + err = gcry_cipher_checktag(hd, tag, SFLC_AESGCM_TAGLEN); if (gcry_err_code(err) == GPG_ERR_CHECKSUM) { // Undo decryption - memset(pt, SFLITE_AESGCM_POISON_PT, ct_len); + memset(pt, SFLC_AESGCM_POISON_PT, ct_len); // Flag it *match = false; } else if (err) { - sflite_log_error("Could not check MAC: error %d", err); + sflc_log_error("Could not check MAC: error %d", err); goto bad_checktag; } else { // Flag MAC verification success *match = true; } - sflite_log_debug("Successfully checked MAC: match = %d", *match); + sflc_log_debug("Successfully checked MAC: match = %d", *match); // No prob, whether MAC verified or not err = 0; @@ -444,11 +444,11 @@ bad_open: * * @return The error code (0 on success) */ -int sflite_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) +int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) { gcry_kdf_hd_t hd; const unsigned long argon_params[4] = - {SFLITE_STANDARD_KEYLEN, SFLITE_ARGON_T, SFLITE_ARGON_M, SFLITE_ARGON_P}; + {SFLC_STANDARD_KEYLEN, SFLC_ARGON_T, SFLC_ARGON_M, SFLC_ARGON_P}; gcry_error_t err; // Instantiate Argon2id handle @@ -456,31 +456,31 @@ int sflite_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) &hd, GCRY_KDF_ARGON2, GCRY_KDF_ARGON2ID, argon_params, 4, pwd, pwd_len, - salt, SFLITE_ARGON_SALTLEN, + salt, SFLC_ARGON_SALTLEN, NULL, 0, /* Optional secret value K */ NULL, 0 /* Optional associated data X */ ); if (err) { - sflite_log_error("Could not open Argon2id handle: error %d", err); + sflc_log_error("Could not open Argon2id handle: error %d", err); goto bad_open; } - sflite_log_debug("Successfully opened Argon2id handle"); + sflc_log_debug("Successfully opened Argon2id handle"); // Run the computation err = gcry_kdf_compute(hd, NULL); if (err) { - sflite_log_error("Could not run Argon2id computation: error %d", err); + sflc_log_error("Could not run Argon2id computation: error %d", err); goto bad_compute; } - sflite_log_debug("Successfully run Argon2id computation"); + sflc_log_debug("Successfully run Argon2id computation"); // Finalise hash - err = gcry_kdf_final(hd, SFLITE_STANDARD_KEYLEN, hash); + err = gcry_kdf_final(hd, SFLC_STANDARD_KEYLEN, hash); if (err) { - sflite_log_error("Could not finalise Argon2id hash: error %d", err); + sflc_log_error("Could not finalise Argon2id hash: error %d", err); goto bad_final; } - sflite_log_debug("Successfully finalised Argon2id hash"); + sflc_log_debug("Successfully finalised Argon2id hash"); // All in order err = 0; diff --git a/shufflecake-userland-lite/src/utils/disk.c b/shufflecake-userland-lite/src/utils/disk.c index 79f2be2..7da8c86 100644 --- a/shufflecake-userland-lite/src/utils/disk.c +++ b/shufflecake-userland-lite/src/utils/disk.c @@ -56,14 +56,14 @@ * * @return A string version of the device ID */ -char *sflite_disk_getDeviceName(char *bdev_path) +char *sflc_disk_getDeviceName(char *bdev_path) { struct stat sb; char *dev_name; if (stat(bdev_path, &sb) != 0) return NULL; - dev_name = malloc(SFLITE_BIGBUFSIZE); + dev_name = malloc(SFLC_BIGBUFSIZE); if (!dev_name) return NULL; @@ -80,7 +80,7 @@ char *sflite_disk_getDeviceName(char *bdev_path) * * @return true iff it's a block device */ -bool sflite_disk_isBlockDevice(char *path) +bool sflc_disk_isBlockDevice(char *path) { struct stat path_stat; if (stat(path, &path_stat) != 0) { @@ -96,7 +96,7 @@ bool sflite_disk_isBlockDevice(char *path) * * @return The size (in 4096-byte sectors) of the disk, or -errno if error */ -int64_t sflite_disk_getSize(char * bdev_path) +int64_t sflc_disk_getSize(char * bdev_path) { int fd; uint64_t size_bytes; @@ -105,24 +105,24 @@ int64_t sflite_disk_getSize(char * bdev_path) /* Open file */ fd = open(bdev_path, O_RDONLY); if (fd < 0) { - sflite_log_error("Could not open file %s", bdev_path); + sflc_log_error("Could not open file %s", bdev_path); perror("Cause: "); ret = -errno; goto bad_open; } - sflite_log_debug("Opened file %s", bdev_path); + sflc_log_debug("Opened file %s", bdev_path); /* Get size in bytes */ if (ioctl(fd, BLKGETSIZE64, &size_bytes) < 0) { - sflite_log_error("Could not ioctl file %s", bdev_path); + sflc_log_error("Could not ioctl file %s", bdev_path); perror("Cause: "); ret = -errno; goto bad_ioctl; } - sflite_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); + sflc_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); - /* Compute size in SFLITE sectors */ - ret = (size_bytes / SFLITE_BLOCK_SIZE); + /* Compute size in SFLC sectors */ + ret = (size_bytes / SFLC_BLOCK_SIZE); bad_ioctl: close(fd); @@ -140,7 +140,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflite_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) +int sflc_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) { int fd; int err; @@ -148,29 +148,29 @@ int sflite_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) /* Open file */ fd = open(bdev_path, O_RDONLY); if (fd < 0) { - sflite_log_error("Could not open file %s", bdev_path); + sflc_log_error("Could not open file %s", bdev_path); perror("Cause: "); err = errno; goto bad_open; } - sflite_log_debug("Opened file %s", bdev_path); + sflc_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * SFLITE_BLOCK_SIZE, SEEK_SET) < 0) { - sflite_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + if (lseek(fd, sector * SFLC_BLOCK_SIZE, SEEK_SET) < 0) { + sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_lseek; } - sflite_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Read in a loop */ - size_t bytes_to_read = SFLITE_BLOCK_SIZE; + size_t bytes_to_read = SFLC_BLOCK_SIZE; while (bytes_to_read > 0) { /* Read syscall */ ssize_t bytes_read = read(fd, buf, bytes_to_read); if (bytes_read < 0) { - sflite_log_error("Could not read file %s at sector %lu", bdev_path, sector); + sflc_log_error("Could not read file %s at sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_read; @@ -178,7 +178,7 @@ int sflite_disk_readBlock(char * bdev_path, uint64_t sector, char * buf) /* Partial read? No problem just log */ if (bytes_read < bytes_to_read) { - sflite_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", + sflc_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", bdev_path, sector, bytes_read, bytes_to_read); } @@ -209,7 +209,7 @@ bad_open: * * @return The error code (0 on success) */ -int sflite_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) +int sflc_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) { int fd; int err; @@ -217,29 +217,29 @@ int sflite_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, s /* Open file */ fd = open(bdev_path, O_WRONLY); if (fd < 0) { - sflite_log_error("Could not open file %s", bdev_path); + sflc_log_error("Could not open file %s", bdev_path); perror("Cause: "); err = errno; goto bad_open; } - sflite_log_debug("Opened file %s", bdev_path); + sflc_log_debug("Opened file %s", bdev_path); /* Set offset in bytes */ - if (lseek(fd, sector * SFLITE_BLOCK_SIZE, SEEK_SET) < 0) { - sflite_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); + if (lseek(fd, sector * SFLC_BLOCK_SIZE, SEEK_SET) < 0) { + sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_lseek; } - sflite_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); + sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); /* Write in a loop */ - size_t bytes_to_write = SFLITE_BLOCK_SIZE * num_sectors; + size_t bytes_to_write = SFLC_BLOCK_SIZE * num_sectors; while (bytes_to_write > 0) { /* Write syscall */ ssize_t bytes_written = write(fd, buf, bytes_to_write); if (bytes_written < 0) { - sflite_log_red("Could not write file %s at sector %lu", bdev_path, sector); + sflc_log_red("Could not write file %s at sector %lu", bdev_path, sector); perror("Cause: "); err = errno; goto bad_write; @@ -247,7 +247,7 @@ int sflite_disk_writeManyBlocks(char * bdev_path, uint64_t sector, char * buf, s /* Partial write? No problem just log */ if (bytes_written < bytes_to_write) { - sflite_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", + sflc_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", bdev_path, sector, bytes_written, bytes_to_write); } diff --git a/shufflecake-userland-lite/src/utils/dm.c b/shufflecake-userland-lite/src/utils/dm.c index da6f259..275d61e 100644 --- a/shufflecake-userland-lite/src/utils/dm.c +++ b/shufflecake-userland-lite/src/utils/dm.c @@ -35,7 +35,7 @@ #include #include "utils/dm.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/log.h" @@ -54,7 +54,7 @@ * * @return The error code (0 on success) */ -int sflite_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) +int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) { struct dm_task *dmt; uint32_t cookie = 0; @@ -65,60 +65,60 @@ int sflite_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) char * dup_virt_dev_name = strdup(virt_dev_name); char * dup_params = strdup(params); - sflite_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); + sflc_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); /* Instantiate the DM task (with the CREATE ioctl command) */ if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) { - sflite_log_error("Cannot create dm_task"); + sflc_log_error("Cannot create dm_task"); err = 1; goto dup_free; } - sflite_log_debug("Successfully created dm_task"); + sflc_log_debug("Successfully created dm_task"); /* Set the name of the target device (to be created) */ if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - sflite_log_error("Cannot set device name"); + sflc_log_error("Cannot set device name"); err = 2; goto out; } - sflite_log_debug("Successfully set device name"); + sflc_log_debug("Successfully set device name"); /* State that it is a Shufflecake device, pass the start and size, and the * constructor parameters */ if (!dm_task_add_target(dmt, 0, num_sectors, SFLC_DM_TARGET_NAME, dup_params)) { - sflite_log_error("Cannot add DM target and parameters"); + sflc_log_error("Cannot add DM target and parameters"); err = 3; goto out; } - sflite_log_debug("Successfully added DM target and parameters"); + sflc_log_debug("Successfully added DM target and parameters"); /* Say that we want a new node under /dev/mapper */ if (!dm_task_set_add_node(dmt, DM_ADD_NODE_ON_CREATE)) { - sflite_log_error("Cannot add /dev/mapper node"); + sflc_log_error("Cannot add /dev/mapper node"); err = 4; goto out; } - sflite_log_debug("Successfully set the ADD_NODE flag"); + sflc_log_debug("Successfully set the ADD_NODE flag"); /* Get a cookie (request ID, basically) to wait for task completion */ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - sflite_log_error("Cannot get cookie"); + sflc_log_error("Cannot get cookie"); err = 5; goto out; } - sflite_log_debug("Successfully got a cookie"); + sflc_log_debug("Successfully got a cookie"); /* Run the task */ if (!dm_task_run(dmt)) { - sflite_log_error("Cannot issue ioctl"); + sflc_log_error("Cannot issue ioctl"); err = 6; goto out; } - sflite_log_debug("Successfully run DM task"); + sflc_log_debug("Successfully run DM task"); /* Wait for completion */ dm_udev_wait(cookie); - sflite_log_debug("Task completed"); + sflc_log_debug("Task completed"); // No prob err = 0; @@ -140,7 +140,7 @@ dup_free: * * @return error code (0 on success) */ -int sflite_dm_destroy(char * virt_dev_name) +int sflc_dm_destroy(char * virt_dev_name) { struct dm_task *dmt; uint32_t cookie = 0; @@ -150,47 +150,47 @@ int sflite_dm_destroy(char * virt_dev_name) /* Just to be sure, let's get it on the heap */ char * dup_virt_dev_name = strdup(virt_dev_name); - sflite_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); + sflc_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); /* Instantiate the DM task (with the REMOVE ioctl command) */ if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) { - sflite_log_error("Cannot create dm_task"); + sflc_log_error("Cannot create dm_task"); err = 1; goto dup_free; } - sflite_log_debug("Successfully created dm_task"); + sflc_log_debug("Successfully created dm_task"); /* Set the name of the target device (to be closed) */ if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - sflite_log_error("Cannot set device name"); + sflc_log_error("Cannot set device name"); err = 2; goto out; } - sflite_log_debug("Successfully set device name"); + sflc_log_debug("Successfully set device name"); /* Get a cookie (request ID, basically) to wait for task completion */ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - sflite_log_error("Cannot set cookie"); + sflc_log_error("Cannot set cookie"); err = 3; goto out; } - sflite_log_debug("Successfully got a cookie"); + sflc_log_debug("Successfully got a cookie"); /* Needed for some reason */ dm_task_retry_remove(dmt); - sflite_log_debug("Successful retry_remove"); + sflc_log_debug("Successful retry_remove"); /* Run the task */ if (!dm_task_run(dmt)) { - sflite_log_error("Cannot issue ioctl"); + sflc_log_error("Cannot issue ioctl"); err = 4; goto out; } - sflite_log_debug("Successfully run task"); + sflc_log_debug("Successfully run task"); /* Wait for completion */ dm_udev_wait(cookie); - sflite_log_debug("Task completed"); + sflc_log_debug("Task completed"); // No prob err = 0; diff --git a/shufflecake-userland-lite/src/utils/file.c b/shufflecake-userland-lite/src/utils/file.c index 82c7472..11066b1 100644 --- a/shufflecake-userland-lite/src/utils/file.c +++ b/shufflecake-userland-lite/src/utils/file.c @@ -38,7 +38,7 @@ *****************************************************/ /* Reads the entire content of a file in a malloc-ed string */ -char *sflite_readFile(char *path) +char *sflc_readFile(char *path) { int filesize; FILE *fp; diff --git a/shufflecake-userland-lite/src/utils/input.c b/shufflecake-userland-lite/src/utils/input.c index 5a0e9ac..ffc0b02 100644 --- a/shufflecake-userland-lite/src/utils/input.c +++ b/shufflecake-userland-lite/src/utils/input.c @@ -41,13 +41,13 @@ *****************************************************/ /* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int sflite_safeReadLine(char *buf, size_t bufsize) +int sflc_safeReadLine(char *buf, size_t bufsize) { size_t len; /* Read from stdin */ if (fgets(buf, bufsize, stdin) == NULL) { - sflite_log_error("Could not read from stdin"); + sflc_log_error("Could not read from stdin"); return EBADFD; } @@ -62,7 +62,7 @@ int sflite_safeReadLine(char *buf, size_t bufsize) /* Reads a password/passphrase in a secure way (no echo) */ -int sflite_safeReadPassphrase(char *buf, size_t bufsize) +int sflc_safeReadPassphrase(char *buf, size_t bufsize) { size_t len; struct termios old, new; @@ -79,7 +79,7 @@ int sflite_safeReadPassphrase(char *buf, size_t bufsize) if (fgets(buf, bufsize, stdin) == NULL) { // If reading the password failed, ensure echoing is turned back on tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); - sflite_log_error("Could not read from stdin"); + sflc_log_error("Could not read from stdin"); return EBADFD; } diff --git a/shufflecake-userland-lite/src/utils/string.c b/shufflecake-userland-lite/src/utils/string.c index 86d735f..c6cf998 100644 --- a/shufflecake-userland-lite/src/utils/string.c +++ b/shufflecake-userland-lite/src/utils/string.c @@ -38,7 +38,7 @@ *****************************************************/ /* Malloc's the buffer for the hex string */ -char *sflite_toHex(char *buf, size_t len) +char *sflc_toHex(char *buf, size_t len) { unsigned char *u = (unsigned char *) buf; char *hex; @@ -46,7 +46,7 @@ char *sflite_toHex(char *buf, size_t len) /* Allocate buffer */ hex = malloc((len * 2) + 1); if (!hex) { - sflite_log_error("Could not allocate buffer for hex string"); + sflc_log_error("Could not allocate buffer for hex string"); return NULL; } @@ -61,7 +61,7 @@ char *sflite_toHex(char *buf, size_t len) } -void sflite_str_replaceAll(char * str, char old, char new) +void sflc_str_replaceAll(char * str, char old, char new) { int i; for (i = 0; str[i] != '\0'; i++) { From cbf035905c2fdd761f539d3db287eb1b919c6874 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 22 Aug 2024 23:57:44 +0200 Subject: [PATCH 65/75] Merge header/ --- shufflecake-userland-lite/include/header.h | 87 +++++-- .../src/header/device_master_block.c | 90 +++---- .../src/header/position_map_legacy.c | 134 +++++++++++ .../{position_map.c => position_map_lite.c} | 18 +- ...r_block.c => volume_master_block_legacy.c} | 72 +++--- .../src/header/volume_master_block_lite.c | 223 ++++++++++++++++++ 6 files changed, 510 insertions(+), 114 deletions(-) create mode 100644 shufflecake-userland-lite/src/header/position_map_legacy.c rename shufflecake-userland-lite/src/header/{position_map.c => position_map_lite.c} (88%) rename shufflecake-userland-lite/src/header/{volume_master_block.c => volume_master_block_legacy.c} (67%) create mode 100644 shufflecake-userland-lite/src/header/volume_master_block_lite.c diff --git a/shufflecake-userland-lite/include/header.h b/shufflecake-userland-lite/include/header.h index 469fe8b..1062a21 100644 --- a/shufflecake-userland-lite/include/header.h +++ b/shufflecake-userland-lite/include/header.h @@ -41,18 +41,18 @@ *****************************************************/ /* The DMB contains one IV + one VMB key + one MAC for each volume */ -#define SFLITE_DMB_CELL_SIZE (SFLITE_AESGCM_PADDED_IVLEN + SFLITE_STANDARD_KEYLEN + SFLITE_AESGCM_TAGLEN) +#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_STANDARD_KEYLEN + SFLC_AESGCM_TAGLEN) /* Let us enforce that the one DMB can fit cells for all volumes */ -#if SFLITE_ARGON_SALTLEN + (SFLITE_DEV_MAX_VOLUMES * SFLITE_DMB_CELL_SIZE) > SFLITE_BLOCK_SIZE +#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL_SIZE) > SFLC_BLOCK_SIZE #error "Invalid combination of parameters: probably SFLITE_DEV_MAX_VOLUMES is too big" #endif // The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) -#define SFLITE_CLEAR_VMB_LEN (SFLITE_BLOCK_SIZE - \ - SFLITE_AESGCM_PADDED_IVLEN - \ - SFLITE_AESGCM_TAGLEN) +#define SFLC_CLEAR_VMB_LEN (SFLC_BLOCK_SIZE - \ + SFLC_AESGCM_PADDED_IVLEN - \ + SFLC_AESGCM_TAGLEN) @@ -67,13 +67,12 @@ */ typedef struct { // Each volume's VMB key - char vmb_keys[SFLITE_DEV_MAX_VOLUMES][SFLITE_STANDARD_KEYLEN]; + char vmb_keys[SFLC_DEV_MAX_VOLUMES][SFLC_STANDARD_KEYLEN]; // How many of these need actually be encrypted size_t nr_vols; -} sflite_Dmb; - +} sflc_Dmb; /** * When unsealing a DMB, only one VMB key can be unlocked with a password. @@ -81,12 +80,12 @@ typedef struct { */ typedef struct { // The unlocked VMB key - char vmb_key[SFLITE_STANDARD_KEYLEN]; + char vmb_key[SFLC_STANDARD_KEYLEN]; // The index of the volume opened by this VMB key size_t vol_idx; -} sflite_DmbCell; +} sflc_DmbCell; /** @@ -95,16 +94,49 @@ typedef struct { * only contains the useful info, in the clear. */ typedef struct { + int mode; + // The key that encrypts the volume's data section - char volume_key[SFLITE_AESXTS_KEYLEN]; + union { + char volume_key_lite[SFLC_AESXTS_KEYLEN]; + char volume_key_legacy[SFLC_STANDARD_KEYLEN]; + }; // The key that encrypts the previous volume's master block - char prev_vmb_key[SFLITE_STANDARD_KEYLEN]; + char prev_vmb_key[SFLC_STANDARD_KEYLEN]; // The total number of logical slices virtually available to this volume size_t nr_slices; -} sflite_Vmb; +} sflc_Vmb; + +/** + * This struct represents an encrypted empty position map. LEGACY version. + * On-disk, the layout interleaves one IV block with 256 PosMap blocks (each + * encrypted by an IV in the IV block). Many such "runs" can be concatenated, + * until the position map is big enough to index the desired number of slices. + * The last "run" might be incomplete, in that it could have less than 256 + * PosMap blocks, if not all of them are needed. + * In the struct, there are as many IV blocks as there are PosMapBlock arrays + * (equal to the number of "runs"). The m-th IV of the n-th IV block encrypts + * the m-th block of the n-th array. The PosMapBlocks in an array are stored + * contiguously in RAM, so a PosMapBlock array is just a char array of length + * multiple of 4096. All the arrays are full (256 PosMapBlocks, 1 MiB) except + * for the last one, which may hold fewer blocks. + */ +typedef struct { + // The number of PosMapBlock arrays (and of IV blocks) + size_t nr_arrays; + + // The sequence of IV blocks + char **iv_blocks; + // The sequence of (encrypted) PosMapBlock arrays + char **pmb_arrays; + + // The number of PosMapBlocks in the last array + size_t nr_last_pmbs; + +} sfold_EncPosMap; /***************************************************** @@ -112,12 +144,12 @@ typedef struct { *****************************************************/ -// Starting block of a volume's position map +// Starting block of a volume's position map. LITE version static inline uint64_t sflite_pmStartBlock(size_t vol_idx, size_t nr_slices) { return 1 + - SFLITE_DEV_MAX_VOLUMES + - vol_idx*ceil(nr_slices, SFLITE_SLICE_IDX_PER_BLOCK); + SFLC_DEV_MAX_VOLUMES + + vol_idx*ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); } @@ -126,22 +158,29 @@ static inline uint64_t sflite_pmStartBlock(size_t vol_idx, size_t nr_slices) *****************************************************/ /* "Encrypt" each VMB key with its pwd, so the DMB is ready to be written on-disk */ -int sflite_dmb_seal(sflite_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); +int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); /* "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF) */ -int sflite_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflite_DmbCell *dmb_cell); +int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); /* Re-encrypt the content of a single DMB cell */ -int sflite_dmb_setCell(char *disk_block, sflite_DmbCell *dmb_cell, char *pwd, size_t pwd_len); +int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len); -/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ -int sflite_vmb_seal(sflite_Vmb *vmb, char *vmb_key, char *disk_block); -/* "Decrypt" a VMB coming from the disk, directly using its key */ -int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflite_Vmb *vmb); +/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk. LITE version */ +int sflite_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block); +/* "Decrypt" a VMB coming from the disk, directly using its key. LITE version */ +int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); + +/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk. LEGACY version */ +int sfold_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block); +/* "Decrypt" a VMB coming from the disk, directly using its key. LEGACY version */ +int sfold_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); -/* Create an encrypted empty position map for the given number of slices (allocates memory) */ +/* Create an encrypted empty position map for the given number of slices (allocates memory). LITE version */ void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key); +/* Create an encrypted empty position map for the given number of slices (allocates memory). LEGACY version */ +int sfold_epm_create(size_t nr_slices, char *volume_key, sfold_EncPosMap *epm); #endif /* _HEADER_H_ */ diff --git a/shufflecake-userland-lite/src/header/device_master_block.c b/shufflecake-userland-lite/src/header/device_master_block.c index 0e6ce22..1cfcd9b 100644 --- a/shufflecake-userland-lite/src/header/device_master_block.c +++ b/shufflecake-userland-lite/src/header/device_master_block.c @@ -60,21 +60,21 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool * * @return The error code, 0 on success */ -int sflite_dmb_seal(sflite_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) +int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) { char *salt; int err; /* Sanity check */ - if (dmb->nr_vols > SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); + if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); return EINVAL; } /* Randomise whole block */ - err = sflite_rand_getWeakBytes(disk_block, SFLITE_BLOCK_SIZE); + err = sflc_rand_getWeakBytes(disk_block, SFLC_BLOCK_SIZE); if (err) { - sflite_log_error("Could not randomise DMB; error %d", err); + sflc_log_error("Could not randomise DMB; error %d", err); return err; } @@ -84,12 +84,12 @@ int sflite_dmb_seal(sflite_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_b /* Loop over all VMB keys to encrypt them */ size_t i; for (i = 0; i < dmb->nr_vols; i++) { - char *dmb_cell = (salt + SFLITE_ARGON_SALTLEN) + (i * SFLITE_DMB_CELL_SIZE); + char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); /* Encrypt it */ err = _encryptVmbKeyWithPwd(salt, pwds[i], pwd_lens[i], dmb->vmb_keys[i], dmb_cell); if (err) { - sflite_log_error("Could not encrypt VMB key number %lu; error %d", i, err); + sflc_log_error("Could not encrypt VMB key number %lu; error %d", i, err); return err; } } @@ -106,50 +106,50 @@ int sflite_dmb_seal(sflite_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_b * @param pwd_len Its length * * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= SFLITE_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int sflite_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflite_DmbCell *dmb_cell) +int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell) { // KDF salt char *salt; // The KDF-derived key - char kek[SFLITE_STANDARD_KEYLEN]; + char kek[SFLC_STANDARD_KEYLEN]; // The unlocked VMB key - char vmb_key[SFLITE_STANDARD_KEYLEN]; + char vmb_key[SFLC_STANDARD_KEYLEN]; // Error code int err; /* Derive KEK once and for all */ salt = disk_block; - err = sflite_argon2id_derive(pwd, pwd_len, salt, kek); + err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); if (err) { - sflite_log_error("Could not perform KDF: error %d", err); + sflc_log_error("Could not perform KDF: error %d", err); goto bad_kdf; } - sflite_log_debug("Successfully derived key-encryption-key with KDF"); + sflc_log_debug("Successfully derived key-encryption-key with KDF"); /* Init dmb->vol_idx to invalid */ - dmb_cell->vol_idx = SFLITE_DEV_MAX_VOLUMES; + dmb_cell->vol_idx = SFLC_DEV_MAX_VOLUMES; /* Try all DMB cells */ size_t i; - for (i = 0; i < SFLITE_DEV_MAX_VOLUMES; i++) { - char *enc_dmb_cell = (salt + SFLITE_ARGON_SALTLEN) + (i * SFLITE_DMB_CELL_SIZE); + for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { + char *enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); bool match; /* Try to decrypt this one */ err = _decryptVmbKeyWithPwd(enc_dmb_cell, kek, vmb_key, &match); if (err) { - sflite_log_error("Error decrypting DMB cell number %lu; error %d", i, err); + sflc_log_error("Error decrypting DMB cell number %lu; error %d", i, err); goto bad_decrypt; } /* If MAC matched, mark it, but don't break from the loop (timing attacks) */ if (match) { - sflite_log_debug("The provided password unlocks volume %lu", i); + sflc_log_debug("The provided password unlocks volume %lu", i); dmb_cell->vol_idx = i; - memcpy(dmb_cell->vmb_key, vmb_key, SFLITE_STANDARD_KEYLEN); + memcpy(dmb_cell->vmb_key, vmb_key, SFLC_STANDARD_KEYLEN); } } @@ -160,7 +160,7 @@ int sflite_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflite_DmbCel bad_decrypt: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLITE_STANDARD_KEYLEN); + memset(kek, 0, SFLC_STANDARD_KEYLEN); return err; } @@ -174,28 +174,28 @@ bad_kdf: * * @return Error code, 0 on success */ -int sflite_dmb_setCell(char *disk_block, sflite_DmbCell *dmb_cell, char *pwd, size_t pwd_len) +int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len) { char *salt; char *enc_dmb_cell; int err; /* Sanity check */ - if (dmb_cell->vol_idx >= SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); return EINVAL; } /* Pointers inside DMB */ salt = disk_block; - enc_dmb_cell = (salt + SFLITE_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLITE_DMB_CELL_SIZE); + enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLC_DMB_CELL_SIZE); /* Encrypt with KDF-derived key */ err = _encryptVmbKeyWithPwd(salt, pwd, pwd_len, dmb_cell->vmb_key, enc_dmb_cell); if (err) { - sflite_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); + sflc_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); return err; } - sflite_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); + sflc_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); return 0; } @@ -210,36 +210,36 @@ static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vm { // Pointers inside the block char *iv = dmb_cell; - char *enc_vmb_key = iv + SFLITE_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLITE_STANDARD_KEYLEN; + char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + SFLC_STANDARD_KEYLEN; // Key-encryption-key derived from KDF - char kek[SFLITE_STANDARD_KEYLEN]; + char kek[SFLC_STANDARD_KEYLEN]; // Error code int err; /* Derive KEK */ - err = sflite_argon2id_derive(pwd, pwd_len, salt, kek); + err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); if (err) { - sflite_log_error("Could not perform KDF: error %d", err); + sflc_log_error("Could not perform KDF: error %d", err); goto bad_kdf; } - sflite_log_debug("Successfully derived key-encryption-key with KDF"); + sflc_log_debug("Successfully derived key-encryption-key with KDF"); /* Sample VMB_IV */ - err = sflite_rand_getWeakBytes(iv, SFLITE_AESGCM_PADDED_IVLEN); + err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); if (err) { - sflite_log_error("Could not sample prologue IV: error %d", err); + sflc_log_error("Could not sample prologue IV: error %d", err); goto bad_sample_iv; } - sflite_log_debug("Successfully sampled prologue IV"); + sflc_log_debug("Successfully sampled prologue IV"); /* Encrypt the VMB key */ - err = sflite_aes256gcm_encrypt(kek, vmb_key, SFLITE_STANDARD_KEYLEN, iv, enc_vmb_key, mac); + err = sflc_aes256gcm_encrypt(kek, vmb_key, SFLC_STANDARD_KEYLEN, iv, enc_vmb_key, mac); if (err) { - sflite_log_error("Could not encrypt the VMB key: error %d", err); + sflc_log_error("Could not encrypt the VMB key: error %d", err); goto bad_encrypt; } - sflite_log_debug("Successfully encrypted VMB key with key-encryption-key"); + sflc_log_debug("Successfully encrypted VMB key with key-encryption-key"); // No prob err = 0; @@ -249,7 +249,7 @@ bad_encrypt: bad_sample_iv: bad_kdf: /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLITE_STANDARD_KEYLEN); + memset(kek, 0, SFLC_STANDARD_KEYLEN); return err; } @@ -258,18 +258,18 @@ static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool { // Pointers inside the block char *iv = dmb_cell; - char *enc_vmb_key = iv + SFLITE_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLITE_STANDARD_KEYLEN; + char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; + char *mac = enc_vmb_key + SFLC_STANDARD_KEYLEN; // Error code int err; /* Decrypt the VMB key */ - err = sflite_aes256gcm_decrypt(kek, enc_vmb_key, SFLITE_STANDARD_KEYLEN, mac, iv, vmb_key, match); + err = sflc_aes256gcm_decrypt(kek, enc_vmb_key, SFLC_STANDARD_KEYLEN, mac, iv, vmb_key, match); if (err) { - sflite_log_error("Error while decrypting VMB key: error %d", err); + sflc_log_error("Error while decrypting VMB key: error %d", err); return err; } - sflite_log_debug("Decrypted VMB key: MAC match = %d", *match); + sflc_log_debug("Decrypted VMB key: MAC match = %d", *match); return 0; } diff --git a/shufflecake-userland-lite/src/header/position_map_legacy.c b/shufflecake-userland-lite/src/header/position_map_legacy.c new file mode 100644 index 0000000..923a830 --- /dev/null +++ b/shufflecake-userland-lite/src/header/position_map_legacy.c @@ -0,0 +1,134 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "header.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/math.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/* Create an encrypted empty position map for the given number of slices. + * Allocates the internal pointers of the EPM structure. + * On failure, does not free the allocated memory. + * + * @param nr_slices The number of slices the device will be composed of. + * @param volume_key The volume's data section encryption key, used to encrypt the + * position map as well. + * @param epm The EncPosMap struct to be initialised. + * + * @return Error code, 0 on success */ +int sfold_epm_create(size_t nr_slices, char *volume_key, sfold_EncPosMap *epm) +{ + size_t nr_pmbs; + size_t nr_arrays; + int err; + + // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) + nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + // Each array holds up to 256 PosMapBlocks + nr_arrays = ceil(nr_pmbs, SFLC_SLICE_SCALE); + + // Fill the EPM numeric fields + epm->nr_arrays = nr_arrays; + // All arrays are full except the last one + epm->nr_last_pmbs = nr_pmbs - (SFLC_SLICE_SCALE * (nr_arrays - 1)); + + // Allocate array of IV blocks + epm->iv_blocks = malloc(nr_arrays * sizeof(char *)); + if (!epm->iv_blocks) { + sflc_log_error("Could not malloc array of IV blocks"); + err = ENOMEM; + goto out; + } + // Allocate array of PosMapBlock arrays + epm->pmb_arrays = malloc(nr_arrays * sizeof(char *)); + if (!epm->pmb_arrays) { + sflc_log_error("Could not malloc array of PosMapBlock arrays"); + err = ENOMEM; + goto out; + } + + // Loop to allocate and encrypt each array + int i; + for (i = 0; i < nr_arrays; i++) { + // The last PMB array might be smaller + size_t nr_pmbs_here = ((i == nr_arrays - 1) ? epm->nr_last_pmbs : SFLC_SLICE_SCALE); + size_t pmb_array_size = SFLC_BLOCK_SIZE * nr_pmbs_here; + char *iv_block; + char *pmb_array; + + // Allocate IV block + epm->iv_blocks[i] = malloc(SFLC_BLOCK_SIZE); + if (!epm->iv_blocks[i]) { + sflc_log_error("Could not allocate IV block number %d", i); + err = ENOMEM; + goto out; + } + // Allocate PosMapBlock array + epm->pmb_arrays[i] = malloc(pmb_array_size); + if (!epm->pmb_arrays[i]) { + sflc_log_error("Could not allocate PMB array number %d", i); + err = ENOMEM; + goto out; + } + // Shorthand + iv_block = epm->iv_blocks[i]; + pmb_array = epm->pmb_arrays[i]; + + // Fill the IV block with random data (can ignore return value) + sflc_rand_getWeakBytes(iv_block, SFLC_BLOCK_SIZE); + // Fill the PMB array with 0xFF + memset(pmb_array, SFLC_EPM_FILLER, pmb_array_size); + + // Loop to encrypt each PMB separately with its IV + int j; + for (j = 0; j < nr_pmbs_here; j++) { + char *iv = iv_block + (j * SFLC_AESCTR_IVLEN); + char *pmb = pmb_array + (j * SFLC_BLOCK_SIZE); + + // Encrypt in-place + err = sflc_aes256ctr_encrypt(volume_key, pmb, SFLC_BLOCK_SIZE, iv, NULL); + if (err) { + sflc_log_error("Could not encrypt PMB %d of array %d", j, i); + goto out; + } + } + } + + +out: + return err; +} diff --git a/shufflecake-userland-lite/src/header/position_map.c b/shufflecake-userland-lite/src/header/position_map_lite.c similarity index 88% rename from shufflecake-userland-lite/src/header/position_map.c rename to shufflecake-userland-lite/src/header/position_map_lite.c index 1059378..7782947 100644 --- a/shufflecake-userland-lite/src/header/position_map.c +++ b/shufflecake-userland-lite/src/header/position_map_lite.c @@ -31,7 +31,7 @@ #include #include "header.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/crypto.h" #include "utils/math.h" #include "utils/log.h" @@ -51,25 +51,25 @@ * @return The memory buffer containing the position map */ void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) { - char pmb[SFLITE_BLOCK_SIZE]; - char iv[SFLITE_AESXTS_IVLEN]; + char pmb[SFLC_BLOCK_SIZE]; + char iv[SFLC_AESXTS_IVLEN]; void *epm; size_t nr_pmbs; uint64_t pblk_num; int err; // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) - nr_pmbs = ceil(nr_slices, SFLITE_SLICE_IDX_PER_BLOCK); + nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); // Allocate EPM - epm = malloc(nr_pmbs * SFLITE_BLOCK_SIZE); + epm = malloc(nr_pmbs * SFLC_BLOCK_SIZE); if (!epm) { sflite_log_error("Could not malloc EPM"); return NULL; } // Fill cleartext PMB with 0xFF - memset(pmb, SFLITE_EPM_FILLER, SFLITE_BLOCK_SIZE); + memset(pmb, SFLC_EPM_FILLER, SFLC_BLOCK_SIZE); // First physical block number pblk_num = sflite_pmStartBlock(vol_idx, nr_slices); @@ -77,12 +77,12 @@ void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) int i; for (i = 0; i < nr_pmbs; i++) { // Set IV - memset(iv, 0, SFLITE_AESXTS_IVLEN); + memset(iv, 0, SFLC_AESXTS_IVLEN); *((uint64_t*)iv) = htole64(pblk_num); // Encrypt - err = sflite_aes256xts_encrypt(volume_key, pmb, SFLITE_BLOCK_SIZE, iv, - epm + i*SFLITE_BLOCK_SIZE); + err = sflite_aes256xts_encrypt(volume_key, pmb, SFLC_BLOCK_SIZE, iv, + epm + i*SFLC_BLOCK_SIZE); if (err) { sflite_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); free(epm); diff --git a/shufflecake-userland-lite/src/header/volume_master_block.c b/shufflecake-userland-lite/src/header/volume_master_block_legacy.c similarity index 67% rename from shufflecake-userland-lite/src/header/volume_master_block.c rename to shufflecake-userland-lite/src/header/volume_master_block_legacy.c index e44963b..30ab258 100644 --- a/shufflecake-userland-lite/src/header/volume_master_block.c +++ b/shufflecake-userland-lite/src/header/volume_master_block_legacy.c @@ -41,10 +41,10 @@ *****************************************************/ /* Serialise the VMB before encrypting it */ -static void _serialiseVmb(sflite_Vmb *vmb, char *clear_vmb); +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb); /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflite_Vmb *vmb); +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); /***************************************************** @@ -61,44 +61,44 @@ static int _deserialiseVmb(char *clear_vmb, sflite_Vmb *vmb); * * @return The error code, 0 on success */ -int sflite_vmb_seal(sflite_Vmb *vmb, char *vmb_key, char *disk_block) +int sfold_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) { // Pointers inside the block char *iv = disk_block; - char *enc_vmb = iv + SFLITE_AESCTR_IVLEN; + char *enc_vmb = iv + SFLC_AESCTR_IVLEN; // Serialised VMB (dynamically allocated), to be encrypted char *clear_vmb; // Error code int err; /* Allocate large buffer on the heap */ - clear_vmb = malloc(SFLITE_CLEAR_VMB_LEN); + clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); if (!clear_vmb) { - sflite_log_error("Could not allocate %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); + sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); err = ENOMEM; goto bad_clear_alloc; } - sflite_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); + sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); /* Serialise the struct */ _serialiseVmb(vmb, clear_vmb); - sflite_log_debug("Serialised VMB struct"); + sflc_log_debug("Serialised VMB struct"); /* Sample VMB IV */ - err = sflite_rand_getWeakBytes(iv, SFLITE_AESGCM_PADDED_IVLEN); + err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); if (err) { - sflite_log_error("Could not sample VMB IV: error %d", err); + sflc_log_error("Could not sample VMB IV: error %d", err); goto bad_sample_iv; } - sflite_log_debug("Successfully sampled VMB IV"); + sflc_log_debug("Successfully sampled VMB IV"); /* Encrypt the VMB */ - err = sflite_aes256ctr_encrypt(vmb_key, clear_vmb, SFLITE_CLEAR_VMB_LEN, iv, enc_vmb); + err = sflc_aes256ctr_encrypt(vmb_key, clear_vmb, SFLC_CLEAR_VMB_LEN, iv, enc_vmb); if (err) { - sflite_log_error("Could not encrypt VMB: error %d", err); + sflc_log_error("Could not encrypt VMB: error %d", err); goto bad_encrypt; } - sflite_log_debug("Successfully encrypted VMB"); + sflc_log_debug("Successfully encrypted VMB"); // No prob err = 0; @@ -107,7 +107,7 @@ int sflite_vmb_seal(sflite_Vmb *vmb, char *vmb_key, char *disk_block) bad_encrypt: bad_sample_iv: /* Always wipe and free the cleartext VMB, even on success */ - memset(clear_vmb, 0, SFLITE_CLEAR_VMB_LEN); + memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); free(clear_vmb); bad_clear_alloc: return err; @@ -123,40 +123,40 @@ bad_clear_alloc: * * @return An error code, 0 on success */ -int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflite_Vmb *vmb) +int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) { // Pointers inside the block char *iv = disk_block; - char *enc_vmb = iv + SFLITE_AESCTR_IVLEN; + char *enc_vmb = iv + SFLC_AESCTR_IVLEN; // Decrypted VMB (dynamically allocated), to be deserialised char *clear_vmb; // Error code int err; /* Allocate large buffer on the heap */ - clear_vmb = malloc(SFLITE_CLEAR_VMB_LEN); + clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); if (!clear_vmb) { - sflite_log_error("Could not allocate %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); + sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); err = ENOMEM; goto bad_clear_alloc; } - sflite_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLITE_CLEAR_VMB_LEN); + sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); /* Decrypt the VMB */ - err = sflite_aes256ctr_decrypt(vmb_key, enc_vmb, SFLITE_CLEAR_VMB_LEN, iv, clear_vmb); + err = sflc_aes256ctr_decrypt(vmb_key, enc_vmb, SFLC_CLEAR_VMB_LEN, iv, clear_vmb); if (err) { - sflite_log_error("Error while decrypting VMB: error %d", err); + sflc_log_error("Error while decrypting VMB: error %d", err); goto bad_decrypt; } - sflite_log_debug("Successfully decrypted VMB"); + sflc_log_debug("Successfully decrypted VMB"); /* Deserialise the struct */ err = _deserialiseVmb(clear_vmb, vmb); if (err) { - sflite_log_error("Error while deserialising VMB: error %d", err); + sflc_log_error("Error while deserialising VMB: error %d", err); goto bad_deserialise; } - sflite_log_debug("Deserialised VMB struct"); + sflc_log_debug("Deserialised VMB struct"); // No prob err = 0; @@ -165,7 +165,7 @@ int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflite_Vmb *vmb) bad_deserialise: bad_decrypt: /* Always wipe and free the VMB cleartext, even on success */ - memset(clear_vmb, 0, SFLITE_CLEAR_VMB_LEN); + memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); free(clear_vmb); bad_clear_alloc: return err; @@ -177,18 +177,18 @@ bad_clear_alloc: *****************************************************/ /* Serialise the payload before encrypting it */ -static void _serialiseVmb(sflite_Vmb *vmb, char *clear_vmb) +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLITE_AESXTS_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLITE_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + SFLC_STANDARD_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(p_vol_key, vmb->volume_key, SFLITE_AESXTS_KEYLEN); + memcpy(p_vol_key, vmb->volume_key_legacy, SFLC_STANDARD_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLITE_STANDARD_KEYLEN); + memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_STANDARD_KEYLEN); /* Write the number of slices (network byte order) */ *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); @@ -200,18 +200,18 @@ static void _serialiseVmb(sflite_Vmb *vmb, char *clear_vmb) /* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflite_Vmb *vmb) +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) { // Pointers inside the VMB char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLITE_AESXTS_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLITE_STANDARD_KEYLEN; + char *p_prev_vmb_key = p_vol_key + SFLC_STANDARD_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; /* Copy the volume key */ - memcpy(vmb->volume_key, p_vol_key, SFLITE_AESXTS_KEYLEN); + memcpy(vmb->volume_key_legacy, p_vol_key, SFLC_STANDARD_KEYLEN); /* Copy the previous volume's VMB key */ - memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLITE_STANDARD_KEYLEN); + memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_STANDARD_KEYLEN); /* Read number of slices (network byte order) */ vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); diff --git a/shufflecake-userland-lite/src/header/volume_master_block_lite.c b/shufflecake-userland-lite/src/header/volume_master_block_lite.c new file mode 100644 index 0000000..0561836 --- /dev/null +++ b/shufflecake-userland-lite/src/header/volume_master_block_lite.c @@ -0,0 +1,223 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include // Network byte order + +#include "header.h" +#include "utils/crypto.h" +#include "utils/string.h" +#include "utils/log.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Serialise the VMB before encrypting it */ +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb); + +/* Deserialise the VMB after decrypting it */ +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Builds the on-disk master block (indistinguishable from random). + * + * @param vmb The useful information stored in this volume master block + * @param vmb_key The key encrypting the VMB + * @param disk_block The 4096-byte buffer that will contain the random-looking + * bytes to be written on-disk + * + * @return The error code, 0 on success + */ +int sflite_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) +{ + // Pointers inside the block + char *iv = disk_block; + char *enc_vmb = iv + SFLC_AESCTR_IVLEN; + // Serialised VMB (dynamically allocated), to be encrypted + char *clear_vmb; + // Error code + int err; + + /* Allocate large buffer on the heap */ + clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); + if (!clear_vmb) { + sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + err = ENOMEM; + goto bad_clear_alloc; + } + sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + + /* Serialise the struct */ + _serialiseVmb(vmb, clear_vmb); + sflc_log_debug("Serialised VMB struct"); + + /* Sample VMB IV */ + err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); + if (err) { + sflc_log_error("Could not sample VMB IV: error %d", err); + goto bad_sample_iv; + } + sflc_log_debug("Successfully sampled VMB IV"); + + /* Encrypt the VMB */ + err = sflc_aes256ctr_encrypt(vmb_key, clear_vmb, SFLC_CLEAR_VMB_LEN, iv, enc_vmb); + if (err) { + sflc_log_error("Could not encrypt VMB: error %d", err); + goto bad_encrypt; + } + sflc_log_debug("Successfully encrypted VMB"); + + // No prob + err = 0; + + +bad_encrypt: +bad_sample_iv: + /* Always wipe and free the cleartext VMB, even on success */ + memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); + free(clear_vmb); +bad_clear_alloc: + return err; +} + + +/** + * Decrypt the VMB payload using the VMB key. + * + * @param disk_block The content of the on-disk encrypted VMB + * @param vmb_key The proposed VMB key to unseal its payload + * @param vmb A pointer to the output struct that will contain all the VMB fields + * + * @return An error code, 0 on success + */ +int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) +{ + // Pointers inside the block + char *iv = disk_block; + char *enc_vmb = iv + SFLC_AESCTR_IVLEN; + // Decrypted VMB (dynamically allocated), to be deserialised + char *clear_vmb; + // Error code + int err; + + /* Allocate large buffer on the heap */ + clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); + if (!clear_vmb) { + sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + err = ENOMEM; + goto bad_clear_alloc; + } + sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); + + /* Decrypt the VMB */ + err = sflc_aes256ctr_decrypt(vmb_key, enc_vmb, SFLC_CLEAR_VMB_LEN, iv, clear_vmb); + if (err) { + sflc_log_error("Error while decrypting VMB: error %d", err); + goto bad_decrypt; + } + sflc_log_debug("Successfully decrypted VMB"); + + /* Deserialise the struct */ + err = _deserialiseVmb(clear_vmb, vmb); + if (err) { + sflc_log_error("Error while deserialising VMB: error %d", err); + goto bad_deserialise; + } + sflc_log_debug("Deserialised VMB struct"); + + // No prob + err = 0; + + +bad_deserialise: +bad_decrypt: + /* Always wipe and free the VMB cleartext, even on success */ + memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); + free(clear_vmb); +bad_clear_alloc: + return err; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Serialise the payload before encrypting it */ +static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) +{ + // Pointers inside the VMB + char *p_vol_key = clear_vmb; + char *p_prev_vmb_key = p_vol_key + SFLC_AESXTS_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; + + /* Copy the volume key */ + memcpy(p_vol_key, vmb->volume_key_lite, SFLC_AESXTS_KEYLEN); + + /* Copy the previous volume's VMB key */ + memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_STANDARD_KEYLEN); + + /* Write the number of slices (network byte order) */ + *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); + + // Leave the rest uninitialised + + return; +} + + +/* Deserialise the VMB after decrypting it */ +static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) +{ + // Pointers inside the VMB + char *p_vol_key = clear_vmb; + char *p_prev_vmb_key = p_vol_key + SFLC_AESXTS_KEYLEN; + char *p_nr_slices = p_prev_vmb_key + SFLC_STANDARD_KEYLEN; + + /* Copy the volume key */ + memcpy(vmb->volume_key_lite, p_vol_key, SFLC_AESXTS_KEYLEN); + + /* Copy the previous volume's VMB key */ + memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_STANDARD_KEYLEN); + + /* Read number of slices (network byte order) */ + vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); + + // Ignore the rest + + return 0; +} + From 79df245acf4061213c892120dfeaed32dd46e440 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 23 Aug 2024 17:13:21 +0200 Subject: [PATCH 66/75] Merge operations/ and commands/ --- shufflecake-userland-lite/include/commands.h | 36 +-- .../include/operations.h | 55 ++++- .../include/utils/disk.h | 12 +- .../include/utils/sflc.h | 3 + .../src/commands/change_pwd.c | 8 +- .../src/commands/close.c | 52 ++--- .../src/commands/init_legacy.c | 202 +++++++++++++++++ .../src/commands/{init.c => init_lite.c} | 54 ++--- .../src/commands/open_legacy.c | 207 ++++++++++++++++++ .../src/commands/{open.c => open_lite.c} | 62 ++++-- .../src/commands/test_pwd.c | 6 +- .../src/header/volume_master_block_legacy.c | 2 +- .../src/header/volume_master_block_lite.c | 2 +- .../src/operations/devmapper_legacy.c | 111 ++++++++++ .../{devmapper.c => devmapper_lite.c} | 22 +- .../src/operations/dmb.c | 52 ++--- .../src/operations/volume_header_legacy.c | 165 ++++++++++++++ .../{volume_header.c => volume_header_lite.c} | 34 +-- 18 files changed, 917 insertions(+), 168 deletions(-) create mode 100644 shufflecake-userland-lite/src/commands/init_legacy.c rename shufflecake-userland-lite/src/commands/{init.c => init_lite.c} (71%) create mode 100644 shufflecake-userland-lite/src/commands/open_legacy.c rename shufflecake-userland-lite/src/commands/{open.c => open_lite.c} (70%) create mode 100644 shufflecake-userland-lite/src/operations/devmapper_legacy.c rename shufflecake-userland-lite/src/operations/{devmapper.c => devmapper_lite.c} (83%) create mode 100644 shufflecake-userland-lite/src/operations/volume_header_legacy.c rename shufflecake-userland-lite/src/operations/{volume_header.c => volume_header_lite.c} (79%) diff --git a/shufflecake-userland-lite/include/commands.h b/shufflecake-userland-lite/include/commands.h index d21c767..6531bf0 100644 --- a/shufflecake-userland-lite/include/commands.h +++ b/shufflecake-userland-lite/include/commands.h @@ -50,8 +50,8 @@ typedef struct { /* Underlying block device */ char *bdev_path; - /* Shufflecake mode (legacy,lite,full) */ - int sflite_mode; + /* Shufflecake mode */ + int sflc_mode; /* Number of volumes */ size_t nr_vols; /* Volumes' passwords */ @@ -60,7 +60,7 @@ typedef struct /* Option to skip random filling */ bool no_randfill; -} sflite_cmd_InitArgs; +} sflc_cmd_InitArgs; /* Parameters for the open command */ @@ -68,47 +68,51 @@ typedef struct { /* Underlying block device */ char *bdev_path; - /* Shufflecake mode (legacy,lite,full) */ - int sflite_mode; + /* Shufflecake mode */ + int sflc_mode; /* The only password provided */ char *pwd; size_t pwd_len; -} sflite_cmd_OpenArgs; +} sflc_cmd_OpenArgs; typedef struct { /* Underlying block device */ char *bdev_path; /* Shufflecake mode (legacy,lite,full) */ - int sflite_mode; + int sflc_mode; /* Content of the DMB cell */ - sflite_DmbCell *dmb_cell; + sflc_DmbCell *dmb_cell; /* The new password */ char *new_pwd; size_t new_pwd_len; -} sflite_cmd_ChangePwdArgs; +} sflc_cmd_ChangePwdArgs; /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ -/* Create N volumes (only formats the device header, does not open the volumes) */ -int sflite_cmd_initVolumes(sflite_cmd_InitArgs *args); +/* Create N volumes (only formats the device header, does not open the volumes). LITE version */ +int sflite_cmd_initVolumes(sflc_cmd_InitArgs *args); +/* Create N volumes (only formats the device header, does not open the volumes). LEGACY version */ +int sfold_cmd_initVolumes(sflc_cmd_InitArgs *args); -/* Open M volumes, from the first down to the one whose pwd is provided */ -int sflite_cmd_openVolumes(sflite_cmd_OpenArgs *args); +/* Open M volumes, from the first down to the one whose pwd is provided. LITE version */ +int sflite_cmd_openVolumes(sflc_cmd_OpenArgs *args); +/* Open M volumes, from the first down to the one whose pwd is provided. LEGACY version */ +int sfold_cmd_openVolumes(sflc_cmd_OpenArgs *args); /* Close all volumes on the device (reads the list from sysfs) */ -int sflite_cmd_closeVolumes(char *bdev_path); +int sflc_cmd_closeVolumes(char *bdev_path); /* Tests which volume is unlocked by the given password */ -int sflite_cmd_testPwd(sflite_cmd_OpenArgs *args, sflite_DmbCell *dmb_cell); +int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell); /* Changes the specified volume's password */ -int sflite_cmd_changePwd(sflite_cmd_ChangePwdArgs *args); +int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args); #endif /* _COMMANDS_H_ */ diff --git a/shufflecake-userland-lite/include/operations.h b/shufflecake-userland-lite/include/operations.h index 25af9fe..c4aaa81 100644 --- a/shufflecake-userland-lite/include/operations.h +++ b/shufflecake-userland-lite/include/operations.h @@ -37,25 +37,60 @@ #include "utils/math.h" +/***************************************************** + * INLINE FUNCTIONS * + *****************************************************/ + +// Size, in 4096-byte blocks, of a whole volume header (VMB+PM). LEGACY version +static inline size_t sfold_volHeaderSize(size_t nr_slices) +{ + // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) + size_t nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + // Each array holds up to 256 PosMapBlocks + size_t nr_arrays = ceil(nr_pmbs, SFLC_SLICE_SCALE); + + // 1 VMB, the PMBs, and the IV blocks + return 1 + nr_pmbs + nr_arrays; +} + +// Position of the VMB for the given volume. LEGACY version +static inline uint64_t sfold_vmbPosition(size_t vol_idx, size_t nr_slices) +{ + return 1 + ((uint64_t) vol_idx) * ((uint64_t) sfold_volHeaderSize(nr_slices)); +} + + /***************************************************** * PUBLIC FUNCTIONS PROTOTYPES * *****************************************************/ /* Encrypts and writes the DMB to disk */ -int sflite_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflite_Dmb *dmb); +int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb); /* Reads the DMB from disk and outputs the unlocked VMB key */ -int sflite_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflite_DmbCell *dmb_cell); +int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); /* Reads the DMB from disk, changes the relevant DMB cell, and writes it back */ -int sflite_ops_rewriteDmbCell(char *bdev_path, sflite_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); +int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); -/* Encrypts and writes a volume header (VMB+PM) on-disk */ -int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflite_Vmb *vmb, size_t vol_idx); -/* Reads a VMB from disk and unlocks it */ -int sflite_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflite_Vmb *vmb); -/* Build parameter list for ctor in dm_sflite, and send DM ioctl to create virtual block device */ -int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflite_Vmb *vmb); -/* Close the volume via the appropriate ioctl to DM */ +/* Encrypts and writes a volume header (VMB+PM) on-disk. LITE version */ +int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx); +/* Reads a VMB from disk and unlocks it. LITE version */ +int sflite_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb); + +/* Encrypts and writes a volume header (VMB+PM) on-disk. LEGACY version */ +int sfold_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx); +/* Reads a VMB from disk and unlocks it. LEGACY version */ +int sfold_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb); + + +/* Build parameter list for ctor in dm_sflc, and send DM ioctl to create virtual block device. LITE version */ +int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb); +/* Close the volume via the appropriate ioctl to DM. LITE version */ int sflite_ops_closeVolume(char *label); +/* Build parameter list for ctor in dm_sflc, and send DM ioctl to create virtual block device. LEGACY version */ +int sfold_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb); +/* Close the volume via the appropriate ioctl to DM. LEGACY version */ +int sfold_ops_closeVolume(char *label); + #endif /* _OPERATIONS_H_ */ diff --git a/shufflecake-userland-lite/include/utils/disk.h b/shufflecake-userland-lite/include/utils/disk.h index 56256c4..954ebce 100644 --- a/shufflecake-userland-lite/include/utils/disk.h +++ b/shufflecake-userland-lite/include/utils/disk.h @@ -50,25 +50,25 @@ static inline uint32_t sflite_disk_maxSlices(uint64_t size) { uint64_t nr_slices; // Start from upper bound - nr_slices = size / SFLITE_SLICE_SCALE; + nr_slices = size / SFLC_SLICE_SCALE; while(true) { if (nr_slices == 0) break; // Stop when this nr_slices can fit in size, including the header - uint64_t posmap_blocks = ceil(nr_slices, SFLITE_SLICE_IDX_PER_BLOCK); - uint64_t header_size = 1 + SFLITE_DEV_MAX_VOLUMES * (1 + posmap_blocks); - if (header_size + nr_slices*SFLITE_SLICE_SCALE <= size) + uint64_t posmap_blocks = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); + uint64_t header_size = 1 + SFLC_DEV_MAX_VOLUMES * (1 + posmap_blocks); + if (header_size + nr_slices*SFLC_SLICE_SCALE <= size) break; nr_slices--; } - return nr_slices > SFLITE_MAX_SLICES ? SFLITE_MAX_SLICES : (uint32_t) nr_slices; + return nr_slices > SFLC_MAX_SLICES ? SFLC_MAX_SLICES : (uint32_t) nr_slices; } /* LEGACY version */ -#define sfold_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFLC_BLOCKS_PER_PHYS_SLICE) +#define sfold_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFOLD_BLOCKS_PER_PHYS_SLICE) /* We need this inequality to hold, in order for the previous bound to be true */ #if SFLC_DEV_MAX_VOLUMES * 2 > SFLC_SLICE_IDX_PER_BLOCK #error "Invalid combination of parameters, probably SFLC_DEV_MAX_VOLUMES is too big" diff --git a/shufflecake-userland-lite/include/utils/sflc.h b/shufflecake-userland-lite/include/utils/sflc.h index a43efba..499f5ae 100644 --- a/shufflecake-userland-lite/include/utils/sflc.h +++ b/shufflecake-userland-lite/include/utils/sflc.h @@ -53,6 +53,9 @@ #define SFLC_SLICE_SCALE 256 /* blocks in a slice */ #define SFLC_MAX_SLICES (UINT32_MAX - 1) /* 0xFFFFFFFF is reserved */ +/* For legacy */ +#define SFOLD_BLOCKS_PER_PHYS_SLICE (SFLC_SLICE_SCALE + 1) + /* Max number of volumes in a device */ #define SFLC_DEV_MAX_VOLUMES 15 diff --git a/shufflecake-userland-lite/src/commands/change_pwd.c b/shufflecake-userland-lite/src/commands/change_pwd.c index dcac991..b823662 100644 --- a/shufflecake-userland-lite/src/commands/change_pwd.c +++ b/shufflecake-userland-lite/src/commands/change_pwd.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/log.h" @@ -51,8 +51,8 @@ * * @return Error code, 0 on success */ -int sflite_cmd_changePwd(sflite_cmd_ChangePwdArgs *args) +int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args) { - /* Delegate entirely to the function reading the DMB */ - return sflite_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); + /* Delegate entirely to the function rewriting the DMB */ + return sflc_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); } diff --git a/shufflecake-userland-lite/src/commands/close.c b/shufflecake-userland-lite/src/commands/close.c index eff361d..73a7605 100644 --- a/shufflecake-userland-lite/src/commands/close.c +++ b/shufflecake-userland-lite/src/commands/close.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/crypto.h" #include "utils/string.h" #include "utils/file.h" @@ -61,18 +61,18 @@ static int _closeVolumes(char **labels, size_t nr_vols); * * @return Error code, 0 on success */ -int sflite_cmd_closeVolumes(char *bdev_path) +int sflc_cmd_closeVolumes(char *bdev_path) { - char *labels[SFLITE_DEV_MAX_VOLUMES]; + char *labels[SFLC_DEV_MAX_VOLUMES]; size_t nr_vols; int err; /* Allocate labels */ size_t i; - for (i = 0; i < SFLITE_DEV_MAX_VOLUMES; i++) { - labels[i] = malloc(SFLITE_MAX_VOL_NAME_LEN + 1); + for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { + labels[i] = malloc(SFLC_MAX_VOL_NAME_LEN + 1); if (!labels[1]) { - sflite_log_error("Could not allocate volume label %lu", i); + sflc_log_error("Could not allocate volume label %lu", i); return ENOMEM; // Do not free the ones already allocated } } @@ -80,14 +80,14 @@ int sflite_cmd_closeVolumes(char *bdev_path) /* Read them */ err = _buildVolumesList(bdev_path, labels, &nr_vols); if (err) { - sflite_log_error("Could not read volume list from sysfs; error %d", err); + sflc_log_error("Could not read volume list from sysfs; error %d", err); goto out; } /* Close the volumes (in reverse order of opening) */ err = _closeVolumes(labels, nr_vols); if (err) { - sflite_log_error("Could not close volumes; error %d", err); + sflc_log_error("Could not close volumes; error %d", err); goto out; } @@ -96,7 +96,7 @@ int sflite_cmd_closeVolumes(char *bdev_path) out: - for (i = 0; i < SFLITE_DEV_MAX_VOLUMES; i++) { + for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { free(labels[i]); } return err; @@ -111,50 +111,50 @@ out: static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols) { char *bdev_name; - char devid_path[SFLITE_BIGBUFSIZE]; + char devid_path[SFLC_BIGBUFSIZE]; char *str_devid; size_t dev_id; - char nrvolumes_path[SFLITE_BIGBUFSIZE]; + char nrvolumes_path[SFLC_BIGBUFSIZE]; char *str_nrvolumes; /* Get device name as : */ - bdev_name = sflite_disk_getDeviceName(bdev_path); + bdev_name = sflc_disk_getDeviceName(bdev_path); if(!bdev_name) { - sflite_log_error("Could not allocate device name"); + sflc_log_error("Could not allocate device name"); return ENOMEM; } /* Build path to sysfs file containing device ID */ - sprintf(devid_path, "%s/%s/%s", SFLITE_SYSFS_BDEVS_DIR, bdev_name, SFLITE_SYSFS_DEVID_FILENAME); + sprintf(devid_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name, SFLC_SYSFS_DEVID_FILENAME); /* Build path to sysfs file containing number of open volumes */ - sprintf(nrvolumes_path, "%s/%s/%s", SFLITE_SYSFS_BDEVS_DIR, bdev_name, SFLITE_SYSFS_OPENVOLUMES_FILENAME); + sprintf(nrvolumes_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name, SFLC_SYSFS_OPENVOLUMES_FILENAME); /* Read the device ID */ - str_devid = sflite_readFile(devid_path); + str_devid = sflc_readFile(devid_path); if (!str_devid) { - sflite_log_error("Could not read file %s", devid_path); + sflc_log_error("Could not read file %s", devid_path); return EBADF; } /* Parse the device ID */ if (sscanf(str_devid, "%lu", &dev_id) != 1) { - sflite_log_error("Could not parse device ID:\n%s", str_devid); + sflc_log_error("Could not parse device ID:\n%s", str_devid); return EBADF; } /* Read the number of volumes */ - str_nrvolumes = sflite_readFile(nrvolumes_path); + str_nrvolumes = sflc_readFile(nrvolumes_path); if (!str_nrvolumes) { - sflite_log_error("Could not read file %s", nrvolumes_path); + sflc_log_error("Could not read file %s", nrvolumes_path); return EBADF; } /* Parse the number of volumes */ if (sscanf(str_nrvolumes, "%lu", nr_vols) != 1) { - sflite_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); + sflc_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); return EBADF; } /* Just to be sure */ - if (*nr_vols > SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); + if (*nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); return EBADF; } @@ -176,12 +176,12 @@ static int _closeVolumes(char **labels, size_t nr_vols) /* Eazy peazy */ int i; for (i = nr_vols-1; i >= 0; i--) { - err = sflite_ops_closeVolume(labels[i]); + err = sflc_ops_closeVolume(labels[i]); if (err) { - sflite_log_error("Could not close volume %s; error %d", labels[i], err); + sflc_log_error("Could not close volume %s; error %d", labels[i], err); return err; } - sflite_log_debug("Closed volume %s", labels[i]); + sflc_log_debug("Closed volume %s", labels[i]); printf("Closed volume /dev/mapper/%s\n", labels[i]); } diff --git a/shufflecake-userland-lite/src/commands/init_legacy.c b/shufflecake-userland-lite/src/commands/init_legacy.c new file mode 100644 index 0000000..3ee1c81 --- /dev/null +++ b/shufflecake-userland-lite/src/commands/init_legacy.c @@ -0,0 +1,202 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/disk.h" +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * CONSTANTS * + *****************************************************/ + +/* The device is randomised in chunks of 1024 blocks (arbitrary number) */ +#define SFLC_BLOCKS_IN_RAND_CHUNK 1024 +/* That's 4 MiB */ +#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_BLOCK_SIZE) + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Fill the device with random data */ +static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Create N volumes (only formats the device header, does not open the volumes). + * Creates them in order from 0 to N-1, so as to induce a back-linked list on the device. + * + * @param args->bdev_path The path to the underlying block device + * @param args->nr_vols The number of volumes to create + * @param args->pwds The array of passwords for the various volumes + * @param args->pwd_lens The length of each password + * @param args->no_randfill A boolean switch indicating that the volume should not + * be filled entirely with random data prior to formatting. + * + * @return Error code, 0 on success + */ +int sfold_cmd_initVolumes(sflc_cmd_InitArgs *args) +{ + sflc_Dmb dmb; + sflc_Vmb vmb; + int64_t dev_size; + size_t nr_slices; + int err; + + /* Sanity check */ + if (args->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create %lu volumes on a single device", args->nr_vols); + return EINVAL; + } + + /* Get device size */ + dev_size = sflc_disk_getSize(args->bdev_path); + if (dev_size < 0) { + err = -dev_size; + sflc_log_error("Could not get device size for %s; error %d", args->bdev_path, err); + return err; + } + /* Convert to number of slices */ + nr_slices = sfold_disk_maxSlices(dev_size); + sflc_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); + + /* Fill disk with random bytes, if requested */ + if (!args->no_randfill) { + err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); + if (err) { + sflc_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); + return err; + } + } + + /* Fill the DMB */ + dmb.nr_vols = args->nr_vols; + /* Sample the VMB keys */ + size_t i; + for (i = 0; i < dmb.nr_vols; i++) { + err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_STANDARD_KEYLEN); + if (err) { + sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); + return err; + } + } + /* And write (encrypted) to disk */ + err = sflc_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); + if (err) { + sflc_log_error("Could not create DMB and write it to disk; error %d", err); + return err; + } + + /* Write the volume headers */ + vmb.nr_slices = nr_slices; + for (i = 0; i < args->nr_vols; i++) { + /* This volume's prev_vmb_key */ + if (i > 0) { + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_STANDARD_KEYLEN); + } + /* Sample this volume's VEK */ + sflc_rand_getStrongBytes(vmb.volume_key_legacy, SFLC_STANDARD_KEYLEN); + + /* Write complete volume header (VMB + PM) */ + err = sfold_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); + if (err) { + sflc_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); + return err; + } + } + printf("Created %lu volumes on device %s\n", args->nr_vols, args->bdev_path); + + return 0; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Fill the device with random data */ +static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) +{ + char *rand_chunk; + int err; + + /* Allocate chunk */ + rand_chunk = malloc(SFLC_RAND_CHUNK_SIZE); + if (!rand_chunk) { + sflc_log_error("Could not allocate %d bytes for chunk of random data", SFLC_RAND_CHUNK_SIZE); + return ENOMEM; + } + + /* Loop to write random data in chunks */ + uint64_t blocks_remaining = dev_size; + uint64_t sector = 0; + while (blocks_remaining > 0) { + uint64_t blocks_to_write = + (blocks_remaining > SFLC_BLOCKS_IN_RAND_CHUNK) ? SFLC_BLOCKS_IN_RAND_CHUNK : blocks_remaining; + uint64_t bytes_to_write = blocks_to_write * SFLC_BLOCK_SIZE; + + /* Sample random bytes */ + err = sflc_rand_getWeakBytes(rand_chunk, bytes_to_write); + if (err) { + sflc_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); + goto out; + } + + /* Write on disk */ + err = sflc_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); + if (err) { + sflc_log_error("Could not write random bytes on disk; error %d", err); + goto out; + } + + /* Advance loop */ + sector += blocks_to_write; + blocks_remaining -= blocks_to_write; + } + + /* No prob */ + err = 0; + + +out: + free(rand_chunk); + return err; +} + diff --git a/shufflecake-userland-lite/src/commands/init.c b/shufflecake-userland-lite/src/commands/init_lite.c similarity index 71% rename from shufflecake-userland-lite/src/commands/init.c rename to shufflecake-userland-lite/src/commands/init_lite.c index 41a6de8..f65d1b6 100644 --- a/shufflecake-userland-lite/src/commands/init.c +++ b/shufflecake-userland-lite/src/commands/init_lite.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -42,9 +42,9 @@ *****************************************************/ /* The device is randomised in chunks of 1024 blocks (arbitrary number) */ -#define SFLITE_BLOCKS_IN_RAND_CHUNK 1024 +#define SFLC_BLOCKS_IN_RAND_CHUNK 1024 /* That's 4 MiB */ -#define SFLITE_RAND_CHUNK_SIZE (SFLITE_BLOCKS_IN_RAND_CHUNK * SFLITE_BLOCK_SIZE) +#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_BLOCK_SIZE) /***************************************************** @@ -72,36 +72,36 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); * * @return Error code, 0 on success */ -int sflite_cmd_initVolumes(sflite_cmd_InitArgs *args) +int sflite_cmd_initVolumes(sflc_cmd_InitArgs *args) { - sflite_Dmb dmb; - sflite_Vmb vmb; + sflc_Dmb dmb; + sflc_Vmb vmb; int64_t dev_size; size_t nr_slices; int err; /* Sanity check */ - if (args->nr_vols > SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("Cannot create %lu volumes on a single device", args->nr_vols); + if (args->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create %lu volumes on a single device", args->nr_vols); return EINVAL; } /* Get device size */ - dev_size = sflite_disk_getSize(args->bdev_path); + dev_size = sflc_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; - sflite_log_error("Could not get device size for %s; error %d", args->bdev_path, err); + sflc_log_error("Could not get device size for %s; error %d", args->bdev_path, err); return err; } /* Convert to number of slices */ nr_slices = sflite_disk_maxSlices(dev_size); - sflite_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); + sflc_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); /* Fill disk with random bytes, if requested */ if (!args->no_randfill) { err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); if (err) { - sflite_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); + sflc_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); return err; } } @@ -111,16 +111,16 @@ int sflite_cmd_initVolumes(sflite_cmd_InitArgs *args) /* Sample the VMB keys */ size_t i; for (i = 0; i < dmb.nr_vols; i++) { - err = sflite_rand_getStrongBytes(dmb.vmb_keys[i], SFLITE_STANDARD_KEYLEN); + err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_STANDARD_KEYLEN); if (err) { - sflite_log_error("Could not sample VMB key number %lu; error %d", i , err); + sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); return err; } } /* And write (encrypted) to disk */ - err = sflite_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); + err = sflc_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); if (err) { - sflite_log_error("Could not create DMB and write it to disk; error %d", err); + sflc_log_error("Could not create DMB and write it to disk; error %d", err); return err; } @@ -129,15 +129,15 @@ int sflite_cmd_initVolumes(sflite_cmd_InitArgs *args) for (i = 0; i < args->nr_vols; i++) { /* This volume's prev_vmb_key */ if (i > 0) { - memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLITE_STANDARD_KEYLEN); + memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_STANDARD_KEYLEN); } /* Sample this volume's VEK */ - sflite_rand_getStrongBytes(vmb.volume_key, SFLITE_AESXTS_KEYLEN); + sflc_rand_getStrongBytes(vmb.volume_key_lite, SFLC_AESXTS_KEYLEN); /* Write complete volume header (VMB + PM) */ err = sflite_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); if (err) { - sflite_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); + sflc_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); return err; } } @@ -158,9 +158,9 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) int err; /* Allocate chunk */ - rand_chunk = malloc(SFLITE_RAND_CHUNK_SIZE); + rand_chunk = malloc(SFLC_RAND_CHUNK_SIZE); if (!rand_chunk) { - sflite_log_error("Could not allocate %d bytes for chunk of random data", SFLITE_RAND_CHUNK_SIZE); + sflc_log_error("Could not allocate %d bytes for chunk of random data", SFLC_RAND_CHUNK_SIZE); return ENOMEM; } @@ -169,20 +169,20 @@ static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) uint64_t sector = 0; while (blocks_remaining > 0) { uint64_t blocks_to_write = - (blocks_remaining > SFLITE_BLOCKS_IN_RAND_CHUNK) ? SFLITE_BLOCKS_IN_RAND_CHUNK : blocks_remaining; - uint64_t bytes_to_write = blocks_to_write * SFLITE_BLOCK_SIZE; + (blocks_remaining > SFLC_BLOCKS_IN_RAND_CHUNK) ? SFLC_BLOCKS_IN_RAND_CHUNK : blocks_remaining; + uint64_t bytes_to_write = blocks_to_write * SFLC_BLOCK_SIZE; /* Sample random bytes */ - err = sflite_rand_getWeakBytes(rand_chunk, bytes_to_write); + err = sflc_rand_getWeakBytes(rand_chunk, bytes_to_write); if (err) { - sflite_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); + sflc_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); goto out; } /* Write on disk */ - err = sflite_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); + err = sflc_disk_writeManyBlocks(bdev_path, sector, rand_chunk, blocks_to_write); if (err) { - sflite_log_error("Could not write random bytes on disk; error %d", err); + sflc_log_error("Could not write random bytes on disk; error %d", err); goto out; } diff --git a/shufflecake-userland-lite/src/commands/open_legacy.c b/shufflecake-userland-lite/src/commands/open_legacy.c new file mode 100644 index 0000000..077edb9 --- /dev/null +++ b/shufflecake-userland-lite/src/commands/open_legacy.c @@ -0,0 +1,207 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include + +#include "commands.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/disk.h" +#include "utils/file.h" +#include "utils/log.h" +#include "utils/string.h" + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Read the next device ID in sysfs */ +static int _getNextDevId(size_t *next_dev_id); + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Open M volumes, from the first one down to the one whose pwd is provided. + * Scans the DMB cells to find which one is unlocked by the provided pwd; then, + * using the decrypted VMB key, unlocks the M-th VMB; then, iteratively using + * the prev_vmb_key field, unlocks all the previous VMBs; then, using the + * decrypted VMB keys, opens the volumes "in order" from 1 to M. + * + * @param args->bdev_path The underlying block device + * @param args->pwd The password + * @param args->pwd_len The password length + * + * @return Error code (also if no volume could be opened), 0 on success + */ +int sfold_cmd_openVolumes(sflc_cmd_OpenArgs *args) +{ + int64_t dev_size; + size_t nr_slices; + sflc_DmbCell dmb_cell; + sflc_Vmb vmbs[SFLC_DEV_MAX_VOLUMES]; + size_t dev_id; + int err; + char *bdev_name; + char opendev_path[SFLC_BIGBUFSIZE]; + DIR* opendev_dir; + + /* Check if device is already opened and abort if so. */ + /* Get device name as : */ + bdev_name = sflc_disk_getDeviceName(args->bdev_path); + if(!bdev_name) { + sflc_log_error("Could not allocate device name"); + return ENOMEM; + } + /* Build sysfs path of opened device */ + sprintf(opendev_path, "%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name); + /* Step 2: check if directory exists. */ + opendev_dir = opendir(opendev_path); + if (opendev_dir) { + /* Directory exists. */ + closedir(opendev_dir); + err = EEXIST; + sflc_log_error("Device %s seems to be already open; error %d", args->bdev_path, err); + return err; + } + + /* Get number of slices */ + dev_size = sflc_disk_getSize(args->bdev_path); + if (dev_size < 0) { + err = -dev_size; + sflc_log_error("Could not read device size for %s; error %d", args->bdev_path, err); + return err; + } + nr_slices = sflc_disk_maxSlices(dev_size); + + /* Find volume opened by the pwd */ + err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); + if (err) { + sflc_log_error("Could not read DMB; error %d", err); + return err; + } + /* Was there one? */ + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("The provided password opens no volume on the device"); + return EINVAL; + } + printf("Password is correct! Opening volumes...\n"); + + /* Unlock VMBs "backwards" */ + int i; // Needs sign, because loop ends on i>=0 + for (i = dmb_cell.vol_idx; i >= 0; i--) { + /* Which VMB key to use? */ + char *vmb_key; + if (i == dmb_cell.vol_idx) { + // The one unlocked by pwd + vmb_key = dmb_cell.vmb_key; + } else { + // Or the prev_vmb_key from last iteration + vmb_key = vmbs[i+1].prev_vmb_key; + } + + /* Read and unlock VMB */ + err = sfold_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); + if (err) { + sflc_log_error("Could not read VMB %d on device %s; error %d", + i, args->bdev_path, err); + return err; + } + } + + /* Get the ID that will be assigned to the block device */ + err = _getNextDevId(&dev_id); + if (err) { + sflc_log_error("Could not get next device ID; error %d", err); + return err; + } + sflc_log_debug("Next device ID is %lu", dev_id); + + /* Open volumes "in order" */ + for (i = 0; i <= dmb_cell.vol_idx; i++) { + err = sfold_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); + if (err) { + sflc_log_error("Could not open volume %d; error %d. " + "Previous volumes on the device might have already " + "been opened, it's recommended you close them", + i, err); + return err; + } + sflc_log_debug("Successfully opened volume %d with VMB key", i); + printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); + } + + return 0; +} + + +/***************************************************** + * PRIVATE FUNCTIONS PROTOTYPES * + *****************************************************/ + +/* Read the next device ID in sysfs */ +static int _getNextDevId(size_t *next_dev_id) +{ + char *str_nextdevid; + int err; + + /* Read sysfs entry */ + str_nextdevid = sflc_readFile(SFLC_SYSFS_NEXTDEVID); + if (!str_nextdevid) { + sflc_log_error("Could not read sysfs entry %s", SFLC_SYSFS_NEXTDEVID); + return EINVAL; + } + + /* Parse integer */ + if (sscanf(str_nextdevid, "%lu", next_dev_id) != 1) { + sflc_log_error("Error parsing content of file %s", SFLC_SYSFS_NEXTDEVID); + err = EINVAL; + goto err_devid; + } + /* Sanity check */ + if (*next_dev_id >= SFLC_TOT_MAX_DEVICES) { + sflc_log_error("There are already %d open devices, this is the maximum allowed", SFLC_TOT_MAX_DEVICES); + err = E2BIG; + goto err_devid; + } + + /* All good */ + err = 0; + + +err_devid: + free(str_nextdevid); + return err; +} + diff --git a/shufflecake-userland-lite/src/commands/open.c b/shufflecake-userland-lite/src/commands/open_lite.c similarity index 70% rename from shufflecake-userland-lite/src/commands/open.c rename to shufflecake-userland-lite/src/commands/open_lite.c index 11ecddd..5f4fec4 100644 --- a/shufflecake-userland-lite/src/commands/open.c +++ b/shufflecake-userland-lite/src/commands/open_lite.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/crypto.h" #include "utils/disk.h" #include "utils/file.h" @@ -63,33 +63,55 @@ static int _getNextDevId(size_t *next_dev_id); * * @return Error code (also if no volume could be opened), 0 on success */ -int sflite_cmd_openVolumes(sflite_cmd_OpenArgs *args) +int sflite_cmd_openVolumes(sflc_cmd_OpenArgs *args) { int64_t dev_size; size_t nr_slices; - sflite_DmbCell dmb_cell; - sflite_Vmb vmbs[SFLITE_DEV_MAX_VOLUMES]; + sflc_DmbCell dmb_cell; + sflc_Vmb vmbs[SFLC_DEV_MAX_VOLUMES]; size_t dev_id; + char *bdev_name; + char opendev_path[SFLC_BIGBUFSIZE]; + DIR* opendev_dir; int err; + /* Check if device is already opened and abort if so. */ + /* Get device name as : */ + bdev_name = sflc_disk_getDeviceName(args->bdev_path); + if(!bdev_name) { + sflc_log_error("Could not allocate device name"); + return ENOMEM; + } + /* Build sysfs path of opened device */ + sprintf(opendev_path, "%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name); + /* Step 2: check if directory exists. */ + opendev_dir = opendir(opendev_path); + if (opendev_dir) { + /* Directory exists. */ + closedir(opendev_dir); + err = EEXIST; + sflc_log_error("Device %s seems to be already open; error %d", args->bdev_path, err); + return err; + } + /* Get number of slices */ - dev_size = sflite_disk_getSize(args->bdev_path); + dev_size = sflc_disk_getSize(args->bdev_path); if (dev_size < 0) { err = -dev_size; - sflite_log_error("Could not read device size for %s; error %d", args->bdev_path, err); + sflc_log_error("Could not read device size for %s; error %d", args->bdev_path, err); return err; } nr_slices = sflite_disk_maxSlices(dev_size); /* Find volume opened by the pwd */ - err = sflite_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); + err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); if (err) { - sflite_log_error("Could not read DMB; error %d", err); + sflc_log_error("Could not read DMB; error %d", err); return err; } /* Was there one? */ - if (dmb_cell.vol_idx >= SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("The provided password opens no volume on the device"); + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("The provided password opens no volume on the device"); return EINVAL; } printf("Password is correct! Opening volumes...\n"); @@ -110,7 +132,7 @@ int sflite_cmd_openVolumes(sflite_cmd_OpenArgs *args) /* Read and unlock VMB */ err = sflite_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); if (err) { - sflite_log_error("Could not read VMB %d on device %s; error %d", + sflc_log_error("Could not read VMB %d on device %s; error %d", i, args->bdev_path, err); return err; } @@ -119,22 +141,22 @@ int sflite_cmd_openVolumes(sflite_cmd_OpenArgs *args) /* Get the ID that will be assigned to the block device */ err = _getNextDevId(&dev_id); if (err) { - sflite_log_error("Could not get next device ID; error %d", err); + sflc_log_error("Could not get next device ID; error %d", err); return err; } - sflite_log_debug("Next device ID is %lu", dev_id); + sflc_log_debug("Next device ID is %lu", dev_id); /* Open volumes "in order" */ for (i = 0; i <= dmb_cell.vol_idx; i++) { err = sflite_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); if (err) { - sflite_log_error("Could not open volume %d; error %d. " + sflc_log_error("Could not open volume %d; error %d. " "Previous volumes on the device might have already " "been opened, it's recommended you close them", i, err); return err; } - sflite_log_debug("Successfully opened volume %d with VMB key", i); + sflc_log_debug("Successfully opened volume %d with VMB key", i); printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); } @@ -153,21 +175,21 @@ static int _getNextDevId(size_t *next_dev_id) int err; /* Read sysfs entry */ - str_nextdevid = sflite_readFile(SFLITE_SYSFS_NEXTDEVID); + str_nextdevid = sflc_readFile(SFLC_SYSFS_NEXTDEVID); if (!str_nextdevid) { - sflite_log_error("Could not read sysfs entry %s", SFLITE_SYSFS_NEXTDEVID); + sflc_log_error("Could not read sysfs entry %s", SFLC_SYSFS_NEXTDEVID); return EINVAL; } /* Parse integer */ if (sscanf(str_nextdevid, "%lu", next_dev_id) != 1) { - sflite_log_error("Error parsing content of file %s", SFLITE_SYSFS_NEXTDEVID); + sflc_log_error("Error parsing content of file %s", SFLC_SYSFS_NEXTDEVID); err = EINVAL; goto err_devid; } /* Sanity check */ - if (*next_dev_id >= SFLITE_TOT_MAX_DEVICES) { - sflite_log_error("There are already %d open devices, this is the maximum allowed", SFLITE_TOT_MAX_DEVICES); + if (*next_dev_id >= SFLC_TOT_MAX_DEVICES) { + sflc_log_error("There are already %d open devices, this is the maximum allowed", SFLC_TOT_MAX_DEVICES); err = E2BIG; goto err_devid; } diff --git a/shufflecake-userland-lite/src/commands/test_pwd.c b/shufflecake-userland-lite/src/commands/test_pwd.c index 09cd5d3..f794347 100644 --- a/shufflecake-userland-lite/src/commands/test_pwd.c +++ b/shufflecake-userland-lite/src/commands/test_pwd.c @@ -31,7 +31,7 @@ #include "commands.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/log.h" @@ -52,8 +52,8 @@ * * @return Error code, 0 on success */ -int sflite_cmd_testPwd(sflite_cmd_OpenArgs *args, sflite_DmbCell *dmb_cell) +int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell) { /* Delegate entirely to the function reading the DMB */ - return sflite_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); + return sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); } diff --git a/shufflecake-userland-lite/src/header/volume_master_block_legacy.c b/shufflecake-userland-lite/src/header/volume_master_block_legacy.c index 30ab258..d8b7529 100644 --- a/shufflecake-userland-lite/src/header/volume_master_block_legacy.c +++ b/shufflecake-userland-lite/src/header/volume_master_block_legacy.c @@ -123,7 +123,7 @@ bad_clear_alloc: * * @return An error code, 0 on success */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) +int sfold_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) { // Pointers inside the block char *iv = disk_block; diff --git a/shufflecake-userland-lite/src/header/volume_master_block_lite.c b/shufflecake-userland-lite/src/header/volume_master_block_lite.c index 0561836..d61099f 100644 --- a/shufflecake-userland-lite/src/header/volume_master_block_lite.c +++ b/shufflecake-userland-lite/src/header/volume_master_block_lite.c @@ -123,7 +123,7 @@ bad_clear_alloc: * * @return An error code, 0 on success */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) +int sflite_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) { // Pointers inside the block char *iv = disk_block; diff --git a/shufflecake-userland-lite/src/operations/devmapper_legacy.c b/shufflecake-userland-lite/src/operations/devmapper_legacy.c new file mode 100644 index 0000000..a0417da --- /dev/null +++ b/shufflecake-userland-lite/src/operations/devmapper_legacy.c @@ -0,0 +1,111 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include +#include + +#include "header.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/crypto.h" +#include "utils/file.h" +#include "utils/string.h" +#include "utils/dm.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Build parameter list for ctor in dm_sflc, and send DM ioctl to create + * virtual block device. + * + * @param bdev_path The path to the underlying device + * @param dev_id The ID of the underlying block device + * @param vol_idx The index of the volume within the device + * @param vmb Volume metadata + * + * @return Error code, 0 on success + */ +int sfold_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb) +{ + char label[SFLC_BIGBUFSIZE]; + char *hex_key; + char params[SFLC_BIGBUFSIZE]; + uint64_t num_sectors; + int err; + + /* Build volume label */ + sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); + + /* Get the hex version of the volume's data section key */ + hex_key = sflc_toHex(vmb->volume_key_legacy, SFLC_STANDARD_KEYLEN); + if (!hex_key) { + sflc_log_error("Could not encode volume key to hexadecimal"); + err = ENOMEM; + goto err_hexkey; + } + + /* Get the number of logical 512-byte sectors composing the volume */ + num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_SLICE_SCALE * SFLC_BLOCK_SCALE; + + /* Build param list */ + sprintf(params, "%d %lu %s %lu %lu %s", SFLC_MODE_LEGACY, dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); + + /* Issue ioctl */ + err = sflc_dm_create(label, num_sectors, params); + if (err) { + sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); + goto err_dmcreate; + } + err = 0; + + +err_dmcreate: + free(hex_key); +err_hexkey: + return err; +} + + +/** + * Close the volume by issuing the appropriate ioctl to the DM. + * + * @param label The only needed parameter: the ID of the volume. + * + * @return Error code, 0 on success + */ +int sfold_ops_closeVolume(char *label) +{ + /* Issue ioctl */ + return sflc_dm_destroy(label); +} diff --git a/shufflecake-userland-lite/src/operations/devmapper.c b/shufflecake-userland-lite/src/operations/devmapper_lite.c similarity index 83% rename from shufflecake-userland-lite/src/operations/devmapper.c rename to shufflecake-userland-lite/src/operations/devmapper_lite.c index 1d0ebae..5dc610b 100644 --- a/shufflecake-userland-lite/src/operations/devmapper.c +++ b/shufflecake-userland-lite/src/operations/devmapper_lite.c @@ -33,7 +33,7 @@ #include "header.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/crypto.h" #include "utils/file.h" #include "utils/string.h" @@ -46,7 +46,7 @@ *****************************************************/ /** - * Build parameter list for ctor in dm_sflite, and send DM ioctl to create + * Build parameter list for ctor in dm_sflc, and send DM ioctl to create * virtual block device. * * @param bdev_path The path to the underlying device @@ -56,11 +56,11 @@ * * @return Error code, 0 on success */ -int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflite_Vmb *vmb) +int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb) { - char label[SFLITE_BIGBUFSIZE]; + char label[SFLC_BIGBUFSIZE]; char *hex_key; - char params[SFLITE_BIGBUFSIZE]; + char params[SFLC_BIGBUFSIZE]; uint64_t num_sectors; int err; @@ -68,23 +68,23 @@ int sflite_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflite sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); /* Get the hex version of the volume's data section key */ - hex_key = sflite_toHex(vmb->volume_key, SFLITE_AESXTS_KEYLEN); + hex_key = sflc_toHex(vmb->volume_key_lite, SFLC_AESXTS_KEYLEN); if (!hex_key) { - sflite_log_error("Could not encode volume key to hexadecimal"); + sflc_log_error("Could not encode volume key to hexadecimal"); err = ENOMEM; goto err_hexkey; } /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vmb->nr_slices) * SFLITE_SLICE_SCALE * SFLITE_BLOCK_SCALE; + num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_SLICE_SCALE * SFLC_BLOCK_SCALE; /* Build param list */ sprintf(params, "%d %lu %s %lu %lu %s", SFLC_MODE_LITE, dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); /* Issue ioctl */ - err = sflite_dm_create(label, num_sectors, params); + err = sflc_dm_create(label, num_sectors, params); if (err) { - sflite_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); + sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); goto err_dmcreate; } err = 0; @@ -108,5 +108,5 @@ err_hexkey: int sflite_ops_closeVolume(char *label) { /* Issue ioctl */ - return sflite_dm_destroy(label); + return sflc_dm_destroy(label); } diff --git a/shufflecake-userland-lite/src/operations/dmb.c b/shufflecake-userland-lite/src/operations/dmb.c index 31569e7..662742e 100644 --- a/shufflecake-userland-lite/src/operations/dmb.c +++ b/shufflecake-userland-lite/src/operations/dmb.c @@ -33,7 +33,7 @@ #include "header.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -54,30 +54,30 @@ * * @return Error code, 0 on success */ -int sflite_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflite_Dmb *dmb) +int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb) { /* On-disk DMB */ - char enc_dmb[SFLITE_BLOCK_SIZE]; + char enc_dmb[SFLC_BLOCK_SIZE]; /* Error code */ int err; /* Sanity check */ - if (dmb->nr_vols > SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); + if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); return EINVAL; } /* Seal DMB */ - err = sflite_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); + err = sflc_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); if (err) { - sflite_log_error("Coul dnot seal DMB; error %d", err); + sflc_log_error("Coul dnot seal DMB; error %d", err); return err; } /* Write it to disk (at sector 0) */ - err = sflite_disk_writeBlock(bdev_path, 0, enc_dmb); + err = sflc_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { - sflite_log_error("Could not write DMB to disk; error %d", err); + sflc_log_error("Could not write DMB to disk; error %d", err); return err; } @@ -93,26 +93,26 @@ int sflite_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflite_D * @param pwd_len Its length * * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= SFLITE_DEV_MAX_VOLUMES if none could be unlocked) + * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) * * @return Error code, 0 on success */ -int sflite_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflite_DmbCell *dmb) +int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb) { - char enc_dmb[SFLITE_BLOCK_SIZE]; + char enc_dmb[SFLC_BLOCK_SIZE]; int err; /* Read DMB from disk (at sector 0) */ - err = sflite_disk_readBlock(bdev_path, 0, enc_dmb); + err = sflc_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { - sflite_log_error("Could not read DMB from disk; error %d", err); + sflc_log_error("Could not read DMB from disk; error %d", err); return err; } /* Unseal it */ - err = sflite_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); + err = sflc_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); if (err) { - sflite_log_error("Could not unseal DMB; error %d", err); + sflc_log_error("Could not unseal DMB; error %d", err); return err; } @@ -129,35 +129,35 @@ int sflite_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflite_DmbCel * * @return Error code, 0 on success */ -int sflite_ops_rewriteDmbCell(char *bdev_path, sflite_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) +int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) { - char enc_dmb[SFLITE_BLOCK_SIZE]; + char enc_dmb[SFLC_BLOCK_SIZE]; int err; /* Sanity check */ - if (dmb_cell->vol_idx >= SFLITE_DEV_MAX_VOLUMES) { - sflite_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); + if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { + sflc_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); return EINVAL; } /* Read DMB from disk (at sector 0) */ - err = sflite_disk_readBlock(bdev_path, 0, enc_dmb); + err = sflc_disk_readBlock(bdev_path, 0, enc_dmb); if (err) { - sflite_log_error("Could not read DMB from disk; error %d", err); + sflc_log_error("Could not read DMB from disk; error %d", err); return err; } /* Update the relevant cell */ - err = sflite_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); + err = sflc_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); if (err) { - sflite_log_error("Could not update DMB cell; error %d", err); + sflc_log_error("Could not update DMB cell; error %d", err); return err; } /* Write it to disk (at sector 0) */ - err = sflite_disk_writeBlock(bdev_path, 0, enc_dmb); + err = sflc_disk_writeBlock(bdev_path, 0, enc_dmb); if (err) { - sflite_log_error("Could not write DMB to disk; error %d", err); + sflc_log_error("Could not write DMB to disk; error %d", err); return err; } diff --git a/shufflecake-userland-lite/src/operations/volume_header_legacy.c b/shufflecake-userland-lite/src/operations/volume_header_legacy.c new file mode 100644 index 0000000..44ec50c --- /dev/null +++ b/shufflecake-userland-lite/src/operations/volume_header_legacy.c @@ -0,0 +1,165 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +/***************************************************** + * INCLUDE SECTION * + *****************************************************/ + +#include +#include +#include +#include + +#include "header.h" +#include "header.h" +#include "operations.h" +#include "utils/sflc.h" +#include "utils/disk.h" +#include "utils/crypto.h" +#include "utils/log.h" + + +/***************************************************** + * PUBLIC FUNCTIONS DEFINITIONS * + *****************************************************/ + +/** + * Writes a volume header (VMB+PM) on-disk. + * + * @param bdev_path The underlying block device to write the volume header + * @param vmb_key The key to encrypt the VMB + * @param vmb The VMB to encrypt + * @param vol_idx The index of the volume within the device + * + * @return Error code, 0 on success + */ +int sfold_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) +{ + char enc_vmb[SFLC_BLOCK_SIZE]; + sfold_EncPosMap epm; + uint64_t sector; + int err; + + // Encrypt VMB + err = sfold_vmb_seal(vmb, vmb_key, enc_vmb); + if (err) { + sflc_log_error("Could not seal VMB; error %d", err); + goto out; + } + + // Write it to disk + sector = sfold_vmbPosition(vol_idx, vmb->nr_slices); + err = sflc_disk_writeBlock(bdev_path, sector, enc_vmb); + if (err) { + sflc_log_error("Could not write VMB to disk; error %d", err); + goto out; + } + sector += 1; + + // Create encrypted empty position map + err = sfold_epm_create(vmb->nr_slices, vmb->volume_key_legacy, &epm); + if (err) { + sflc_log_error("Could not create encrypted empty position map; error %d", err); + goto out; + } + + // Loop over PMB arrays to write them to disk + int i; + for (i = 0; i < epm.nr_arrays; i++) { + char *iv_block = epm.iv_blocks[i]; + char *pmb_array = epm.pmb_arrays[i]; + size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_SLICE_SCALE); + + // First write the IV block + err = sflc_disk_writeBlock(bdev_path, sector, iv_block); + if (err) { + sflc_log_error("Could not write IV block to disk; error %d", err); + goto out; + } + sector += 1; + + // Then the whole PMB array + err = sflc_disk_writeManyBlocks(bdev_path, sector, pmb_array, nr_pmbs); + if (err) { + sflc_log_error("Could not write PMB array to disk; error %d", err); + goto out; + } + sector += nr_pmbs; + + // Free them both + free(iv_block); + free(pmb_array); + } + + // Free containers + free(epm.iv_blocks); + free(epm.pmb_arrays); + + +out: + return err; +} + + +/** + * Reads a VMB from disk and unlocks it + * + * @param bdev_path The underlying block device + * @param vmb_key The key to decrypt the VMB + * @param nr_slices The number of slices in the device + * @param vol_idx The index of the volume within the device + * + * @output vmb The decrypted VMB + * + * @return Error code, 0 on success + */ +int sfold_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) +{ + char enc_vmb[SFLC_BLOCK_SIZE]; + uint64_t sector; + int err; + + /* Read encrypted VMB from disk */ + sector = sfold_vmbPosition(vol_idx, nr_slices); + err = sflc_disk_readBlock(bdev_path, sector, enc_vmb); + if (err) { + sflc_log_error("Could not read VMB from disk; error %d", err); + return err; + } + + /* Unseal it */ + err = sfold_vmb_unseal(enc_vmb, vmb_key, vmb); + if (err) { + sflc_log_error("Could not unseal VMB; error %d", err); + return err; + } + + /* Compare the number of slices */ + if (nr_slices != vmb->nr_slices) { + sflc_log_error("Incompatible header size: the device size was different when the volumes" + "were created. Did you resize the device %s since last time?", bdev_path); + return EINVAL; + } + + return 0; +} diff --git a/shufflecake-userland-lite/src/operations/volume_header.c b/shufflecake-userland-lite/src/operations/volume_header_lite.c similarity index 79% rename from shufflecake-userland-lite/src/operations/volume_header.c rename to shufflecake-userland-lite/src/operations/volume_header_lite.c index 40e0fda..ce649ab 100644 --- a/shufflecake-userland-lite/src/operations/volume_header.c +++ b/shufflecake-userland-lite/src/operations/volume_header_lite.c @@ -33,7 +33,7 @@ #include "header.h" #include "header.h" #include "operations.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/disk.h" #include "utils/crypto.h" #include "utils/log.h" @@ -53,9 +53,9 @@ * * @return Error code, 0 on success */ -int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflite_Vmb *vmb, size_t vol_idx) +int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) { - char enc_vmb[SFLITE_BLOCK_SIZE]; + char enc_vmb[SFLC_BLOCK_SIZE]; void *epm; uint64_t sector; int err; @@ -63,32 +63,32 @@ int sflite_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflite_Vmb *vmb // Encrypt VMB err = sflite_vmb_seal(vmb, vmb_key, enc_vmb); if (err) { - sflite_log_error("Could not seal VMB; error %d", err); + sflc_log_error("Could not seal VMB; error %d", err); goto out; } // Write it to disk sector = 1 + vol_idx; - err = sflite_disk_writeBlock(bdev_path, sector, enc_vmb); + err = sflc_disk_writeBlock(bdev_path, sector, enc_vmb); if (err) { - sflite_log_error("Could not write VMB to disk; error %d", err); + sflc_log_error("Could not write VMB to disk; error %d", err); goto out; } // Create encrypted empty position map - epm = sflite_epm_create(vmb->nr_slices, vol_idx, vmb->volume_key); + epm = sflite_epm_create(vmb->nr_slices, vol_idx, vmb->volume_key_lite); if (!epm) { - sflite_log_error("Could not create encrypted empty position map."); + sflc_log_error("Could not create encrypted empty position map."); err = ENOMEM; goto out; } // Write to disk sector = sflite_pmStartBlock(vol_idx, vmb->nr_slices); - err = sflite_disk_writeManyBlocks(bdev_path, sector, epm, - ceil(vmb->nr_slices, SFLITE_SLICE_IDX_PER_BLOCK)); + err = sflc_disk_writeManyBlocks(bdev_path, sector, epm, + ceil(vmb->nr_slices, SFLC_SLICE_IDX_PER_BLOCK)); if (err) { - sflite_log_error("Could not write encrypted PosMap; error %d", err); + sflc_log_error("Could not write encrypted PosMap; error %d", err); } free(epm); @@ -110,30 +110,30 @@ out: * * @return Error code, 0 on success */ -int sflite_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflite_Vmb *vmb) +int sflite_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) { - char enc_vmb[SFLITE_BLOCK_SIZE]; + char enc_vmb[SFLC_BLOCK_SIZE]; uint64_t sector; int err; /* Read encrypted VMB from disk */ sector = 1 + vol_idx; - err = sflite_disk_readBlock(bdev_path, sector, enc_vmb); + err = sflc_disk_readBlock(bdev_path, sector, enc_vmb); if (err) { - sflite_log_error("Could not read VMB from disk; error %d", err); + sflc_log_error("Could not read VMB from disk; error %d", err); return err; } /* Unseal it */ err = sflite_vmb_unseal(enc_vmb, vmb_key, vmb); if (err) { - sflite_log_error("Could not unseal VMB; error %d", err); + sflc_log_error("Could not unseal VMB; error %d", err); return err; } /* Compare the number of slices */ if (nr_slices != vmb->nr_slices) { - sflite_log_error("Incompatible header size: the device size was different when the volumes" + sflc_log_error("Incompatible header size: the device size was different when the volumes" "were created. Did you resize the device %s since last time?", bdev_path); return EINVAL; } From 5f25d8f90b27595c032afcdf56af09201ee2c1aa Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Aug 2024 23:30:00 +0200 Subject: [PATCH 67/75] Merge everything else --- shufflecake-userland-lite/Makefile | 4 +- shufflecake-userland-lite/Makefile.sources | 6 +- shufflecake-userland-lite/include/cli.h | 22 ++--- .../include/utils/disk.h | 2 +- shufflecake-userland-lite/src/cli/changepwd.c | 32 +++--- shufflecake-userland-lite/src/cli/close.c | 6 +- shufflecake-userland-lite/src/cli/dispatch.c | 97 +++++++++++-------- shufflecake-userland-lite/src/cli/init.c | 45 +++++---- shufflecake-userland-lite/src/cli/open.c | 26 +++-- shufflecake-userland-lite/src/cli/testpwd.c | 22 ++--- .../src/commands/close.c | 2 +- .../src/commands/open_legacy.c | 2 +- .../src/commands/open_lite.c | 1 + .../src/header/position_map_lite.c | 6 +- shufflecake-userland-lite/src/main.c | 2 +- shufflecake-userland-lite/src/utils/file.c | 4 +- 16 files changed, 157 insertions(+), 122 deletions(-) diff --git a/shufflecake-userland-lite/Makefile b/shufflecake-userland-lite/Makefile index c0d4151..ee59323 100644 --- a/shufflecake-userland-lite/Makefile +++ b/shufflecake-userland-lite/Makefile @@ -61,10 +61,10 @@ DEPS := $(PROJ_DEPS) $(TEST_DEPS) DIRS := $(sort $(dir $(BIN_DIR) $(PROJ_OBJS) $(TEST_OBJS) $(PROJ_DEPS) $(TEST_DEPS))) # The target binaries -MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake-lite +MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake TEST_BIN := $(TEST_OUT_DIR)/tests # Their symlink -MAIN_LINK := shufflecake-lite +MAIN_LINK := shufflecake TEST_LINK := tests diff --git a/shufflecake-userland-lite/Makefile.sources b/shufflecake-userland-lite/Makefile.sources index 0e2a80b..d2313c8 100644 --- a/shufflecake-userland-lite/Makefile.sources +++ b/shufflecake-userland-lite/Makefile.sources @@ -28,9 +28,9 @@ #### PROJ_SRCS := $(addprefix utils/,crypto.c disk.c dm.c file.c string.c input.c) -PROJ_SRCS += $(addprefix header/,position_map.c volume_master_block.c device_master_block.c) -PROJ_SRCS += $(addprefix operations/,volume_header.c devmapper.c dmb.c) -PROJ_SRCS += $(addprefix commands/,init.c open.c close.c test_pwd.c change_pwd.c) +PROJ_SRCS += $(addprefix header/,position_map_legacy.c position_map_lite.c volume_master_block_legacy.c volume_master_block_lite.c device_master_block.c) +PROJ_SRCS += $(addprefix operations/,volume_header_legacy.c volume_header_lite.c devmapper_legacy.c devmapper_lite.c dmb.c) +PROJ_SRCS += $(addprefix commands/,init_legacy.c init_lite.c open_legacy.c open_lite.c close.c test_pwd.c change_pwd.c) PROJ_SRCS += $(addprefix cli/,dispatch.c init.c open.c close.c testpwd.c changepwd.c) PROJ_SRCS += main.c diff --git a/shufflecake-userland-lite/include/cli.h b/shufflecake-userland-lite/include/cli.h index f175931..1c53043 100644 --- a/shufflecake-userland-lite/include/cli.h +++ b/shufflecake-userland-lite/include/cli.h @@ -30,15 +30,15 @@ *****************************************************/ /* Action to create volumes */ -#define SFLITE_CLI_INITACT "init" +#define SFLC_CLI_INITACT "init" /* Action to open volumes */ -#define SFLITE_CLI_OPENACT "open" +#define SFLC_CLI_OPENACT "open" /* Action to close volumes */ -#define SFLITE_CLI_CLOSEACT "close" +#define SFLC_CLI_CLOSEACT "close" /* Action to test password */ -#define SFLITE_CLI_TESTPWDACT "testpwd" +#define SFLC_CLI_TESTPWDACT "testpwd" /* Action to change password */ -#define SFLITE_CLI_CHANGEPWDACT "changepwd" +#define SFLC_CLI_CHANGEPWDACT "changepwd" /***************************************************** @@ -46,18 +46,18 @@ *****************************************************/ /* Called by the main to parse the arguments and dispatch to the right command */ -int sflite_cli_dispatch(int argc, char **argv); +int sflc_cli_dispatch(int argc, char **argv); /* Initializes device and create empty volumes */ -int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill); +int sflc_cli_init(char *block_device, int sflc_mode, int num_volumes, int skip_randfill); /* Open volumes */ -int sflite_cli_open(char *block_device); +int sflc_cli_open(char *block_device, int sflc_mode); /* Close volumes */ -int sflite_cli_close(char *block_device); +int sflc_cli_close(char *block_device); /* Test password */ -int sflite_cli_testPwd(char *block_device); +int sflc_cli_testPwd(char *block_device); /* Change password */ -int sflite_cli_changePwd(char *block_device); +int sflc_cli_changePwd(char *block_device); #endif /* _CLI_H_ */ diff --git a/shufflecake-userland-lite/include/utils/disk.h b/shufflecake-userland-lite/include/utils/disk.h index 954ebce..426921f 100644 --- a/shufflecake-userland-lite/include/utils/disk.h +++ b/shufflecake-userland-lite/include/utils/disk.h @@ -97,7 +97,7 @@ int sflc_disk_readBlock(char *bdev_path, uint64_t bnum, char *buf); int sflc_disk_writeManyBlocks(char *bdev_path, uint64_t bnum, char *buf, size_t num_blocks); /* Writes a single 4096-byte block to the disk */ -#define sflc_disk_writeBlock(bdev_path, bnum, buf) sflite_disk_writeManyBlocks(bdev_path, bnum, buf, 1) +#define sflc_disk_writeBlock(bdev_path, bnum, buf) sflc_disk_writeManyBlocks(bdev_path, bnum, buf, 1) #endif /* _UTILS_DISK_H_ */ diff --git a/shufflecake-userland-lite/src/cli/changepwd.c b/shufflecake-userland-lite/src/cli/changepwd.c index a4f85e7..de37779 100644 --- a/shufflecake-userland-lite/src/cli/changepwd.c +++ b/shufflecake-userland-lite/src/cli/changepwd.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -45,14 +45,14 @@ * * @return Error code, 0 on success */ -int sflite_cli_changePwd(char *block_device) +int sflc_cli_changePwd(char *block_device) { // Requires: block_device is a correct block device path - sflite_cmd_OpenArgs open_args; - sflite_cmd_ChangePwdArgs change_pwd_args; - sflite_DmbCell dmb_cell; - char old_pwd[SFLITE_BIGBUFSIZE]; + sflc_cmd_OpenArgs open_args; + sflc_cmd_ChangePwdArgs change_pwd_args; + sflc_DmbCell dmb_cell; + char old_pwd[SFLC_BIGBUFSIZE]; size_t old_pwd_len; - char new_pwd[SFLITE_BIGBUFSIZE]; + char new_pwd[SFLC_BIGBUFSIZE]; size_t new_pwd_len; int err; @@ -60,9 +60,9 @@ int sflite_cli_changePwd(char *block_device) /* Gather password */ printf("Enter the password you want to change: "); - err = sflite_safeReadPassphrase(old_pwd, SFLITE_BIGBUFSIZE); + err = sflc_safeReadPassphrase(old_pwd, SFLC_BIGBUFSIZE); if (err) { - sflite_log_error("Could not read password; error %d", err); + sflc_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -72,14 +72,14 @@ int sflite_cli_changePwd(char *block_device) open_args.pwd_len = old_pwd_len; /* Test the password */ - err = sflite_cmd_testPwd(&open_args, &dmb_cell); + err = sflc_cmd_testPwd(&open_args, &dmb_cell); if (err) { - sflite_log_error("Could not test password; error %d", err); + sflc_log_error("Could not test password; error %d", err); return err; } /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= SFLITE_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { printf("This password does not unlock any volume.\n"); return 0; } @@ -87,9 +87,9 @@ int sflite_cli_changePwd(char *block_device) /* Gather new password (no secure shell) */ printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); printf("Choose new password for volume %lu: ", dmb_cell.vol_idx); - err = sflite_safeReadLine(new_pwd, SFLITE_BIGBUFSIZE); + err = sflc_safeReadLine(new_pwd, SFLC_BIGBUFSIZE); if (err) { - sflite_log_error("Could not read new password; error %d", err); + sflc_log_error("Could not read new password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -102,9 +102,9 @@ int sflite_cli_changePwd(char *block_device) change_pwd_args.new_pwd_len = new_pwd_len; /* Change password */ - err = sflite_cmd_changePwd(&change_pwd_args); + err = sflc_cmd_changePwd(&change_pwd_args); if (err) { - sflite_log_error("Could not change password; error %d", err); + sflc_log_error("Could not change password; error %d", err); return err; } printf("Password changed successfully.\n"); diff --git a/shufflecake-userland-lite/src/cli/close.c b/shufflecake-userland-lite/src/cli/close.c index ecedda2..da4c02f 100644 --- a/shufflecake-userland-lite/src/cli/close.c +++ b/shufflecake-userland-lite/src/cli/close.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -45,7 +45,7 @@ * * @return Error code, 0 on success */ -int sflite_cli_close(char *block_device) +int sflc_cli_close(char *block_device) { // Requires: block_device is a correct block device path // char bdev_path[SFLITE_BDEV_PATH_MAX_LEN + 2]; // int err; @@ -69,6 +69,6 @@ int sflite_cli_close(char *block_device) // return sflite_cmd_closeVolumes(bdev_path); - return sflite_cmd_closeVolumes(block_device); + return sflc_cmd_closeVolumes(block_device); } diff --git a/shufflecake-userland-lite/src/cli/dispatch.c b/shufflecake-userland-lite/src/cli/dispatch.c index 871b751..0bed6ff 100644 --- a/shufflecake-userland-lite/src/cli/dispatch.c +++ b/shufflecake-userland-lite/src/cli/dispatch.c @@ -32,7 +32,7 @@ #include #include "cli.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/disk.h" #include "utils/log.h" @@ -47,24 +47,25 @@ const char *argp_program_version = "0.5.0"; // Temporary hack const char *argp_program_bug_address = ""; /* Signed integer values representing a handle for each option */ -#define SFLITE_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option -#define SFLITE_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this +#define SFLC_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option +#define SFLC_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this +#define SFLC_OPT_LEGACY_KEY (-'l') /***************************************************** * TYPES * *****************************************************/ -enum sflite_cli_action { - SFLITE_ACT_INIT, - SFLITE_ACT_OPEN, - SFLITE_ACT_CLOSE, - SFLITE_ACT_TESTPWD, - SFLITE_ACT_CHANGEPWD +enum sflc_cli_action { + SFLC_ACT_INIT, + SFLC_ACT_OPEN, + SFLC_ACT_CLOSE, + SFLC_ACT_TESTPWD, + SFLC_ACT_CHANGEPWD }; -struct sflite_cli_arguments { - enum sflite_cli_action act; +struct sflc_cli_arguments { + enum sflc_cli_action act; char *block_device; int sflc_mode; int num_volumes; @@ -111,10 +112,11 @@ static char doc[] = /* Description of each option */ static struct argp_option options[] = { - {"num-volumes", SFLITE_OPT_NUMVOLS_KEY, "num", 0, + {"num-volumes", SFLC_OPT_NUMVOLS_KEY, "num", 0, "Specify number of volumes to be created with `init'. Must be an integer between 1 and 15.", 0 }, // TODO: define MAX_VOLS instead of hardcoding 15 - {"skip-randfill", SFLITE_OPT_SKIPRAND_KEY, 0, 0, + {"skip-randfill", SFLC_OPT_SKIPRAND_KEY, 0, 0, "Skip pre-overwriting block device with random data, only valid with `init'. Faster but less secure. Use only for debugging or testing."}, + {"legacy", SFLC_OPT_LEGACY_KEY, 0, 0, "Use the old (pre-v0.5.0) Shufflecake format. Only valid with `init` and `open'. Use of this option is not recommended. This mode is going to be deprecated in future versions."}, {0} }; @@ -136,11 +138,12 @@ static struct argp argp = {options, _parseArgpKey, args_doc, doc}; * @return Error code, 0 on success */ -int sflite_cli_dispatch(int argc, char **argv) { - struct sflite_cli_arguments arguments; +int sflc_cli_dispatch(int argc, char **argv) { + struct sflc_cli_arguments arguments; arguments.act = -1; arguments.block_device = NULL; + arguments.sflc_mode = SFLC_MODE_LITE; arguments.num_volumes = 0; arguments.skip_randfill = false; @@ -148,36 +151,43 @@ int sflite_cli_dispatch(int argc, char **argv) { argp_parse(&argp, argc, argv, 0, 0, &arguments); /* Check options consistency */ - if (arguments.num_volumes && arguments.act != SFLITE_ACT_INIT) { + if (arguments.num_volumes && arguments.act != SFLC_ACT_INIT) { printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); return EINVAL; } /* Check options consistency */ - if (arguments.skip_randfill && arguments.act != SFLITE_ACT_INIT) { + if (arguments.sflc_mode == SFLC_MODE_LEGACY && + arguments.act != SFLC_ACT_INIT && + arguments.act != SFLC_ACT_OPEN) { + printf("Error: --legacy (-l) can only be combined with `init' or 'open'.\n"); + return EINVAL; + } + /* Check options consistency */ + if (arguments.skip_randfill && arguments.act != SFLC_ACT_INIT) { printf("Error: --skip-randfill can only be combined with `init'.\n"); return EINVAL; } /* Check that input is actually a block device */ - if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !sflite_disk_isBlockDevice(arguments.block_device)) { + if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !sflc_disk_isBlockDevice(arguments.block_device)) { printf("Error: '%s' is not a valid block device.\n", arguments.block_device); return EINVAL; } /* Dispatch to specific command */ - if (arguments.act == SFLITE_ACT_INIT) { - return sflite_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); + if (arguments.act == SFLC_ACT_INIT) { + return sflc_cli_init(arguments.block_device, arguments.sflc_mode, arguments.num_volumes, arguments.skip_randfill); } - if (arguments.act == SFLITE_ACT_OPEN) { - return sflite_cli_open(arguments.block_device); + if (arguments.act == SFLC_ACT_OPEN) { + return sflc_cli_open(arguments.block_device, arguments.sflc_mode); } - if (arguments.act == SFLITE_ACT_CLOSE) { - return sflite_cli_close(arguments.block_device); + if (arguments.act == SFLC_ACT_CLOSE) { + return sflc_cli_close(arguments.block_device); } - if (arguments.act == SFLITE_ACT_TESTPWD) { - return sflite_cli_testPwd(arguments.block_device); + if (arguments.act == SFLC_ACT_TESTPWD) { + return sflc_cli_testPwd(arguments.block_device); } - if (arguments.act == SFLITE_ACT_CHANGEPWD) { - return sflite_cli_changePwd(arguments.block_device); + if (arguments.act == SFLC_ACT_CHANGEPWD) { + return sflc_cli_changePwd(arguments.block_device); } printf("\n"); @@ -191,26 +201,26 @@ int sflite_cli_dispatch(int argc, char **argv) { *****************************************************/ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { - struct sflite_cli_arguments *arguments = state->input; + struct sflc_cli_arguments *arguments = state->input; switch (key) { /* We are parsing an argument (not an option) */ case ARGP_KEY_ARG: /* We are parsing the command */ if (state->arg_num == 0) { - if (strcmp(arg, SFLITE_CLI_INITACT) == 0) { - arguments->act = SFLITE_ACT_INIT; - } else if (strcmp(arg, SFLITE_CLI_OPENACT) == 0) { - arguments->act = SFLITE_ACT_OPEN; - } else if (strcmp(arg, SFLITE_CLI_CLOSEACT) == 0) { - arguments->act = SFLITE_ACT_CLOSE; - } else if (strcmp(arg, SFLITE_CLI_TESTPWDACT) == 0) { - arguments->act = SFLITE_ACT_TESTPWD; - } else if (strcmp(arg, SFLITE_CLI_CHANGEPWDACT) == 0) { - arguments->act = SFLITE_ACT_CHANGEPWD; + if (strcmp(arg, SFLC_CLI_INITACT) == 0) { + arguments->act = SFLC_ACT_INIT; + } else if (strcmp(arg, SFLC_CLI_OPENACT) == 0) { + arguments->act = SFLC_ACT_OPEN; + } else if (strcmp(arg, SFLC_CLI_CLOSEACT) == 0) { + arguments->act = SFLC_ACT_CLOSE; + } else if (strcmp(arg, SFLC_CLI_TESTPWDACT) == 0) { + arguments->act = SFLC_ACT_TESTPWD; + } else if (strcmp(arg, SFLC_CLI_CHANGEPWDACT) == 0) { + arguments->act = SFLC_ACT_CHANGEPWD; } else { argp_error(state, "Invalid action. Please enter one and only one of: `%s', `%s', `%s', '%s', or '%s'.", - SFLITE_CLI_INITACT, SFLITE_CLI_OPENACT, SFLITE_CLI_CLOSEACT, SFLITE_CLI_TESTPWDACT, SFLITE_CLI_CHANGEPWDACT); + SFLC_CLI_INITACT, SFLC_CLI_OPENACT, SFLC_CLI_CLOSEACT, SFLC_CLI_TESTPWDACT, SFLC_CLI_CHANGEPWDACT); } /* We are parsing the block device */ } else if (state->arg_num == 1) { @@ -222,10 +232,13 @@ static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { break; /* We are parsing an option */ - case SFLITE_OPT_NUMVOLS_KEY: + case SFLC_OPT_NUMVOLS_KEY: arguments->num_volumes = atoi(arg); break; - case SFLITE_OPT_SKIPRAND_KEY: + case SFLC_OPT_LEGACY_KEY: + arguments->sflc_mode = SFLC_MODE_LEGACY; + break; + case SFLC_OPT_SKIPRAND_KEY: arguments->skip_randfill = true; break; diff --git a/shufflecake-userland-lite/src/cli/init.c b/shufflecake-userland-lite/src/cli/init.c index 0639bb3..85f5074 100644 --- a/shufflecake-userland-lite/src/cli/init.c +++ b/shufflecake-userland-lite/src/cli/init.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -45,30 +45,31 @@ * * @return Error code, 0 on success */ -int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill) +int sflc_cli_init(char *block_device, int sflc_mode, int num_volumes, int skip_randfill) { // Requires: block_device is a correct block device path - sflite_cmd_InitArgs args; - char str_nrvols[SFLITE_BIGBUFSIZE]; - char *pwds[SFLITE_DEV_MAX_VOLUMES]; - size_t pwd_lens[SFLITE_DEV_MAX_VOLUMES]; + sflc_cmd_InitArgs args; + char str_nrvols[SFLC_BIGBUFSIZE]; + char *pwds[SFLC_DEV_MAX_VOLUMES]; + size_t pwd_lens[SFLC_DEV_MAX_VOLUMES]; int err; args.bdev_path = block_device; + args.sflc_mode = sflc_mode; // Check if number of volumes was nonzero passed by command line already if (num_volumes) { args.nr_vols = num_volumes; } else { // If not, ask user for number of volumes - printf("\nHow many volumes do you want to create (maximum is %d)? ", SFLITE_DEV_MAX_VOLUMES); - err = sflite_safeReadLine(str_nrvols, SFLITE_BIGBUFSIZE); + printf("\nHow many volumes do you want to create (maximum is %d)? ", SFLC_DEV_MAX_VOLUMES); + err = sflc_safeReadLine(str_nrvols, SFLC_BIGBUFSIZE); if (err) { - sflite_log_error("Error: could not read number of volumes; error %d", err); + sflc_log_error("Error: could not read number of volumes; error %d", err); return err; } /* Parse string */ if (sscanf(str_nrvols, "%lu\n", &args.nr_vols) != 1) { - sflite_log_error("Error: could not parse number of volumes"); + sflc_log_error("Error: could not parse number of volumes"); return EINVAL; } } @@ -78,8 +79,8 @@ int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill) printf("Error: number of volumes must be a positive integer"); return EINVAL; } - if (args.nr_vols > SFLITE_DEV_MAX_VOLUMES) { - printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", SFLITE_DEV_MAX_VOLUMES); + if (args.nr_vols > SFLC_DEV_MAX_VOLUMES) { + printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", SFLC_DEV_MAX_VOLUMES); return EINVAL; } @@ -89,13 +90,13 @@ int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill) size_t i; for (i = 0; i < args.nr_vols; i++) { // Allocate pwd - pwds[i] = malloc(SFLITE_BIGBUFSIZE); + pwds[i] = malloc(SFLC_BIGBUFSIZE); /* Read it */ printf("Choose password for volume %lu (must not be empty): ", i); - err = sflite_safeReadLine(pwds[i], SFLITE_BIGBUFSIZE); + err = sflc_safeReadLine(pwds[i], SFLC_BIGBUFSIZE); if (err) { - sflite_log_error("Could not read password for volume %lu; error %d", i, err); + sflc_log_error("Could not read password for volume %lu; error %d", i, err); return err; } @@ -103,7 +104,7 @@ int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill) pwd_lens[i] = strlen(pwds[i]); /* Check non-empty */ if (pwd_lens[i] == 0) { - sflite_log_error("Password cannot be empty!"); + sflc_log_error("Password cannot be empty!"); return EINVAL; } } @@ -114,5 +115,15 @@ int sflite_cli_init(char *block_device, int num_volumes, int skip_randfill) args.no_randfill = skip_randfill; /* Actually perform the command */ - return sflite_cmd_initVolumes(&args); + switch(sflc_mode) + { + case SFLC_MODE_LEGACY: + return sfold_cmd_initVolumes(&args); + case SFLC_MODE_LITE: + return sflite_cmd_initVolumes(&args); + default: + sflc_log_error("WTF, sflc_mode out of bounds!"); + return ENOTRECOVERABLE; + } + } diff --git a/shufflecake-userland-lite/src/cli/open.c b/shufflecake-userland-lite/src/cli/open.c index bc6d70b..ae1cb8d 100644 --- a/shufflecake-userland-lite/src/cli/open.c +++ b/shufflecake-userland-lite/src/cli/open.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -45,10 +45,10 @@ * * @return Error code, 0 on success */ -int sflite_cli_open(char *block_device) +int sflc_cli_open(char *block_device, int sflc_mode) { // Requires: block_device is a correct block device path - sflite_cmd_OpenArgs args; - char pwd[SFLITE_BIGBUFSIZE]; + sflc_cmd_OpenArgs args; + char pwd[SFLC_BIGBUFSIZE]; size_t pwd_len; int err; @@ -56,16 +56,16 @@ int sflite_cli_open(char *block_device) /* Gather password */ printf("Enter the password for the most secret volume you want to open: "); - err = sflite_safeReadPassphrase(pwd, SFLITE_BIGBUFSIZE); + err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); if (err) { - sflite_log_error("Could not read password; error %d", err); + sflc_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ pwd_len = strlen(pwd); /* Check non-empty */ if (pwd_len == 0) { - sflite_log_error("Password cannot be empty!"); + sflc_log_error("Password cannot be empty!"); return EINVAL; } /* Assign them */ @@ -73,5 +73,15 @@ int sflite_cli_open(char *block_device) args.pwd_len = pwd_len; /* Actually perform the command */ - return sflite_cmd_openVolumes(&args); + /* Actually perform the command */ + switch(sflc_mode) + { + case SFLC_MODE_LEGACY: + return sfold_cmd_openVolumes(&args); + case SFLC_MODE_LITE: + return sflite_cmd_openVolumes(&args); + default: + sflc_log_error("WTF, sflc_mode out of bounds!"); + return ENOTRECOVERABLE; + } } diff --git a/shufflecake-userland-lite/src/cli/testpwd.c b/shufflecake-userland-lite/src/cli/testpwd.c index 4bc5695..550df25 100644 --- a/shufflecake-userland-lite/src/cli/testpwd.c +++ b/shufflecake-userland-lite/src/cli/testpwd.c @@ -31,7 +31,7 @@ #include "cli.h" #include "commands.h" -#include "utils/sflite.h" +#include "utils/sflc.h" #include "utils/input.h" #include "utils/log.h" @@ -45,12 +45,12 @@ * * @return Error code, 0 on success */ -int sflite_cli_testPwd(char *block_device) +int sflc_cli_testPwd(char *block_device) { // Requires: block_device is a correct block device path - sflite_cmd_OpenArgs args; - sflite_DmbCell dmb_cell; -// char bdev_path[SFLITE_BDEV_PATH_MAX_LEN + 2]; - char pwd[SFLITE_BIGBUFSIZE]; + sflc_cmd_OpenArgs args; + sflc_DmbCell dmb_cell; +// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; + char pwd[SFLC_BIGBUFSIZE]; size_t pwd_len; int err; @@ -58,9 +58,9 @@ int sflite_cli_testPwd(char *block_device) /* Gather password */ printf("Enter the password you want to test: "); - err = sflite_safeReadPassphrase(pwd, SFLITE_BIGBUFSIZE); + err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); if (err) { - sflite_log_error("Could not read password; error %d", err); + sflc_log_error("Could not read password; error %d", err); return err; } /* You can trust the length of strings input this way */ @@ -70,14 +70,14 @@ int sflite_cli_testPwd(char *block_device) args.pwd_len = pwd_len; /* Actually perform the command */ - err = sflite_cmd_testPwd(&args, &dmb_cell); + err = sflc_cmd_testPwd(&args, &dmb_cell); if (err) { - sflite_log_error("Could not test password; error %d", err); + sflc_log_error("Could not test password; error %d", err); return err; } /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= SFLITE_DEV_MAX_VOLUMES) { + if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { printf("This password does not unlock any volume.\n"); } else { printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); diff --git a/shufflecake-userland-lite/src/commands/close.c b/shufflecake-userland-lite/src/commands/close.c index 73a7605..28e63d4 100644 --- a/shufflecake-userland-lite/src/commands/close.c +++ b/shufflecake-userland-lite/src/commands/close.c @@ -176,7 +176,7 @@ static int _closeVolumes(char **labels, size_t nr_vols) /* Eazy peazy */ int i; for (i = nr_vols-1; i >= 0; i--) { - err = sflc_ops_closeVolume(labels[i]); + err = sflite_ops_closeVolume(labels[i]); if (err) { sflc_log_error("Could not close volume %s; error %d", labels[i], err); return err; diff --git a/shufflecake-userland-lite/src/commands/open_legacy.c b/shufflecake-userland-lite/src/commands/open_legacy.c index 077edb9..66660d4 100644 --- a/shufflecake-userland-lite/src/commands/open_legacy.c +++ b/shufflecake-userland-lite/src/commands/open_legacy.c @@ -103,7 +103,7 @@ int sfold_cmd_openVolumes(sflc_cmd_OpenArgs *args) sflc_log_error("Could not read device size for %s; error %d", args->bdev_path, err); return err; } - nr_slices = sflc_disk_maxSlices(dev_size); + nr_slices = sfold_disk_maxSlices(dev_size); /* Find volume opened by the pwd */ err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); diff --git a/shufflecake-userland-lite/src/commands/open_lite.c b/shufflecake-userland-lite/src/commands/open_lite.c index 5f4fec4..4604719 100644 --- a/shufflecake-userland-lite/src/commands/open_lite.c +++ b/shufflecake-userland-lite/src/commands/open_lite.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "commands.h" #include "operations.h" diff --git a/shufflecake-userland-lite/src/header/position_map_lite.c b/shufflecake-userland-lite/src/header/position_map_lite.c index 7782947..ae2b48a 100644 --- a/shufflecake-userland-lite/src/header/position_map_lite.c +++ b/shufflecake-userland-lite/src/header/position_map_lite.c @@ -64,7 +64,7 @@ void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) // Allocate EPM epm = malloc(nr_pmbs * SFLC_BLOCK_SIZE); if (!epm) { - sflite_log_error("Could not malloc EPM"); + sflc_log_error("Could not malloc EPM"); return NULL; } @@ -81,10 +81,10 @@ void *sflite_epm_create(size_t nr_slices, size_t vol_idx, char *volume_key) *((uint64_t*)iv) = htole64(pblk_num); // Encrypt - err = sflite_aes256xts_encrypt(volume_key, pmb, SFLC_BLOCK_SIZE, iv, + err = sflc_aes256xts_encrypt(volume_key, pmb, SFLC_BLOCK_SIZE, iv, epm + i*SFLC_BLOCK_SIZE); if (err) { - sflite_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); + sflc_log_error("Could not encrypt %d-th block of PosMap; error %d", i , err); free(epm); return NULL; } diff --git a/shufflecake-userland-lite/src/main.c b/shufflecake-userland-lite/src/main.c index 50d86e7..737b57e 100644 --- a/shufflecake-userland-lite/src/main.c +++ b/shufflecake-userland-lite/src/main.c @@ -39,6 +39,6 @@ int main(int argc, char **argv) { - return sflite_cli_dispatch(argc, argv); + return sflc_cli_dispatch(argc, argv); } diff --git a/shufflecake-userland-lite/src/utils/file.c b/shufflecake-userland-lite/src/utils/file.c index 11066b1..a8e70e2 100644 --- a/shufflecake-userland-lite/src/utils/file.c +++ b/shufflecake-userland-lite/src/utils/file.c @@ -47,7 +47,7 @@ char *sflc_readFile(char *path) /* Open file */ fp = fopen(path, "r"); if (fp == NULL) { - sflite_log_error("Could not open file %s", path); + sflc_log_error("Could not open file %s", path); perror("Reason: "); goto bad_fopen; } @@ -60,7 +60,7 @@ char *sflc_readFile(char *path) /* Allocate */ content = malloc(filesize + 1); if (content == NULL) { - sflite_log_error("Could not malloc %d bytes for file content", filesize); + sflc_log_error("Could not malloc %d bytes for file content", filesize); goto bad_malloc; } From 08b298c39c0662711b84e638a4308b04412f17b4 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 27 Aug 2024 20:07:40 +0200 Subject: [PATCH 68/75] Remove duplicate dirs --- dm-vvz/Kbuild | 36 -- dm-vvz/Makefile | 41 -- dm-vvz/SCHOLIA.md | 18 - dm-vvz/crypto.c | 125 ------ dm-vvz/device.c | 177 -------- dm-vvz/posmap.c | 376 ---------------- dm-vvz/read.c | 168 ------- dm-vvz/sysfs.c | 244 ---------- dm-vvz/volume.c | 116 ----- dm-vvz/vvz.c | 382 ---------------- dm-vvz/vvz.h | 194 -------- dm-vvz/vvz_constants.h | 78 ---- dm-vvz/write.c | 148 ------ shufflecake-userland-legacy/Makefile | 131 ------ shufflecake-userland-legacy/Makefile.sources | 49 -- shufflecake-userland-legacy/include/cli.h | 65 --- .../include/commands.h | 113 ----- shufflecake-userland-legacy/include/header.h | 161 ------- .../include/operations.h | 84 ---- .../include/sflc_constants.h | 1 - .../include/utils/crypto.h | 103 ----- .../include/utils/disk.h | 109 ----- .../include/utils/input.h | 46 -- .../include/utils/log.h | 136 ------ .../include/utils/sflc.h | 93 ---- shufflecake-userland-legacy/src/cli/close.c | 74 --- .../src/cli/dispatch.c | 245 ---------- shufflecake-userland-legacy/src/cli/init.c | 118 ----- shufflecake-userland-legacy/src/cli/open.c | 77 ---- .../src/commands/change_pwd.c | 58 --- .../src/commands/close.c | 190 -------- .../src/commands/init.c | 202 --------- .../src/commands/open.c | 206 --------- .../src/header/device_master_block.c | 276 ------------ .../src/header/position_map.c | 134 ------ .../src/header/volume_master_block.c | 223 --------- .../src/operations/devmapper.c | 111 ----- .../src/operations/dmb.c | 167 ------- .../src/operations/volume_header.c | 165 ------- .../src/utils/crypto.c | 424 ------------------ shufflecake-userland-legacy/src/utils/disk.c | 283 ------------ shufflecake-userland-legacy/src/utils/dm.c | 203 --------- .../test/crypto/test_aes256ctr.c | 178 -------- .../test/crypto/test_aes256gcm.c | 160 ------- .../test/crypto/test_argon2id.c | 83 ---- shufflecake-userland-legacy/test/main.c | 80 ---- shufflecake-userland-lite/.gitignore | 11 - shufflecake-userland-lite/include/utils/dm.h | 56 --- .../include/utils/file.h | 36 -- .../include/utils/math.h | 36 -- .../include/utils/string.h | 39 -- shufflecake-userland-lite/src/cli/changepwd.c | 112 ----- shufflecake-userland-lite/src/cli/testpwd.c | 87 ---- .../src/commands/test_pwd.c | 59 --- shufflecake-userland-lite/src/main.c | 44 -- shufflecake-userland-lite/src/utils/file.c | 81 ---- shufflecake-userland-lite/src/utils/input.c | 101 ----- shufflecake-userland-lite/src/utils/string.c | 74 --- .../test/crypto/test_aes256ctr.h | 85 ---- .../test/crypto/test_aes256gcm.h | 91 ---- .../test/crypto/test_argon2id.h | 43 -- shufflecake-userland-lite/test/minunit.h | 10 - .../.gitignore | 0 .../Makefile | 0 .../Makefile.sources | 0 .../include/cli.h | 0 .../include/commands.h | 0 .../include/header.h | 0 .../include/operations.h | 0 .../include/utils/crypto.h | 0 .../include/utils/disk.h | 0 .../include/utils/dm.h | 0 .../include/utils/file.h | 0 .../include/utils/input.h | 0 .../include/utils/log.h | 0 .../include/utils/math.h | 0 .../include/utils/sflc.h | 0 .../include/utils/string.h | 0 .../src/cli/changepwd.c | 0 .../src/cli/close.c | 0 .../src/cli/dispatch.c | 0 .../src/cli/init.c | 0 .../src/cli/open.c | 0 .../src/cli/testpwd.c | 0 .../src/commands/change_pwd.c | 0 .../src/commands/close.c | 0 .../src/commands/init_legacy.c | 0 .../src/commands/init_lite.c | 0 .../src/commands/open_legacy.c | 0 .../src/commands/open_lite.c | 0 .../src/commands/test_pwd.c | 0 .../src/header/device_master_block.c | 0 .../src/header/position_map_legacy.c | 0 .../src/header/position_map_lite.c | 0 .../src/header/volume_master_block_legacy.c | 0 .../src/header/volume_master_block_lite.c | 0 .../src/main.c | 0 .../src/operations/devmapper_legacy.c | 0 .../src/operations/devmapper_lite.c | 0 .../src/operations/dmb.c | 0 .../src/operations/volume_header_legacy.c | 0 .../src/operations/volume_header_lite.c | 0 .../src/utils/crypto.c | 0 .../src/utils/disk.c | 0 .../src/utils/dm.c | 0 .../src/utils/file.c | 0 .../src/utils/input.c | 0 .../src/utils/string.c | 0 .../test/crypto/test_aes256ctr.c | 0 .../test/crypto/test_aes256ctr.h | 0 .../test/crypto/test_aes256gcm.c | 0 .../test/crypto/test_aes256gcm.h | 0 .../test/crypto/test_argon2id.c | 0 .../test/crypto/test_argon2id.h | 0 .../test/main.c | 0 .../test/minunit.h | 0 116 files changed, 7816 deletions(-) delete mode 100644 dm-vvz/Kbuild delete mode 100644 dm-vvz/Makefile delete mode 100644 dm-vvz/SCHOLIA.md delete mode 100644 dm-vvz/crypto.c delete mode 100644 dm-vvz/device.c delete mode 100644 dm-vvz/posmap.c delete mode 100644 dm-vvz/read.c delete mode 100644 dm-vvz/sysfs.c delete mode 100644 dm-vvz/volume.c delete mode 100644 dm-vvz/vvz.c delete mode 100644 dm-vvz/vvz.h delete mode 100644 dm-vvz/vvz_constants.h delete mode 100644 dm-vvz/write.c delete mode 100644 shufflecake-userland-legacy/Makefile delete mode 100644 shufflecake-userland-legacy/Makefile.sources delete mode 100644 shufflecake-userland-legacy/include/cli.h delete mode 100644 shufflecake-userland-legacy/include/commands.h delete mode 100644 shufflecake-userland-legacy/include/header.h delete mode 100644 shufflecake-userland-legacy/include/operations.h delete mode 120000 shufflecake-userland-legacy/include/sflc_constants.h delete mode 100644 shufflecake-userland-legacy/include/utils/crypto.h delete mode 100644 shufflecake-userland-legacy/include/utils/disk.h delete mode 100644 shufflecake-userland-legacy/include/utils/input.h delete mode 100644 shufflecake-userland-legacy/include/utils/log.h delete mode 100644 shufflecake-userland-legacy/include/utils/sflc.h delete mode 100644 shufflecake-userland-legacy/src/cli/close.c delete mode 100644 shufflecake-userland-legacy/src/cli/dispatch.c delete mode 100644 shufflecake-userland-legacy/src/cli/init.c delete mode 100644 shufflecake-userland-legacy/src/cli/open.c delete mode 100644 shufflecake-userland-legacy/src/commands/change_pwd.c delete mode 100644 shufflecake-userland-legacy/src/commands/close.c delete mode 100644 shufflecake-userland-legacy/src/commands/init.c delete mode 100644 shufflecake-userland-legacy/src/commands/open.c delete mode 100644 shufflecake-userland-legacy/src/header/device_master_block.c delete mode 100644 shufflecake-userland-legacy/src/header/position_map.c delete mode 100644 shufflecake-userland-legacy/src/header/volume_master_block.c delete mode 100644 shufflecake-userland-legacy/src/operations/devmapper.c delete mode 100644 shufflecake-userland-legacy/src/operations/dmb.c delete mode 100644 shufflecake-userland-legacy/src/operations/volume_header.c delete mode 100644 shufflecake-userland-legacy/src/utils/crypto.c delete mode 100644 shufflecake-userland-legacy/src/utils/disk.c delete mode 100644 shufflecake-userland-legacy/src/utils/dm.c delete mode 100644 shufflecake-userland-legacy/test/crypto/test_aes256ctr.c delete mode 100644 shufflecake-userland-legacy/test/crypto/test_aes256gcm.c delete mode 100644 shufflecake-userland-legacy/test/crypto/test_argon2id.c delete mode 100644 shufflecake-userland-legacy/test/main.c delete mode 100644 shufflecake-userland-lite/.gitignore delete mode 100644 shufflecake-userland-lite/include/utils/dm.h delete mode 100644 shufflecake-userland-lite/include/utils/file.h delete mode 100644 shufflecake-userland-lite/include/utils/math.h delete mode 100644 shufflecake-userland-lite/include/utils/string.h delete mode 100644 shufflecake-userland-lite/src/cli/changepwd.c delete mode 100644 shufflecake-userland-lite/src/cli/testpwd.c delete mode 100644 shufflecake-userland-lite/src/commands/test_pwd.c delete mode 100644 shufflecake-userland-lite/src/main.c delete mode 100644 shufflecake-userland-lite/src/utils/file.c delete mode 100644 shufflecake-userland-lite/src/utils/input.c delete mode 100644 shufflecake-userland-lite/src/utils/string.c delete mode 100644 shufflecake-userland-lite/test/crypto/test_aes256ctr.h delete mode 100644 shufflecake-userland-lite/test/crypto/test_aes256gcm.h delete mode 100644 shufflecake-userland-lite/test/crypto/test_argon2id.h delete mode 100644 shufflecake-userland-lite/test/minunit.h rename {shufflecake-userland-legacy => shufflecake-userland}/.gitignore (100%) rename {shufflecake-userland-lite => shufflecake-userland}/Makefile (100%) rename {shufflecake-userland-lite => shufflecake-userland}/Makefile.sources (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/cli.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/commands.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/header.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/operations.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/utils/crypto.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/utils/disk.h (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/include/utils/dm.h (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/include/utils/file.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/utils/input.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/utils/log.h (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/include/utils/math.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/include/utils/sflc.h (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/include/utils/string.h (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/cli/changepwd.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/cli/close.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/cli/dispatch.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/cli/init.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/cli/open.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/cli/testpwd.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/commands/change_pwd.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/commands/close.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/commands/init_legacy.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/commands/init_lite.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/commands/open_legacy.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/commands/open_lite.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/commands/test_pwd.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/header/device_master_block.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/header/position_map_legacy.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/header/position_map_lite.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/header/volume_master_block_legacy.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/header/volume_master_block_lite.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/main.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/operations/devmapper_legacy.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/operations/devmapper_lite.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/operations/dmb.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/operations/volume_header_legacy.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/operations/volume_header_lite.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/utils/crypto.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/utils/disk.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/src/utils/dm.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/utils/file.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/utils/input.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/src/utils/string.c (100%) rename {shufflecake-userland-lite => shufflecake-userland}/test/crypto/test_aes256ctr.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/test/crypto/test_aes256ctr.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/test/crypto/test_aes256gcm.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/test/crypto/test_aes256gcm.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/test/crypto/test_argon2id.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/test/crypto/test_argon2id.h (100%) rename {shufflecake-userland-lite => shufflecake-userland}/test/main.c (100%) rename {shufflecake-userland-legacy => shufflecake-userland}/test/minunit.h (100%) diff --git a/dm-vvz/Kbuild b/dm-vvz/Kbuild deleted file mode 100644 index 1ed4b30..0000000 --- a/dm-vvz/Kbuild +++ /dev/null @@ -1,36 +0,0 @@ - # - # Copyright The Shufflecake Project Authors (2022) - # Copyright The Shufflecake Project Contributors (2022) - # Copyright Contributors to the The Shufflecake Project. - # - # See the AUTHORS file at the top-level directory of this distribution and at - # - # - # This file is part of the program shufflecake-c, which is part of the - # Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - # layer for Linux. See . - # - # This program is free software: you can redistribute it and/or modify it - # under the terms of the GNU General Public License as published by the Free - # Software Foundation, either version 2 of the License, or (at your option) - # any later version. 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, see . - # - -MODULE_NAME := dm_vvz -obj-m := $(MODULE_NAME).o - - -OBJ_LIST := vvz.o device.o volume.o sysfs.o crypto.o posmap.o read.o write.o - -$(MODULE_NAME)-y += $(OBJ_LIST) - - -# Normal CC flags -ccflags-y := -O2 -ccflags-y += -I$(src) -ccflags-y += -Wall -Wno-declaration-after-statement diff --git a/dm-vvz/Makefile b/dm-vvz/Makefile deleted file mode 100644 index 982f8ab..0000000 --- a/dm-vvz/Makefile +++ /dev/null @@ -1,41 +0,0 @@ - # - # Copyright The Shufflecake Project Authors (2022) - # Copyright The Shufflecake Project Contributors (2022) - # Copyright Contributors to the The Shufflecake Project. - # - # See the AUTHORS file at the top-level directory of this distribution and at - # - # - # This file is part of the program shufflecake-c, which is part of the - # Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - # layer for Linux. See . - # - # This program is free software: you can redistribute it and/or modify it - # under the terms of the GNU General Public License as published by the Free - # Software Foundation, either version 2 of the License, or (at your option) - # any later version. 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, see . - # - -KERNEL_DIR = /lib/modules/$(shell uname -r)/build -SRC_DIR = $(shell pwd) -BUILD_DIR = $(shell pwd)/bin -BUILD_DIR_MAKEFILE = $(BUILD_DIR)/Makefile - -default: $(BUILD_DIR_MAKEFILE) - make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) modules - -$(BUILD_DIR_MAKEFILE): | $(BUILD_DIR) - echo "# This Makefile does nothing, but Kbuild needs one in this directory" > $@ - -$(BUILD_DIR): - mkdir $@ - - -clean: - rm -rf $(BUILD_DIR) - diff --git a/dm-vvz/SCHOLIA.md b/dm-vvz/SCHOLIA.md deleted file mode 100644 index a8b2439..0000000 --- a/dm-vvz/SCHOLIA.md +++ /dev/null @@ -1,18 +0,0 @@ -#### Workqueues -Apparently, using bound workqueues is recommended, unless the work items are expected to hog the CPU for "huge" amounts of cycles (see the [cmwq docs](https://www.kernel.org/doc/html/v6.6/core-api/workqueue.html)). In fact, `dm-crypt` uses a bound `io_queue` for bio mapping; it also has a `crypt_queue` for encryption/decryption, that is `WQ_CPU_INTENSIVE`: that wq is either bound or unbound, based on the flag `DM_CRYPT_SAME_CPU`. Both these workqueues are `WQ_MEM_RECLAIM`, and we probably need that for Shufflecake too. -As for granularity, almost no DM target uses the kernel-global wq (with `schedule_work()`); many allocate a per-target wq, while some use a module-wide wq. At this first stage, we use a per-device wq, since we imagine the device as the unit of resource sharing; we might hit the concurrency limit (set by `max_active`) in the future, so that's one thing to look out for. -All in all, we can use a per-device bound wq, that is `WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE`, and whose work items process bio's start-to-finish. - -#### Position map: write-back or write-through? -A first idea was to have slice allocation happen exclusively in memory, and only synchronise the position map to disk upon FLUSH requests (write-back posmap), but this gives the scheme a weird and inconsistent *crash behaviour*. -Suppose, for example, that the upper-layer FS keeps an `index` block with a list of all allocated data blocks; suppose that a new data block is written at a position falling in a yet-unmapped slice (triggering slice allocation); the `index` block is consequently updated so that the list also contains a pointer to the new data block; suppose that, by Satan's inscrutable will, the update of the `index` block gets persisted to disk but the system crashes right afterwards, before the on-disk position map is updated; when the system boots back up, the FS will legitimately believe that the data block is allocated (because that's what the `index` block says) and contains all zeros (because READ requests to blocks in unmapped slices return all-zeros, for good reasons). This is bad. -On the other hand, one might possibly argue that the upper layer employed an unsafe sequence of operations, and should have only updated the `index` after a FLUSH request. After all, the all-zeros was just the previous (logical) content of the data block, before it was written by the FS, so it's just as if our driver reordered the two WRITE requests and failed in the middle, which is perfectly legit. Right now, I can't think of a more compelling argument against a write-back position map, but the fact that a WRITE request can complete, only for the affected block to then become "unreachable" (i.e. contain all-zeros) again, is fishy. -Anyway, to avoid headaches, we'll probably go for a write-through position map at first, at least until we discuss this more accurately with someone. Also, this simplifies handling of FLUSH requests: we have nothing to flush, so we just pass them down. This is because there is no volatile cache, since the in-memory view of the position map is write-through. - -#### FLUSH requests and where to find them -How do we even know if a bio is a FLUSH? Main references are the comments in [this source file](https://elixir.bootlin.com/linux/v6.6.9/source/block/blk-flush.c), as well as [these docs](https://www.kernel.org/doc/Documentation/block/writeback_cache_control.txt). The point seems to be that we are unlikely to see `REQ_OP_FLUSH` bio's incoming: rather, we'll receive an empty bio with `REQ_OP_WRITE | REQ_PREFLUSH`. Indeed, that's what `dm-crypt` checks for; there's also a comment there that reads `for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight` although I couldn't confirm that myself. `REQ_FUA` might be set on some bio's, and we should pass it down; I've read somewhere that the device-mapper core will strip it and just send an emtpy FLUSH afterwards, but I haven't found many confirmations of that. - -#### Locking of write-through posmap -About the posmap view being write-through, there is something to add. This first implementation is very crude: when we create a new slice mapping, we hold onto the `posmap_lock` for dear life until the new mapping is persisted on-disk. This approach unnecessarily blocks all new bio's, even unrelated ones (i.e. falling in a different slice); also, the new bio's falling in that same slice could at least start processing, and only wait for the slice mapping to be persisted once they are done, before returning. -There is a fix to both these problems, but it results in the locking scheme for the position map to be a bit more convoluted, so it's better to resist the urge of premature optimisation. We would also reserve the MSB of the posmap entry (which is a `u32`) to signal that the entry "is being written to disk": this limits the range of usable PSIs to `0x00000000` to `0x7FFFFFFE` (with `0x7FFFFFFF` and `0xFFFFFFFF` being the "unmapped LSI" symbol), so we can have at most 2^31-1 PSIs. -The optimised posmap would work as follows. The function `create_slice_mapping()` takes the `posmap_lock`, then samples a new PSIs, then writes it in the posmap **with the MSB set**, then releases the `posmap_lock` (so other bio's can use the posmap), then writes the updated posmap block on the disk. If a new incoming bio falls in the same LSI, it can still proceed even if the MSB of the entry is set ("speculating" that the update of the posmap block will succeed) and use the slice mapping normally to launch the mapped bio; then, just before returning, it waits for the MSB to clear using a waitqueue (as explained in [LDD](https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch05s02.html)). The waitqueue is declared in the volume struct alongside the posmap, and is woken up by `create_slice_mapping()` once the update of the posmap block finishes successfully, after clearing the MSB. diff --git a/dm-vvz/crypto.c b/dm-vvz/crypto.c deleted file mode 100644 index e4a2c0d..0000000 --- a/dm-vvz/crypto.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include -#include -#include "vvz_constants.h" - -#include "vvz.h" - - -/** - * Encrypt/decrypt exactly one block, already encoded in the scatterlist. - * All other crypto functions reduce to this one. - * The IV is constructed as the right-0-padded LE representation of the - * physical block number, which is exactly what dm-crypt does when using the - * IV mode "plain64". - */ -static int crypt_sg(struct crypto_skcipher *tfm, struct scatterlist *src, - struct scatterlist *dst, u64 pblk_num, int rw) -{ - u8 iv[VVZ_XTS_IVLEN]; - struct skcipher_request *req = NULL; - DECLARE_CRYPTO_WAIT(wait); - int err; - - // TODO not too sure about the gfp_mask here - // TODO move @req into struct vvz_io? - req = skcipher_request_alloc(tfm, GFP_NOIO); - if (!req) - return -ENOMEM; - - skcipher_request_set_callback(req, - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, - crypto_req_done, &wait); - - /* Construct IV */ - memset(iv, 0, VVZ_XTS_IVLEN); - *(__le64 *)iv = cpu_to_le64(pblk_num); - - skcipher_request_set_crypt(req, src, dst, VVZ_BLOCK_SIZE, iv); - if (rw == READ) - err = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); - else - err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); - skcipher_request_free(req); - - return err; -} - -/* Encrypt-decrypt a single block (memory buffer is a page) */ -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw) -{ - struct scatterlist dst, src, *p_dst; - bool is_inplace; - - /* Use same scatterlist if in-place */ - is_inplace = (src_page == dst_page); - p_dst = is_inplace ? &src : &dst; - - /* We assume PAGE_SIZE == VVZ_BLOCK_SIZE */ - /* And orig_bio to start at offset 0 within the page */ - sg_init_table(&src, 1); - sg_set_page(&src, src_page, VVZ_BLOCK_SIZE, 0); - if (!is_inplace) { - sg_init_table(&dst, 1); - sg_set_page(&dst, dst_page, VVZ_BLOCK_SIZE, 0); - } - - return crypt_sg(tfm, &src, p_dst, pblk_num, rw); -} - - -/* Encrypt-decrypt consecutive blocks (memory buffer is vmalloc'ed) */ -int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, - u64 num_blocks, u64 first_pblk_num, int rw) -{ - struct scatterlist dst, src, *p_dst; - u64 pblk_num; - bool is_inplace; - int err; - - /* Use same scatterlist if in-place */ - is_inplace = (src_buf == dst_buf); - p_dst = is_inplace ? &src : &dst; - - for (pblk_num = first_pblk_num; - pblk_num < first_pblk_num + num_blocks; - pblk_num++) { - sg_init_one(&src, src_buf, VVZ_BLOCK_SIZE); - if (!is_inplace) - sg_init_one(&dst, dst_buf, VVZ_BLOCK_SIZE); - - err = crypt_sg(tfm, &src, p_dst, pblk_num, rw); - if (err) - return err; - - src_buf += VVZ_BLOCK_SIZE; - dst_buf += VVZ_BLOCK_SIZE; - } - - return 0; -} - diff --git a/dm-vvz/device.c b/dm-vvz/device.c deleted file mode 100644 index fd7cab3..0000000 --- a/dm-vvz/device.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include -#include -#include -#include "vvz.h" - - -/* Depth of the mempool backing the bio_set */ -#define VVZ_BIOSET_BIOS 64 - - -/* Fisher-Yates shuffle */ -static void fisheryates_u32(u32 *v, u32 len) -{ - u32 i, j; - - for (i = len-1; i >= 1; i--) { - j = get_random_u32_below(i+1); - swap(v[i], v[j]); - } - - return; -} - -struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices) -{ - struct vvz_device *sdev; - dev_t devt; - int i; - int err; - - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); - if (!sdev) { - DMERR("Could not allocate device"); - return ERR_PTR(-ENOMEM); - } - sdev->dev_id = dev_id; - sdev->nr_volumes = 0; - - /* Look up block device and set name */ - err = lookup_bdev(bdev_path, &devt); - if (err) { - DMERR("Could not look up block device"); - goto bad_lookup; - } - format_dev_t(sdev->name, devt); - - /* Compute sizes */ - sdev->tot_slices = tot_slices; - sdev->nr_free_slices = tot_slices; - /* Enough posmap blocks to fit all the entries */ - sdev->posmap_size_sectors = VVZ_BLOCK_SCALE * - DIV_ROUND_UP(tot_slices, VVZ_PSIS_PER_BLOCK); - /* DMB + VMBs + PosMaps */ - sdev->dev_header_size_sectors = VVZ_BLOCK_SCALE + - (VVZ_DEV_MAX_VOLUMES * VVZ_BLOCK_SCALE) + - (VVZ_DEV_MAX_VOLUMES * sdev->posmap_size_sectors); - - /* Shuffled PSIs */ - mutex_init(&sdev->slices_lock); - sdev->slices_ofld = vzalloc(tot_slices * sizeof(bool)); - if (!sdev->slices_ofld) { - DMERR("Could not allocate PSI occupation bitfield"); - err = -ENOMEM; - goto bad_ofld; - } - - sdev->prmslices = vmalloc(tot_slices * sizeof(u32)); - if (!sdev->prmslices) { - DMERR("Could not allocate shuffled PSI array"); - err = -ENOMEM; - goto bad_prmslices; - } - /* Generate a permutation */ - for (i = 0; i < tot_slices; i++) - sdev->prmslices[i] = i; - fisheryates_u32(sdev->prmslices, tot_slices); - sdev->prmslices_octr = 0; - - /* Bioset */ - err = bioset_init(&sdev->bioset, VVZ_BIOSET_BIOS, 0, BIOSET_NEED_BVECS); - if (err) { - DMERR("Could not init bioset; error %d", err); - goto bad_bioset; - } - - /* Client for dm-io */ - sdev->io_client = dm_io_client_create(); - if (IS_ERR(sdev->io_client)) { - err = PTR_ERR(sdev->io_client); - DMERR("Could not create dm-io client; error %d", err); - goto bad_dmio_client; - } - - /* I/O workqueue */ - sdev->io_queue = alloc_workqueue("vvz_%s_io", - WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, - 0, sdev->name); - if (!sdev->io_queue) { - err = -ENOMEM; - DMERR("Could not allocate I/O workqueue"); - goto bad_io_wq; - } - /* Decryption workqueue */ - sdev->crypt_queue = alloc_workqueue("vvz_%s_crypt", - WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, - 0, sdev->name); - if (!sdev->crypt_queue) { - err = -ENOMEM; - DMERR("Could not allocate decryption workqueue"); - goto bad_crypt_wq; - } - - /* Register to sysfs, once initialised */ - err = vvz_sysfs_register_device(sdev); - if (err) - goto bad_sysfs; - - return sdev; - - -bad_sysfs: - destroy_workqueue(sdev->crypt_queue); -bad_crypt_wq: - destroy_workqueue(sdev->io_queue); -bad_io_wq: - dm_io_client_destroy(sdev->io_client); -bad_dmio_client: - bioset_exit(&sdev->bioset); -bad_bioset: - vfree(sdev->prmslices); -bad_prmslices: - vfree(sdev->slices_ofld); -bad_ofld: -bad_lookup: - kfree(sdev); - return ERR_PTR(err); -} - - -void vvz_dev_destroy(struct vvz_device *sdev) -{ - vvz_sysfs_unregister_device(sdev); - destroy_workqueue(sdev->crypt_queue); - destroy_workqueue(sdev->io_queue); - dm_io_client_destroy(sdev->io_client); - bioset_exit(&sdev->bioset); - vfree(sdev->prmslices); - vfree(sdev->slices_ofld); - kfree(sdev); - - return; -} - diff --git a/dm-vvz/posmap.c b/dm-vvz/posmap.c deleted file mode 100644 index 6d8711c..0000000 --- a/dm-vvz/posmap.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include -#include "vvz.h" - - -/* Helpers */ - -#define IS_PSI_TAKEN(sdev, psi) ( (sdev)->slices_ofld[(psi)] ) -#define NEXT_RANDOM_PSI(sdev) ( (sdev)->prmslices[(sdev)->prmslices_octr] ) -#define IS_LAST_LSI_IN_BLOCK(lsi, sdev) ( (((lsi)+1) % VVZ_PSIS_PER_BLOCK == 0) || \ - (((lsi)+1) == (sdev)->tot_slices) ) - - -/* - *---------------------------- - * Create slice mapping - *---------------------------- - */ - -/** - * Return the next free PSI in the device's shuffled array, without modifying - * the device state. - * - * MUTEX: @sdev->slices_lock must be held. - */ -static int peek_next_free_psi(struct vvz_device *sdev, u32 *psi) -{ - if (unlikely(!sdev->nr_free_slices)) - return -ENOSPC; - if (unlikely(sdev->prmslices_octr >= sdev->tot_slices)) { - DMCRIT("octr = %u, tot_slices = %u, free_slices = %u", sdev->prmslices_octr, sdev->tot_slices, sdev->nr_free_slices); - print_hex_dump(KERN_CRIT, "prmslices(REV) ", DUMP_PREFIX_OFFSET, 32, 4, sdev->prmslices, 4*sdev->tot_slices, false); - msleep(10000); - print_hex_dump(KERN_CRIT, "ofld(REV) ", DUMP_PREFIX_OFFSET, 32, 1, sdev->slices_ofld, sdev->tot_slices, false); - msleep(10000); - return -ENOTRECOVERABLE; // Grave inconsistency - } - - /* Invariant: @prmslices_octr points to a free slice */ - *psi = NEXT_RANDOM_PSI(sdev); - if (unlikely(IS_PSI_TAKEN(sdev, *psi))){ - DMCRIT("octr = %u, tot_slices = %u, free_slices = %u", sdev->prmslices_octr, sdev->tot_slices, sdev->nr_free_slices); - DMCRIT("PSI %u is occupied", *psi); - print_hex_dump(KERN_CRIT, "prmslices ", DUMP_PREFIX_OFFSET, 32, 4, sdev->prmslices, 4*sdev->tot_slices, false); - msleep(10000); - print_hex_dump(KERN_CRIT, "ofld ", DUMP_PREFIX_OFFSET, 32, 1, sdev->slices_ofld, sdev->tot_slices, false); - msleep(10000); - return -ENOTRECOVERABLE; // Grave inconsistency - } - - return 0; -} - -/** - * Map LSI => PSI, only in memory. - * Sanity checks to be performed by the caller. - * - * MUTEX: @sdev->slices_lock must be held. - * MUTEX: @svol->posmap_lock must be held, except under volume ctor. - */ -static void _create_local_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 psi) -{ - struct vvz_device *sdev = svol->sdev; - - /* Grab it from the device */ - sdev->slices_ofld[psi] = true; - sdev->nr_free_slices--; - // Preserve the invariant: @prmslices_octr must point to a free slice - while(sdev->prmslices_octr < sdev->tot_slices && - IS_PSI_TAKEN(sdev, NEXT_RANDOM_PSI(sdev))) { - sdev->prmslices_octr++; - } - - /* Insert in the volume */ - svol->posmap[lsi] = psi; - svol->nr_mapped_slices++; - - return; -} - -/** - * Delete mapping for the given LSI, only in memory. - * Sanity checks to be performed by the caller. - * - * MUTEX: @svol->posmap_lock must be held, except under volume ctor. - */ -static void _delete_local_slice_mapping(struct vvz_volume *svol, u32 lsi) -{ - /* Delete mapping in the volume */ - svol->posmap[lsi] = VVZ_PSI_INVALID; - svol->nr_mapped_slices--; - - /* Don't do anything in the device though, leave it there: we don't yet - * have an obvious way to release PSIs. - * This means a PSI will be incorrectly marked as occupied, but that's - * not too bad: the PSI shuffling and its occupation counter are - * ephemeral, so they reset if you close and reopen all the volumes. */ - return; -} - -/** - * Synchronously store (and flush) the given posmap block - * - * MUTEX: @svol->posmap_lock must be held, except under volume ctor. - */ -static int store_posmap_block(struct vvz_volume *svol, u32 posmap_block_num) -{ - struct vvz_device *sdev = svol->sdev; - struct page *page; - struct bio *bio; - int err; - - /* Sync + flush TODO GFP mask ok? */ - bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, - REQ_OP_WRITE | REQ_SYNC | REQ_FUA, GFP_NOIO, - &sdev->bioset); - if (!bio) { - DMERR("Could not allocate posmap block bio"); - return -ENOMEM; - } - bio->bi_iter.bi_sector = VVZ_POSMAP_START_SECTOR(svol) + - (posmap_block_num << VVZ_BLOCK_SHIFT); - - /* Alloc and add page TODO GFP mask */ - page = alloc_page(GFP_NOIO); - if (!page) { - DMERR("Could not allocate posmap block page"); - err = -ENOMEM; - goto bad_alloc_page; - } - // TODO remove this error check - if (unlikely(!bio_add_page(bio, page, VVZ_BLOCK_SIZE, 0))) { - DMCRIT("Could not add posmap block page to bio!"); - err = -ENOTRECOVERABLE; - goto bad_add_page; - } - - /* Serialise posmap block onto the page */ - void *page_ptr = kmap_local_page(page); - u32 first_lsi = posmap_block_num * VVZ_PSIS_PER_BLOCK; - u32 last_lsi = min(first_lsi + VVZ_PSIS_PER_BLOCK, sdev->tot_slices); - u32 lsi; - for (lsi = first_lsi; lsi < last_lsi; lsi++) { - u32 psi = svol->posmap[lsi]; - __be32 *be_psi = (__be32*) (page_ptr + ((lsi-first_lsi) * sizeof(__be32))); - *be_psi = cpu_to_be32(psi); - } - -// print_hex_dump(KERN_WARNING, "page_ptr(REV) ", DUMP_PREFIX_OFFSET, 32, 4, page_ptr, VVZ_BLOCK_SIZE, false); -// msleep(100); - - kunmap_local(page_ptr); - - /* Encrypt the block in place */ - err = vvz_crypt_block_page(svol->tfm, page, page, - bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); - if (err) { - DMERR("Could not encrypt posmap block; error %d", err); - goto bad_encrypt; - } - - /* Submit */ - err = submit_bio_wait(bio); - if (err) - DMERR("Could not complete posmap block bio; error %d", err); - -bad_encrypt: -bad_add_page: - __free_page(page); -bad_alloc_page: - bio_put(bio); - return err; -} - - -/** - * Create a new mapping for the given LSI, and synchronise back to disk. - * - * MUTEX: @svol->posmap_lock must be held, except under volume ctor. - * MUTEX: takes @sdev->slices_lock. - * - * Syncing to disk means the posmap lock will be held (by the caller) for a long - * time thus blocking out all the other incoming bio's, even unrelated ones - * (falling in different slices). Several strategies are possible to avoid this - * problem, but for now we keep this simple implementation. - */ -int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *psi) -{ - struct vvz_device *sdev = svol->sdev; - int err; - - /* Bounds check TODO redundant? */ - if(unlikely(lsi >= svol->sdev->tot_slices)) - return -EINVAL; - /* Check mapping not existent TODO redundant? */ - if (unlikely(svol->posmap[lsi] != VVZ_PSI_INVALID)) - return -EINVAL; - - /* Create mapping */ - if (mutex_lock_interruptible(&sdev->slices_lock)) - return -ERESTARTSYS; - err = peek_next_free_psi(sdev, psi); - if (err) { - mutex_unlock(&sdev->slices_lock); - return err; - } - _create_local_slice_mapping(svol, lsi, *psi); - mutex_unlock(&sdev->slices_lock); - - /* Write posmap block to disk */ - err = store_posmap_block(svol, lsi/VVZ_PSIS_PER_BLOCK); - if (err) { - DMERR("Could not store posmap block; error %d", err); - _delete_local_slice_mapping(svol, lsi); - return err; - } - - return 0; -} - - -/* - *---------------------------- - * Load position map - *---------------------------- - */ - -/** - * Synchronously read the entire on-disk encrypted position map - * - * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). - */ -static int read_encrypted_posmap(struct vvz_volume *svol) -{ - struct dm_io_request io_req = { - .bi_opf = REQ_OP_READ | REQ_SYNC, - .mem.type = DM_IO_VMA, - .mem.ptr.vma = svol->posmap, - .notify.fn = NULL, - .client = svol->sdev->io_client - }; - struct dm_io_region io_region = { - .bdev = svol->dm_dev->bdev, - .sector = VVZ_POSMAP_START_SECTOR(svol), - .count = svol->sdev->posmap_size_sectors - }; - - return dm_io(&io_req, 1, &io_region, NULL); -} - -/** - * De-serialise the position map entries. On the fly, if a conflict is detected, - * resolve it by sampling a new PSI, and sync to disk (block by block). - * - * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). - * MUTEX: @sdev->slices_lock must be held. - */ -static int _deserialise_and_sanitise_posmap(struct vvz_volume *svol) -{ - struct vvz_device *sdev = svol->sdev; - void *posmap_ptr = svol->posmap; - u32 lsi; - bool posmap_block_dirty; - int err; - - for (lsi = 0; lsi < sdev->tot_slices; lsi++) { - /* Reset dirty bit at the start of every posmap block */ - if (lsi % VVZ_PSIS_PER_BLOCK == 0) - posmap_block_dirty = false; - - /* De-serialise posmap entry */ - __be32 *be_psi = (__be32*) (posmap_ptr + (lsi * sizeof(__be32))); - u32 psi = be32_to_cpu(*be_psi); - - /* If LSI unmapped, skip mapping creation */ - if (psi == VVZ_PSI_INVALID) { - svol->posmap[lsi] = psi; - goto skip_create_mapping; - } - - /* If PSI out of bounds, something's seriously wrong */ - if (psi >= sdev->tot_slices) { - DMERR("Decrypted PSI out of bounds: %u >= %u", psi, sdev->tot_slices); - return -EDOM; - } - - /* If PSI already taken, sample a new one */ - if (sdev->slices_ofld[psi]) { - DMWARN("Corruption of volume %lu: LSI %u was evicted from PSI %u", - svol->vol_idx, lsi, psi); - err = peek_next_free_psi(sdev, &psi); - if (err) - return err; - posmap_block_dirty = true; - } - /* Whether sanitised or not, create the mapping locally */ - _create_local_slice_mapping(svol, lsi, psi); - -skip_create_mapping: - - /* Only check dirty bit at the end of the posmap block */ - if (posmap_block_dirty && - IS_LAST_LSI_IN_BLOCK(lsi, sdev)) { - err = store_posmap_block(svol, lsi/VVZ_PSIS_PER_BLOCK); - if (err) - return err; - } - } - - return 0; -} - - -/** - * Load the volume's position map from the disk. If some conflicts are present - * (i.e. an LSI is mapped to a PSI that's already taken), then resolve them - * (i.e. re-sample a free PSI for the "unlucky" LSI) and sync back to disk. - * - * MUTEX: no need for the caller to hold @svol->posmap_lock (we are in ctor). - * MUTEX: takes @sdev->slices_lock. - */ -int vvz_load_and_sanitise_posmap(struct vvz_volume *svol) -{ - int err; - struct vvz_device *sdev = svol->sdev; - - /* Read raw posmap from disk */ - err = read_encrypted_posmap(svol); - if (err) - return err; - - /* Decrypt in place */ - err = vvz_crypt_blocks_vm(svol->tfm, svol->posmap, svol->posmap, - svol->sdev->posmap_size_sectors >> VVZ_BLOCK_SHIFT, - VVZ_POSMAP_START_SECTOR(svol) >> VVZ_BLOCK_SHIFT, - READ); - if (err) - return err; - - /* Deserialise and sanitise as you go */ - if (mutex_lock_interruptible(&sdev->slices_lock)) - return -ERESTARTSYS; - err = _deserialise_and_sanitise_posmap(svol); - mutex_unlock(&sdev->slices_lock); - if (err) - return err; - -// print_hex_dump(KERN_CRIT, "posmap(REV) ", DUMP_PREFIX_OFFSET, 32, 4, svol->posmap, 4*sdev->tot_slices, false); -// msleep(2000); - - return 0; -} - diff --git a/dm-vvz/read.c b/dm-vvz/read.c deleted file mode 100644 index cd61934..0000000 --- a/dm-vvz/read.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include "vvz.h" -#include - - -static void vvz_read_endio(struct bio *phys_bio); -static void vvz_decrypt_work_fn(struct work_struct *work); - - -/* Landing here from ->map() through the io_queue */ -void vvz_read_work_fn(struct work_struct *work) -{ - struct vvz_io *sio = container_of(work, struct vvz_io, work); - struct vvz_volume *svol = sio->svol; - struct vvz_device *sdev = svol->sdev; - struct bio *orig_bio = sio->orig_bio; - struct bio *phys_bio; - u32 lsi = sio->lsi; - u32 block_offset = sio->block_offset; - u32 psi; - - /* Read position map */ - if (mutex_lock_interruptible(&svol->posmap_lock)) { - orig_bio->bi_status = BLK_STS_IOERR; - goto endio; - } - psi = svol->posmap[lsi]; - mutex_unlock(&svol->posmap_lock); - - /* If LSI is unmapped, short-circuit and return all zeros */ - if (psi == VVZ_PSI_INVALID) { - - zero_fill_bio(orig_bio); - orig_bio->bi_status = BLK_STS_OK; - goto endio; - } - sio->psi = psi; - -// DMWARN("READ: LSI=%u, PSI=%u, offset=%u", lsi, psi, sio->block_offset); -// msleep(100); - - /* Shallow-copy the bio and submit it (different bi_endio). - We can shallow-copy because we don't need to own the pages, - we can decrypt in place. */ - - - //DMWARN("READ: shallow copying"); - //msleep(500); - - /* Shallow copy */ - phys_bio = bio_alloc_clone(svol->dm_dev->bdev, orig_bio, GFP_NOIO, &sdev->bioset); - if (!phys_bio) { - DMERR("Could not clone original bio"); - orig_bio->bi_status = BLK_STS_IOERR; - goto endio; - } - /* Insert in the I/O struct */ - sio->phys_bio = phys_bio; - -// DMWARN("READ: submitting bio"); -// msleep(500); - - /* Remap sector */ - phys_bio->bi_iter.bi_sector = VVZ_PHYS_BIO_SECTOR(sdev, psi, block_offset); - /* Set fields for the endio */ - phys_bio->bi_private = sio; - phys_bio->bi_end_io = vvz_read_endio; - /* Submit */ - dm_submit_bio_remap(orig_bio, phys_bio); - - return; - - -endio: - bio_endio(orig_bio); - return; -} - - -/* ISR for the phys_bio */ -static void vvz_read_endio(struct bio *phys_bio) -{ - struct vvz_io *sio = phys_bio->bi_private; - -// DMWARN("READ ENDIO: queueing decryption"); -// //msleep(500); - - /* Can't decrypt here in ISR: submit to decryption workqueue. - * Can reuse the same work item, though, since it was popped out of the - * io_queue already */ - INIT_WORK(&sio->work, vvz_decrypt_work_fn); - queue_work(sio->svol->sdev->crypt_queue, &sio->work); -} - - -/* Decrypt and endio */ -static void vvz_decrypt_work_fn(struct work_struct *work) -{ - struct vvz_io *sio = container_of(work, struct vvz_io, work); - struct vvz_volume *svol = sio->svol; - struct bio *orig_bio = sio->orig_bio; - struct bio *phys_bio = sio->phys_bio; - struct bio_vec bvl = bio_iovec(orig_bio); - int err; - - /* If physical bio failed, then fail-fast */ - if (phys_bio->bi_status != BLK_STS_OK) { - orig_bio->bi_status = phys_bio->bi_status; - goto endio; - } - -// DMWARN("DECRYPT FN: decrypting page in place"); -// msleep(2000); - - /* Decrypt page in-place */ - err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, bvl.bv_page, - VVZ_PHYS_BIO_SECTOR(svol->sdev, sio->psi, sio->block_offset) >> VVZ_BLOCK_SHIFT, - READ); - if (err) { - DMERR("Could not decrypt bio; error %d", err); - orig_bio->bi_status = BLK_STS_IOERR; - goto endio; - } - -// print_hex_dump(KERN_WARNING, "readpage ", DUMP_PREFIX_OFFSET, 32, 1, bvl.bv_page, VVZ_BLOCK_SIZE, true); -// msleep(2000); - -// DMWARN("DECRYPT FN: bio_advance"); -// msleep(300); - - /* Advance original bio by one block */ - bio_advance(orig_bio, VVZ_BLOCK_SIZE); - orig_bio->bi_status = BLK_STS_OK; - -endio: - /* Free the physical bio */ -// DMWARN("DECRYPT FN: bio_put"); -// msleep(300); - bio_put(phys_bio); - /* End original bio */ -// DMWARN("DECRYPT FN: bio_endio\n\n\n\n"); -// msleep(300); - bio_endio(orig_bio); - - return; -} diff --git a/dm-vvz/sysfs.c b/dm-vvz/sysfs.c deleted file mode 100644 index efd3df2..0000000 --- a/dm-vvz/sysfs.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include "vvz.h" - -/* - *---------------------------- - * Top-level entries - *---------------------------- - */ - -static ssize_t next_dev_id_show(struct module_attribute *mattr, struct module_kobject *mkobj, char *buf) -{ - ssize_t ret; - - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return -ERESTARTSYS; - ret = sysfs_emit(buf, "%u\n", vvz_free_devid); - mutex_unlock(&vvz_alldevs_lock); - - return ret; -} - -static struct kset *bdevs_kset; -static struct module_attribute devid_mattr = __ATTR_RO(next_dev_id); - -int vvz_sysfs_init() -{ - int err; - - bdevs_kset = kset_create_and_add(VVZ_SYSFS_BDEVS, NULL, &THIS_MODULE->mkobj.kobj); - if (!bdevs_kset) { - err = -ENOMEM; - DMERR("Could not create %s kset", VVZ_SYSFS_BDEVS); - goto bad_bdevs; - } - - err = sysfs_create_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); - if (err) { - DMERR("Could not create %s file", VVZ_SYSFS_DEVID); - goto bad_devid; - } - - return 0; - - -bad_devid: - kset_unregister(bdevs_kset); -bad_bdevs: - return err; -} - -void vvz_sysfs_exit() -{ - sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &devid_mattr.attr); - kset_unregister(bdevs_kset); -} - - -/* - *---------------------------- - * Device entries - *---------------------------- - */ - -static ssize_t dev_id_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) -{ - struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - - return sysfs_emit(buf, "%u\n", sdev->dev_id); -} - -static ssize_t volumes_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) -{ - struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - - return sysfs_emit(buf, "%lu\n", sdev->nr_volumes); -} - -static ssize_t tot_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) -{ - struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - - return sysfs_emit(buf, "%u\n", sdev->tot_slices); -} - -static ssize_t free_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) -{ - struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - int ret; - - if (mutex_lock_interruptible(&sdev->slices_lock)) - return -ERESTARTSYS; - ret = sysfs_emit(buf, "%u\n", sdev->nr_free_slices); - mutex_unlock(&sdev->slices_lock); - - return ret; -} - -static struct kobj_attribute dev_id_kattr = __ATTR_RO(dev_id); -static struct kobj_attribute volumes_kattr = __ATTR_RO(volumes); -static struct kobj_attribute tot_slices_kattr = __ATTR_RO(tot_slices); -static struct kobj_attribute free_slices_kattr = __ATTR_RO(free_slices); -static struct attribute *vvz_device_default_attrs[] = { - &dev_id_kattr.attr, - &volumes_kattr.attr, - &tot_slices_kattr.attr, - &free_slices_kattr.attr, - NULL -}; -ATTRIBUTE_GROUPS(vvz_device_default); - -static void vvz_device_kobj_release(struct kobject *kobj) -{ - struct vvz_device *sdev = container_of(kobj, struct vvz_device, kobj); - complete(&sdev->kobj_released); -} - -static struct kobj_type vvz_device_ktype = { - .release = vvz_device_kobj_release, - .sysfs_ops = &kobj_sysfs_ops, - .default_groups = vvz_device_default_groups -}; - -int vvz_sysfs_register_device(struct vvz_device *sdev) -{ - int err; - - /* Completion */ - init_completion(&sdev->kobj_released); - - /* Register directory :/ under bdevs/ */ - sdev->kobj.kset = bdevs_kset; - err = kobject_init_and_add(&sdev->kobj, &vvz_device_ktype, NULL, - "%s", sdev->name); - if (err) - goto bad; - /* Emit uevent */ - kobject_uevent(&sdev->kobj, KOBJ_ADD); - - return 0; - - -bad: - kobject_put(&sdev->kobj); - wait_for_completion(&sdev->kobj_released); - return err; -} - -void vvz_sysfs_unregister_device(struct vvz_device *sdev) -{ - kobject_put(&sdev->kobj); - wait_for_completion(&sdev->kobj_released); -} - - -/* - *---------------------------- - * Volume entries - *---------------------------- - */ - -static ssize_t mapped_slices_show(struct kobject *kobj, struct kobj_attribute *kattr, char *buf) -{ - struct vvz_volume *svol = container_of(kobj, struct vvz_volume, kobj); - int ret; - - if (mutex_lock_interruptible(&svol->posmap_lock)) - return -ERESTARTSYS; - ret = sysfs_emit(buf, "%u\n", svol->nr_mapped_slices); - mutex_unlock(&svol->posmap_lock); - - return ret; -} - -static struct kobj_attribute mapped_slices_kattr = __ATTR_RO(mapped_slices); -static struct attribute *vvz_volume_default_attrs[] = { - &mapped_slices_kattr.attr, - NULL -}; -ATTRIBUTE_GROUPS(vvz_volume_default); - -static void vvz_volume_kobj_release(struct kobject *kobj) -{ - struct vvz_volume *svol = container_of(kobj, struct vvz_volume, kobj); - - complete(&svol->kobj_released); -} - -static struct kobj_type vvz_volume_ktype = { - .release = vvz_volume_kobj_release, - .sysfs_ops = &kobj_sysfs_ops, - .default_groups = vvz_volume_default_groups -}; - -int vvz_sysfs_register_volume(struct vvz_volume *svol) -{ - int err; - - /* Completion */ - init_completion(&svol->kobj_released); - - /* Register directory name>/ under device directory */ - err = kobject_init_and_add(&svol->kobj, &vvz_volume_ktype, &svol->sdev->kobj, - "%s", svol->name); - if (err) - goto bad; - /* Emit uevent */ - kobject_uevent(&svol->kobj, KOBJ_ADD); - - return 0; - - -bad: - kobject_put(&svol->kobj); - wait_for_completion(&svol->kobj_released); - return err; -} - -void vvz_sysfs_unregister_volume(struct vvz_volume *svol) -{ - kobject_put(&svol->kobj); - wait_for_completion(&svol->kobj_released); -} diff --git a/dm-vvz/volume.c b/dm-vvz/volume.c deleted file mode 100644 index 7de135b..0000000 --- a/dm-vvz/volume.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include "vvz.h" - - -struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, - u8 *enckey, struct dm_target *ti) -{ - struct vvz_volume *svol; - int err; - - svol = kzalloc(sizeof(*svol), GFP_KERNEL); - if (!svol) { - DMERR("Could not allocate volume"); - return ERR_PTR(-ENOMEM); - } - - svol->sdev = sdev; - svol->vol_idx = vol_idx; - sprintf(svol->name, "vvz_%u_%lu", sdev->dev_id, vol_idx); - - svol->ti = ti; - err = dm_get_device(ti, sdev->name, - dm_table_get_mode(ti->table), &svol->dm_dev); - if (err) { - ti->error = "Device lookup failed"; - goto bad_dm_dev; - } - - /* Crypto */ - svol->tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); - if (IS_ERR(svol->tfm)) { - err = PTR_ERR(svol->tfm); - DMERR("Could not allocate AES-XTS cipher handle; error %d", err); - goto bad_tfm_alloc; - } - memcpy(svol->enckey, enckey, VVZ_XTS_KEYLEN); - err = crypto_skcipher_setkey(svol->tfm, svol->enckey, VVZ_XTS_KEYLEN); - if (err) { - DMERR("Could not set key in crypto transform; error %d", err); - goto bad_tfm_setkey; - } - - /* Position map */ - mutex_init(&svol->posmap_lock); - /* Slight over-allocation, to fit a whole number of blocks */ - svol->posmap = vmalloc(sdev->posmap_size_sectors * SECTOR_SIZE); - if (!svol->posmap) { - DMERR("Could not allocate position map"); - err = -ENOMEM; - goto bad_posmap_alloc; - } - svol->nr_mapped_slices = 0; - /* Load from disk */ - err = vvz_load_and_sanitise_posmap(svol); - if (err) { - DMERR("Could not load position map from disk; error %d", err); - goto bad_posmap_load; - } - - /* Register to sysfs, once initialised */ - err = vvz_sysfs_register_volume(svol); - if (err) { - DMERR("Could not register volume with sysfs; error %d", err); - goto bad_sysfs; - } - - return svol; - - -bad_sysfs: -bad_posmap_load: - vfree(svol->posmap); -bad_posmap_alloc: -bad_tfm_setkey: - crypto_free_skcipher(svol->tfm); -bad_tfm_alloc: - dm_put_device(ti, svol->dm_dev); -bad_dm_dev: - kfree(svol); - return ERR_PTR(err); -} - - -void vvz_vol_destroy(struct vvz_volume *svol) -{ - vvz_sysfs_unregister_volume(svol); - vfree(svol->posmap); - crypto_free_skcipher(svol->tfm); - dm_put_device(svol->ti, svol->dm_dev); - kfree(svol); - - return; -} diff --git a/dm-vvz/vvz.c b/dm-vvz/vvz.c deleted file mode 100644 index a61b688..0000000 --- a/dm-vvz/vvz.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include -#include -#include -#include "vvz_constants.h" -#include "vvz.h" - -#include - -/* - *---------------------------- - * Device mapper target - *---------------------------- - */ - -DEFINE_MUTEX(vvz_alldevs_lock); -struct vvz_device **vvz_alldevs = NULL; -u32 vvz_free_devid = 0; /* The lowest free devID */ - - -/* Add a device to the global array, and advance next_dev_id */ -static int vvz_add_device_global(u32 dev_id, struct vvz_device *sdev) -{ - int i; - - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return -ERESTARTSYS; - - /* Check for dev_id conflict, possible because a read() to next_dev_id - * in sysfs can return the same value to two processes */ - if (vvz_alldevs[dev_id]) { - mutex_unlock(&vvz_alldevs_lock); - DMERR("A device with this ID already exists. Retry"); - return -EINVAL; - } - // Add to the global array, and advance free_devid - vvz_alldevs[dev_id] = sdev; - for (i = vvz_free_devid; i < VVZ_MAX_DEVS && vvz_alldevs[i]; i++); - vvz_free_devid = i; - - mutex_unlock(&vvz_alldevs_lock); - - return 0; -} - -/* Remove a device from the global array, and update next_dev_id */ -static void vvz_remove_device_global(u32 dev_id) -{ - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return; - vvz_alldevs[dev_id] = NULL; - if (dev_id < vvz_free_devid) - vvz_free_devid = dev_id; - mutex_unlock(&vvz_alldevs_lock); -} - - -/* - * Create volume and, if not existent, the underlying device. - */ -static int vvz_ctr(struct dm_target *ti, unsigned int argc, char **argv) -{ - u32 dev_id; - char *bdev_path; - size_t vol_idx; - char *enckey_hex; - u8 enckey[VVZ_XTS_KEYLEN]; - u32 tot_slices; - struct vvz_device *sdev; - struct vvz_volume *svol; - int err; - - /** - * Parse arguments. - * - * argv[0]: Shufflecake-unique device ID - * argv[1]: path to underlying physical device - * argv[2]: volume index within the device - * argv[3]: number of 1-MiB slices in the underlying device - * argv[4]: 64-byte encryption key (hex-encoded, so 128 chars) - */ - if (argc != 5) { - ti->error = "Invalid argument count"; - return -EINVAL; - } - sscanf(argv[0], "%u", &dev_id); - bdev_path = argv[1]; - sscanf(argv[2], "%lu", &vol_idx); - sscanf(argv[3], "%u", &tot_slices); - enckey_hex = argv[4]; - /* Sanity checks */ - if (dev_id >= VVZ_MAX_DEVS) { - ti->error = "Device ID out of bounds"; - return -EINVAL; - } - if (vol_idx >= VVZ_DEV_MAX_VOLUMES) { - ti->error = "Volume index out of bounds"; - return -EINVAL; - } - if (strlen(enckey_hex) != 2 * VVZ_XTS_KEYLEN) { - ti->error = "Invalid key length"; - return -EINVAL; - } - /* Decode the encryption key */ - err = hex2bin(enckey, enckey_hex, VVZ_XTS_KEYLEN); - if (err) { - ti->error = "Could not decode hexadecimal encryption key"; - return err; - } - - /* Create device, if this is the first volume, otherwise retrieve it */ - if (vol_idx == 0) { - sdev = vvz_dev_create(dev_id, bdev_path, tot_slices); - if (IS_ERR(sdev)) { - ti->error = "Could not instantiate device"; - return PTR_ERR(sdev); - } - /* Insert in global array */ - err = vvz_add_device_global(dev_id, sdev); - if (err) { - ti->error = "Could not add device to global array"; - goto bad_dev_global; - } - - } else { - if (mutex_lock_interruptible(&vvz_alldevs_lock)) - return -ERESTARTSYS; - sdev = vvz_alldevs[dev_id]; - mutex_unlock(&vvz_alldevs_lock); - - if (!sdev) { - ti->error = "Could not find device"; - return -EINVAL; - } - } - - /* Create volume */ - svol = vvz_vol_create(sdev, vol_idx, enckey, ti); - if (IS_ERR(svol)) { - ti->error = "Could not instantiate volume"; - err = PTR_ERR(svol); - goto bad_vol_create; - } - /* We expect ->ctr() calls to be strictly sequential */ - sdev->nr_volumes++; - - /* Only accept one block per request for simplicity TODO: improve to one slice*/ - ti->max_io_len = VVZ_BLOCK_SCALE; - ti->flush_supported = true; - ti->num_flush_bios = 1; - ti->discards_supported = false; - ti->num_discard_bios = 0; - ti->num_secure_erase_bios = 0; - ti->num_write_zeroes_bios = 0; - ti->accounts_remapped_io = true; - ti->per_io_data_size = sizeof(struct vvz_io); - ti->private = svol; - - return 0; - - -bad_vol_create: - if (vol_idx == 0) { - vvz_remove_device_global(dev_id); -bad_dev_global: - vvz_dev_destroy(sdev); - } - return err; -} - - -/* Destroy volume and, if needed, the underlying device */ -static void vvz_dtr(struct dm_target *ti) -{ - struct vvz_volume *svol = ti->private; - struct vvz_device *sdev = svol->sdev; - - vvz_vol_destroy(svol); - /* We expect ->dtr() calls to be strictly sequential */ - sdev->nr_volumes--; - - if (sdev->nr_volumes == 0) { - vvz_remove_device_global(sdev->dev_id); - vvz_dev_destroy(sdev); - } - - return; -} - - -static int vvz_map(struct dm_target *ti, struct bio *bio) -{ - struct vvz_io *sio = dm_per_bio_data(bio, sizeof(struct vvz_io)); - struct vvz_volume *svol = ti->private; - sector_t lblk_num = bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT; - - if (unlikely(!bio_has_data(bio))) { -// DMWARN("No-data bio: bio_op() = %d, bi_opf = %u, bi_io_vec = %p, bi_idx = %u", bio_op(bio), bio->bi_opf, bio->bi_io_vec, bio->bi_iter.bi_idx); -// msleep(100); - } - - /* Flush requests are just passed down, since our position map is - * currently write-through, so we have no volatile cache */ - if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - /* Has to be empty though */ - if (bio_sectors(bio)) { - DMWARN("Non-empty flush request!"); - msleep(3000); - return DM_MAPIO_KILL; - } -// DMWARN("REQ_PREFLUSH empty (phew), sector: %llu", bio->bi_iter.bi_sector); -// msleep(100); - bio_set_dev(bio, svol->dm_dev->bdev); - return DM_MAPIO_REMAPPED; - } - - /* Accept one block at a time TODO improve */ - if (unlikely(bio->bi_iter.bi_size > VVZ_BLOCK_SIZE)) { - DMWARN("Big bio: %u", bio->bi_iter.bi_size); - msleep(300); - dm_accept_partial_bio(bio, VVZ_BLOCK_SCALE); - } - /* Only one segment, single page, starting at 0 TODO improve */ - if (unlikely(bio_segments(bio) > 1 || - bio_offset(bio) != 0)) { - DMWARN("Unaligned bio!"); - msleep(3000); - return DM_MAPIO_KILL; - } - if (unlikely(bio->bi_iter.bi_size != VVZ_BLOCK_SIZE)) { - DMWARN("Wrong bio size: %u", bio->bi_iter.bi_size); - msleep(3000); - return DM_MAPIO_KILL; - } - - /* Init I/O struct */ - sio->svol = svol; - sio->orig_bio = bio; - sio->lsi = lblk_num >> VVZ_SLICE_SHIFT; - sio->block_offset = lblk_num & ((1U << VVZ_SLICE_SHIFT) - 1); - - /* Enqueue */ - if (bio_data_dir(bio) == READ) - INIT_WORK(&sio->work, vvz_read_work_fn); - else - INIT_WORK(&sio->work, vvz_write_work_fn); - queue_work(svol->sdev->io_queue, &sio->work); - - return DM_MAPIO_SUBMITTED; -} - - -static void vvz_io_hints(struct dm_target *ti, struct queue_limits *limits) -{ - // Currently, we only handle one block at a time TODO improve - limits->logical_block_size = VVZ_BLOCK_SIZE; - limits->physical_block_size = VVZ_BLOCK_SIZE; - limits->io_min = VVZ_BLOCK_SIZE; - limits->io_opt = VVZ_BLOCK_SIZE; - - return; -} - - -static int vvz_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) -{ - struct vvz_volume *svol = ti->private; - struct vvz_device *sdev = svol->sdev; - - if (!fn) { - dump_stack(); - msleep(2000); - return -EINVAL; - } - return fn(ti, svol->dm_dev, 0, sdev->dev_header_size_sectors + ti->len, data); -} - - -/* - *---------------------------- - * Kernel module - *---------------------------- - */ - -static struct target_type vvz_target = { - .name = VVZ_TARGET_NAME, - .version = {VVZ_VER_MAJOR, VVZ_VER_MINOR, VVZ_VER_REVISION}, - .module = THIS_MODULE, - .ctr = vvz_ctr, - .dtr = vvz_dtr, - .map = vvz_map, - .io_hints = vvz_io_hints, - .iterate_devices = vvz_iterate_devices, -}; - - -/* Module entry point: init variables and register DM target */ -static int __init vvz_init(void) -{ - int err; - - /* For the moment, we assume PAGE_SIZE == VVZ_BLOCK_SIZE TODO improve */ - if (VVZ_BLOCK_SIZE != PAGE_SIZE) { - DMERR("Error, PAGE_SIZE != %d bytes not yet supported", VVZ_BLOCK_SIZE); - err = -ENOTRECOVERABLE; - goto bad_page_size; - } - - vvz_alldevs = vzalloc(VVZ_MAX_DEVS * sizeof(*vvz_alldevs)); - if (!vvz_alldevs) { - DMERR("Could not allocate vvz_alldevs"); - err = -ENOMEM; - goto bad_alldevs_alloc; - } - - err = vvz_sysfs_init(); - if (err) { - DMERR("Could not init sysfs; error %d", err); - goto bad_sysfs_init; - } - - err = dm_register_target(&vvz_target); - if (err < 0) { - DMERR("Could not register DM target"); - goto bad_register_target; - } - - DMINFO("loaded"); - return 0; - - -bad_register_target: - vvz_sysfs_exit(); -bad_sysfs_init: - vfree(vvz_alldevs); -bad_alldevs_alloc: -bad_page_size: - DMERR("not loaded"); - return err; -} - - -/* Module exit point: de-init variables and unregister DM target */ -static void __exit vvz_exit(void) -{ - dm_unregister_target(&vvz_target); - vvz_sysfs_exit(); - vfree(vvz_alldevs); - - DMINFO("unloaded"); - return; -} - - -module_init(vvz_init); -module_exit(vvz_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Shufflecake authors"); -MODULE_DESCRIPTION(DM_NAME " target for Shufflecake"); diff --git a/dm-vvz/vvz.h b/dm-vvz/vvz.h deleted file mode 100644 index de4ec73..0000000 --- a/dm-vvz/vvz.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _VVZ_H -#define _VVZ_H - -#include -#include -#include -#include -#include "vvz_constants.h" - - -/* - *---------------------------- - * Constants - *---------------------------- - */ - -#define DM_MSG_PREFIX "vvz" - - -/* - *---------------------------- - * Structs - *---------------------------- - */ - -struct vvz_device -{ - /* Shufflecake-unique device ID */ - u32 dev_id; - /* : */ - char name[16]; - - /* Logical size of each volume */ - u32 tot_slices; - /* Header sizes in 512-byte sectors */ - sector_t posmap_size_sectors; - sector_t dev_header_size_sectors; - - /* Number of volumes. No need for an atomic_t */ - size_t nr_volumes; - - /* Shuffled array of PSIs */ - struct mutex slices_lock; - u32 *prmslices; - u32 prmslices_octr; - bool *slices_ofld; - u32 nr_free_slices; - - /* Sysfs */ - struct kobject kobj; - struct completion kobj_released; - - /* Resource sharing */ - struct bio_set bioset; - struct dm_io_client *io_client; - struct workqueue_struct *io_queue; - struct workqueue_struct *crypt_queue; -}; - -struct vvz_volume -{ - /* Backing device */ - struct vvz_device *sdev; - - /* Underlying block device. This can't go in the vvz_device struct, - * because each ti grabs its own reference. */ - struct dm_dev *dm_dev; - struct dm_target *ti; - - /* Volume index within the device */ - size_t vol_idx; - /* Volume name: vvz__ */ - char name[32]; - - /* Position map */ - struct mutex posmap_lock; - u32 *posmap; - u32 nr_mapped_slices; - - /* Sysfs */ - struct kobject kobj; - struct completion kobj_released; - - /* Crypto */ - u8 enckey[VVZ_XTS_KEYLEN]; - struct crypto_skcipher *tfm; -}; - -struct vvz_io -{ - struct vvz_volume *svol; - - struct bio *orig_bio; - struct bio *phys_bio; - u32 lsi; - u32 block_offset; - u32 psi; - - struct work_struct work; -}; - - -/* - *---------------------------- - * Macros - *---------------------------- - */ - -/* Starting sector of position map */ -#define VVZ_POSMAP_START_SECTOR(svol) \ - (VVZ_BLOCK_SCALE * (1 + VVZ_DEV_MAX_VOLUMES) + \ - (svol)->vol_idx * (svol)->sdev->posmap_size_sectors) - - -/* Physical sector of a remapped bio */ -#define VVZ_PHYS_BIO_SECTOR(sdev, psi, off) ( \ - (sdev)->dev_header_size_sectors + ( \ - ((psi << VVZ_SLICE_SHIFT) + off) << VVZ_BLOCK_SHIFT \ - ) \ -) - -/* - *---------------------------- - * Global variables - *---------------------------- - */ - -/* Array of devices, and next free id */ -extern struct mutex vvz_alldevs_lock; -extern struct vvz_device **vvz_alldevs; -extern u32 vvz_free_devid; /* The lowest free devID */ - - -/* - *---------------------------- - * Functions - *---------------------------- - */ - -/* Device */ -struct vvz_device *vvz_dev_create(u32 dev_id, char *bdev_path, u32 tot_slices); -void vvz_dev_destroy(struct vvz_device *sdev); - -/* Volume */ -struct vvz_volume *vvz_vol_create(struct vvz_device *sdev, size_t vol_idx, - u8 *enckey, struct dm_target *ti); -void vvz_vol_destroy(struct vvz_volume *svol); - -/* Sysfs */ -int vvz_sysfs_init(void); -void vvz_sysfs_exit(void); -int vvz_sysfs_register_device(struct vvz_device *sdev); -void vvz_sysfs_unregister_device(struct vvz_device *sdev); -int vvz_sysfs_register_volume(struct vvz_volume *svol); -void vvz_sysfs_unregister_volume(struct vvz_volume *svol); - -/* Bio mapping */ -void vvz_read_work_fn(struct work_struct *work); -void vvz_write_work_fn(struct work_struct *work); - -/* Position map */ -int vvz_load_and_sanitise_posmap(struct vvz_volume *svol); -int vvz_create_persistent_slice_mapping(struct vvz_volume *svol, u32 lsi, u32 *psi); - -/* Crypto */ -int vvz_crypt_blocks_vm(struct crypto_skcipher *tfm, void *src_buf, void *dst_buf, - u64 num_blocks, u64 first_pblk_num, int rw); -int vvz_crypt_block_page(struct crypto_skcipher *tfm, struct page *src_page, - struct page *dst_page, u64 pblk_num, int rw); - -#endif /* _VVZ_H */ diff --git a/dm-vvz/vvz_constants.h b/dm-vvz/vvz_constants.h deleted file mode 100644 index 7ed62d1..0000000 --- a/dm-vvz/vvz_constants.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* This is just a placeholder for defining constants and parameters that must - * be the same across Shufflecake components (kernel module, userland tool) - * such as block size, slice size etc */ - -#ifndef _VVZ_CONSTANTS_H_ -#define _VVZ_CONSTANTS_H_ - - -#define VVZ_TARGET_NAME "vvz" - - -#define VVZ_VER_MAJOR 0 -#define VVZ_VER_MINOR 4 -#define VVZ_VER_REVISION 0 -#define VVZ_VER_SPECIAL "rc1" - -#define STRINGIFY0(s) # s -#define STRINGIFY(s) STRINGIFY0(s) - -#define VVZ_VERSION STRINGIFY(VVZ_VER_MAJOR)"."STRINGIFY(VVZ_VER_MINOR)"."STRINGIFY(VVZ_VER_REVISION)""VVZ_VER_SPECIAL - - -#define VVZ_MODE_LEGACY 0 -#define VVZ_MODE_LITE 1 -#define VVZ_MODE_FULL 2 - - -#define VVZ_BLOCK_SIZE 4096 /* bytes */ -#define VVZ_BLOCK_SHIFT 3 -#define VVZ_BLOCK_SCALE (1 << VVZ_BLOCK_SHIFT) /* 8 sectors in a block */ -#define VVZ_SLICE_SHIFT 8 -#define VVZ_SLICE_SCALE (1 << VVZ_SLICE_SHIFT) /* 256 blocks in a slice */ - - -/* XTS requires doubling the key size */ -#define VVZ_XTS_KEYLEN 64 /* bytes */ -/* The IV is the right-0-padded LE physical block number */ -#define VVZ_XTS_IVLEN 16 /* bytes */ - - -#define VVZ_DEV_MAX_VOLUMES 15 -#define VVZ_MAX_DEVS 1024 - - -#define VVZ_PSI_INVALID 0xFFFFFFFF -/* PosMap entries are 4 bytes, therefore there are 1024 of them in a block */ -#define VVZ_PSIS_PER_BLOCK 1024 - - -/* Sysfs entries under /sys/module/dm_vvz/ */ -#define VVZ_SYSFS_BDEVS "bdevs" -#define VVZ_SYSFS_DEVID "next_dev_id" - - -#endif /* _VVZ_CONSTANTS_H_ */ diff --git a/dm-vvz/write.c b/dm-vvz/write.c deleted file mode 100644 index 36ee151..0000000 --- a/dm-vvz/write.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#include "vvz.h" -#include - - -static void vvz_write_endio(struct bio *phys_bio); - - -void vvz_write_work_fn(struct work_struct *work) -{ - struct vvz_io *sio = container_of(work, struct vvz_io, work); - struct vvz_volume *svol = sio->svol; - struct vvz_device *sdev = svol->sdev; - struct bio *orig_bio = sio->orig_bio; - struct bio_vec bvl = bio_iovec(orig_bio); - struct bio *phys_bio; - struct page *page; - u32 lsi = sio->lsi; - u32 block_offset = sio->block_offset; - u32 psi; - int err; - -// DMWARN("WRITE: dequeued. Sector = %llu", orig_bio->bi_iter.bi_sector); -// msleep(100); - - - /* Read existing mapping, or create new one */ - if (mutex_lock_interruptible(&svol->posmap_lock)) { - orig_bio->bi_status = BLK_STS_IOERR; - goto endio; - } - psi = svol->posmap[lsi]; - /* If LSI unmapped, create new mapping, while holding the lock */ - if (psi == VVZ_PSI_INVALID) { -// DMWARN("WRITE: unmapped LSI %u, sampling PSI", lsi); -// msleep(100); - - err = vvz_create_persistent_slice_mapping(svol, lsi, &psi); - if (err){ - DMERR("Could not create slice mapping; error %d", err); - mutex_unlock(&svol->posmap_lock); - orig_bio->bi_status = BLK_STS_IOERR; - goto endio; - } -// DMWARN("WRITE: sampled PSI %u for LSI %u", psi, lsi); -// msleep(100); - } - mutex_unlock(&svol->posmap_lock); - sio->psi = psi; - - /* Allocate physical bio */ - phys_bio = bio_alloc_bioset(svol->dm_dev->bdev, 1, orig_bio->bi_opf, - GFP_NOIO, &sdev->bioset); - if (!phys_bio) { - DMERR("Could not allocate physical bio"); - orig_bio->bi_status = BLK_STS_IOERR; - goto endio; - } - /* Insert in the I/O struct */ - sio->phys_bio = phys_bio; - - /* Physical bio needs its own page */ - page = alloc_pages(GFP_NOIO, 0); - if (!page) { - DMERR("Could not allocate page for physical bio"); - orig_bio->bi_status = BLK_STS_IOERR; - goto bad_alloc_page; - } - - /* Remap sector */ - phys_bio->bi_iter.bi_sector = VVZ_PHYS_BIO_SECTOR(sdev, psi, block_offset); - /* Encrypt */ - err = vvz_crypt_block_page(svol->tfm, bvl.bv_page, page, - phys_bio->bi_iter.bi_sector >> VVZ_BLOCK_SHIFT, WRITE); - if (err) { - DMERR("Could not encrypt bio; error %d", err); - orig_bio->bi_status = BLK_STS_IOERR; - goto bad_encrypt; - } - - /* Add page to bio */ - __bio_add_page(phys_bio, page, VVZ_BLOCK_SIZE, 0); - /* Set fields for the endio */ - phys_bio->bi_private = sio; - phys_bio->bi_end_io = vvz_write_endio; - /* Submit */ - dm_submit_bio_remap(orig_bio, phys_bio); - - return; - - -bad_encrypt: - __free_page(page); -bad_alloc_page: - bio_put(phys_bio); -endio: - bio_endio(orig_bio); - return; -} - -static void vvz_write_endio(struct bio *phys_bio) -{ - struct vvz_io *sio = phys_bio->bi_private; - struct bio *orig_bio = sio->orig_bio; - - /* If physical bio failed, then fail-fast */ - if (phys_bio->bi_status != BLK_STS_OK) { - orig_bio->bi_status = phys_bio->bi_status; - DMWARN("WRITE ENDIO: phys_bio failed"); - goto endio; - } - - /* Advance original bio by one block */ - bio_advance(orig_bio, VVZ_BLOCK_SIZE); - orig_bio->bi_status = BLK_STS_OK; - -endio: - /* Free the physical bio and its page */ - bio_free_pages(phys_bio); - bio_put(phys_bio); - /* End original bio */ - bio_endio(orig_bio); - - return; -} - diff --git a/shufflecake-userland-legacy/Makefile b/shufflecake-userland-legacy/Makefile deleted file mode 100644 index e8598dc..0000000 --- a/shufflecake-userland-legacy/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright The Shufflecake Project Authors (2022) -# Copyright The Shufflecake Project Contributors (2022) -# Copyright Contributors to the The Shufflecake Project. - -# See the AUTHORS file at the top-level directory of this distribution and at -# - -# This file is part of the program shufflecake-c, which is part of the Shufflecake -# Project. Shufflecake is a plausible deniability (hidden storage) layer for -# Linux. See . - -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 2 of the License, or (at your option) -# any later version. 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, see . - -############################################################################# -# Makefile with dependency auto-generation, taken and adapted from -# https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ -############################################################################# - -# Output dirs for binaries -BIN_DIR := bin -PROJ_OUT_DIR := $(BIN_DIR)/proj_build -TEST_OUT_DIR := $(BIN_DIR)/test_build -# Output dirs for dependency files -PROJ_DEP_DIR := $(BIN_DIR)/.proj_deps -TEST_DEP_DIR := $(BIN_DIR)/.test_deps - -# Include directories for compilation -INCLUDE := include test - -# Use gcc -CC := gcc -# All warnings, add includes (other options may be supplied on command line) -override CFLAGS += -Wall $(addprefix -I,$(INCLUDE)) -# Flags for dependency file auto-generation (deferred evaluation) -PROJ_DEPFLAGS = -MT $@ -MMD -MP -MF $(PROJ_DEP_DIR)/$*.d -TEST_DEPFLAGS = -MT $@ -MMD -MP -MF $(TEST_DEP_DIR)/$*.d -# Linker flags -LDFLAGS := -lgcrypt -ldevmapper - -# The variables PROJ_SRCS (and PROJ_ROOT) and TEST_SRCS (and TEST_ROOT) are defined in this Makefile -include Makefile.sources -# Create the three lists of object files -PROJ_OBJS := $(PROJ_SRCS:$(PROJ_ROOT)/%.c=$(PROJ_OUT_DIR)/%.o) -TEST_OBJS := $(TEST_SRCS:$(TEST_ROOT)/%.c=$(TEST_OUT_DIR)/%.o) -PROJ_OBJS_NO_MAIN := $(filter-out $(PROJ_OUT_DIR)/main.o,$(PROJ_OBJS)) -# Create the two lists of dependency files -PROJ_DEPS := $(PROJ_SRCS:$(PROJ_ROOT)/%.c=$(PROJ_DEP_DIR)/%.d) -TEST_DEPS := $(TEST_SRCS:$(TEST_ROOT)/%.c=$(TEST_DEP_DIR)/%.d) -# Put them together -DEPS := $(PROJ_DEPS) $(TEST_DEPS) - -# All directories to be created if non-existing (sort to remove duplicates) -DIRS := $(sort $(dir $(BIN_DIR) $(PROJ_OBJS) $(TEST_OBJS) $(PROJ_DEPS) $(TEST_DEPS))) - -# The target binaries -MAIN_BIN := $(PROJ_OUT_DIR)/shufflecake-legacy -TEST_BIN := $(TEST_OUT_DIR)/tests -# Their symlink -MAIN_LINK := shufflecake-legacy -TEST_LINK := tests - - - -#### -#### RULES -#### - - -.PHONY: main -main: $(MAIN_BIN) - -.PHONY: test -test: $(TEST_BIN) - -.PHONY: link_msg -link_msg: - @echo "Linking object files" - -.PHONY: compile_msg -compile_msg: - @echo "Compiling source files" - -# Link project object files -$(MAIN_BIN): $(PROJ_OBJS) | link_msg - @echo "\t---> $@" - @$(CC) $^ -o $@ $(LDFLAGS) - @rm -f $(MAIN_LINK) - @ln -s $@ $(MAIN_LINK) - -# Link test object files -$(TEST_BIN): $(PROJ_OBJS_NO_MAIN) $(TEST_OBJS) | link_msg - @echo "\t---> $@" - @$(CC) $^ -o $@ $(LDFLAGS) - @rm -f $(TEST_LINK) - @ln -s $@ $(TEST_LINK) - @echo "Done, launching tests" - @./$(TEST_LINK) - -# Cancel implicit rule -%.o : %.c - -# Build project object file -$(PROJ_OUT_DIR)/%.o : $(PROJ_ROOT)/%.c $(PROJ_DEP_DIR)/%.d | $(DIRS) compile_msg - @echo "\t---> $@" - @$(CC) $(PROJ_DEPFLAGS) $(CFLAGS) -c -o $@ $< - -# Build test object file -$(TEST_OUT_DIR)/%.o : $(TEST_ROOT)/%.c $(TEST_DEP_DIR)/%.d | $(DIRS) compile_msg - @echo "\t---> $@" - @$(CC) $(TEST_DEPFLAGS) $(CFLAGS) -c -o $@ $< - -# Create needed directories -$(DIRS): - @mkdir -p $@ - -.PHONY: clean -clean: - rm -rf $(PROJ_OUT_DIR) $(TEST_OUT_DIR) $(PROJ_DEP_DIR) $(TEST_DEP_DIR) - rm -rf $(BIN_DIR) - @rm -f $(MAIN_LINK) $(TEST_LINK) - -$(DEPS): -include $(wildcard $(DEPS)) diff --git a/shufflecake-userland-legacy/Makefile.sources b/shufflecake-userland-legacy/Makefile.sources deleted file mode 100644 index 0e2a80b..0000000 --- a/shufflecake-userland-legacy/Makefile.sources +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright The Shufflecake Project Authors (2022) -# Copyright The Shufflecake Project Contributors (2022) -# Copyright Contributors to the The Shufflecake Project. - -# See the AUTHORS file at the top-level directory of this distribution and at -# - -# This file is part of the program shufflecake-c, which is part of the Shufflecake -# Project. Shufflecake is a plausible deniability (hidden storage) layer for -# Linux. See . - -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 2 of the License, or (at your option) -# any later version. 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, see . - -######################################### -# Only define the sources to be compiled -######################################### - -#### -#### Main files -#### - -PROJ_SRCS := $(addprefix utils/,crypto.c disk.c dm.c file.c string.c input.c) -PROJ_SRCS += $(addprefix header/,position_map.c volume_master_block.c device_master_block.c) -PROJ_SRCS += $(addprefix operations/,volume_header.c devmapper.c dmb.c) -PROJ_SRCS += $(addprefix commands/,init.c open.c close.c test_pwd.c change_pwd.c) -PROJ_SRCS += $(addprefix cli/,dispatch.c init.c open.c close.c testpwd.c changepwd.c) -PROJ_SRCS += main.c - -PROJ_ROOT := src -PROJ_SRCS := $(addprefix $(PROJ_ROOT)/,$(PROJ_SRCS)) - - -#### -#### Test files -#### - -TEST_SRCS := $(addprefix crypto/,test_aes256ctr.c test_aes256gcm.c test_argon2id.c) -TEST_SRCS += main.c - -TEST_ROOT := test -TEST_SRCS := $(addprefix $(TEST_ROOT)/,$(TEST_SRCS)) diff --git a/shufflecake-userland-legacy/include/cli.h b/shufflecake-userland-legacy/include/cli.h deleted file mode 100644 index 838f618..0000000 --- a/shufflecake-userland-legacy/include/cli.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _CLI_H_ -#define _CLI_H_ - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/* Action to create volumes */ -#define SFLC_CLI_INITACT "init" -/* Action to open volumes */ -#define SFLC_CLI_OPENACT "open" -/* Action to close volumes */ -#define SFLC_CLI_CLOSEACT "close" -/* Action to test password */ -#define SFLC_CLI_TESTPWDACT "testpwd" -/* Action to change password */ -#define SFLC_CLI_CHANGEPWDACT "changepwd" - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Called by the main to parse the arguments and dispatch to the right command */ -int sflc_cli_dispatch(int argc, char **argv); - -/* Initializes device and create empty volumes */ -int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill); -/* Open volumes */ -int sflc_cli_open(char *block_device); -/* Close volumes */ -int sflc_cli_close(char *block_device); -/* Test password */ -int sflc_cli_testPwd(char *block_device); -/* Change password */ -int sflc_cli_changePwd(char *block_device); - - -#endif /* _CLI_H_ */ - - diff --git a/shufflecake-userland-legacy/include/commands.h b/shufflecake-userland-legacy/include/commands.h deleted file mode 100644 index 68a14ac..0000000 --- a/shufflecake-userland-legacy/include/commands.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _COMMANDS_H_ -#define _COMMANDS_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "header.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - - -/***************************************************** - * STRUCTS * - *****************************************************/ - -/* Parameters for the init command */ -typedef struct -{ - /* Underlying block device */ - char *bdev_path; - - /* Number of volumes */ - size_t nr_vols; - /* Volumes' passwords */ - char **pwds; - size_t *pwd_lens; - - /* Option to skip random filling */ - bool no_randfill; - -} sflc_cmd_InitArgs; - - -/* Parameters for the open command */ -typedef struct -{ - /* Underlying block device */ - char *bdev_path; - - /* The only password provided */ - char *pwd; - size_t pwd_len; - -} sflc_cmd_OpenArgs; - -typedef struct -{ - /* Underlying block device */ - char *bdev_path; - - /* Content of the DMB cell */ - sflc_DmbCell *dmb_cell; - - /* The new password */ - char *new_pwd; - size_t new_pwd_len; - -} sflc_cmd_ChangePwdArgs; - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Create N volumes (only formats the device header, does not open the volumes) */ -int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args); - -/* Open M volumes, from the first down to the one whose pwd is provided */ -int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args); - -/* Close all volumes on the device (reads the list from sysfs) */ -int sflc_cmd_closeVolumes(char *bdev_path); - -/* Tests which volume is unlocked by the given password */ -int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell); - -/* Changes the specified volume's password */ -int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args); - - -#endif /* _COMMANDS_H_ */ diff --git a/shufflecake-userland-legacy/include/header.h b/shufflecake-userland-legacy/include/header.h deleted file mode 100644 index 869b868..0000000 --- a/shufflecake-userland-legacy/include/header.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _HEADER_H_ -#define _HEADER_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "utils/crypto.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/* The DMB contains one IV + one VMB key + one MAC for each volume */ -#define SFLC_DMB_CELL_SIZE (SFLC_AESGCM_PADDED_IVLEN + SFLC_CRYPTO_KEYLEN + SFLC_AESGCM_TAGLEN) - -/* Let us enforce that the one DMB can fit cells for all volumes */ -#if SFLC_ARGON_SALTLEN + (SFLC_DEV_MAX_VOLUMES * SFLC_DMB_CELL) > SFLC_SECTOR_SIZE -#error "Invalid combination of parameters: probably SFLC_DEV_MAX_VOLUMES is too big" -#endif - - -// The VMB cleartext occupies the last 4064 bytes on-disk (4096 bytes minus IV and MAC) -#define SFLC_CLEAR_VMB_LEN (SFLC_SECTOR_SIZE - \ - SFLC_AESGCM_PADDED_IVLEN - \ - SFLC_AESGCM_TAGLEN) - - - -/***************************************************** - * STRUCTS * - *****************************************************/ - -/** - * The on-disk master block of a device contains lots of crypto stuff - * (a KDF salt, IVs, MACs...) used to properly hide the VMB keys. - * This struct only contains such useful info, in the clear. - */ -typedef struct { - // Each volume's VMB key - char vmb_keys[SFLC_DEV_MAX_VOLUMES][SFLC_CRYPTO_KEYLEN]; - - // How many of these need actually be encrypted - size_t nr_vols; - -} sflc_Dmb; - - -/** - * When unsealing a DMB, only one VMB key can be unlocked with a password. - * An invalid value for vol_idx means no VMB key could be unlocked (wrong pwd) - */ -typedef struct { - // The unlocked VMB key - char vmb_key[SFLC_CRYPTO_KEYLEN]; - - // The index of the volume opened by this VMB key - size_t vol_idx; - -} sflc_DmbCell; - - -/** - * The on-disk master block of a volume contains crypto stuff - * (an IV) used to properly hide the useful info. This struct - * only contains the useful info, in the clear. - */ -typedef struct { - // The key that encrypts the volume's data section - char volume_key[SFLC_CRYPTO_KEYLEN]; - - // The key that encrypts the previous volume's master block - char prev_vmb_key[SFLC_CRYPTO_KEYLEN]; - - // The total number of logical slices virtually available to this volume - size_t nr_slices; - -} sflc_Vmb; - - -/** - * This struct represents an encrypted empty position map. - * On-disk, the layout interleaves one IV block with 256 PosMap blocks (each - * encrypted by an IV in the IV block). Many such "runs" can be concatenated, - * until the position map is big enough to index the desired number of slices. - * The last "run" might be incomplete, in that it could have less than 256 - * PosMap blocks, if not all of them are needed. - * In the struct, there are as many IV blocks as there are PosMapBlock arrays - * (equal to the number of "runs"). The m-th IV of the n-th IV block encrypts - * the m-th block of the n-th array. The PosMapBlocks in an array are stored - * contiguously in RAM, so a PosMapBlock array is just a char array of length - * multiple of 4096. All the arrays are full (256 PosMapBlocks, 1 MiB) except - * for the last one, which may hold fewer blocks. - */ -typedef struct { - // The number of PosMapBlock arrays (and of IV blocks) - size_t nr_arrays; - - // The sequence of IV blocks - char **iv_blocks; - // The sequence of (encrypted) PosMapBlock arrays - char **pmb_arrays; - - // The number of PosMapBlocks in the last array - size_t nr_last_pmbs; - -} sflc_EncPosMap; - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* "Encrypt" each VMB key with its pwd, so the DMB is ready to be written on-disk */ -int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block); -/* "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF) */ -int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); -/* Re-encrypt the content of a single DMB cell */ -int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len); - - -/* "Encrypt" a VMB with a VMB key, so it's ready to be written on-disk */ -int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block); -/* "Decrypt" a VMB coming from the disk, directly using its key */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb); - - -/* Create an encrypted empty position map for the given number of slices (allocates memory) */ -int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm); - - - -#endif /* _HEADER_H_ */ diff --git a/shufflecake-userland-legacy/include/operations.h b/shufflecake-userland-legacy/include/operations.h deleted file mode 100644 index 8de9ab6..0000000 --- a/shufflecake-userland-legacy/include/operations.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _OPERATIONS_H_ -#define _OPERATIONS_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "header.h" -#include "utils/crypto.h" -#include "utils/math.h" - - -/***************************************************** - * INLINE FUNCTIONS * - *****************************************************/ - -// Size, in 4096-byte blocks, of a whole volume header (VMB+PM) -static inline size_t sflc_volHeaderSize(size_t nr_slices) -{ - // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) - size_t nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); - // Each array holds up to 256 PosMapBlocks - size_t nr_arrays = ceil(nr_pmbs, SFLC_BLOCKS_PER_LOG_SLICE); - - // 1 VMB, the PMBs, and the IV blocks - return 1 + nr_pmbs + nr_arrays; -} - -// Position of the VMB for the given volume -static inline uint64_t sflc_vmbPosition(size_t vol_idx, size_t nr_slices) -{ - return 1 + ((uint64_t) vol_idx) * ((uint64_t) sflc_volHeaderSize(nr_slices)); -} - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Encrypts and writes the DMB to disk */ -int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb); -/* Reads the DMB from disk and outputs the unlocked VMB key */ -int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell); -/* Reads the DMB from disk, changes the relevant DMB cell, and writes it back */ -int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len); - -/* Encrypts and writes a volume header (VMB+PM) on-disk */ -int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx); -/* Reads a VMB from disk and unlocks it */ -int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb); - -/* Build parameter list for ctor in dm_sflc, and send DM ioctl to create virtual block device */ -int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb); -/* Close the volume via the appropriate ioctl to DM */ -int sflc_ops_closeVolume(char *label); - -#endif /* _OPERATIONS_H_ */ diff --git a/shufflecake-userland-legacy/include/sflc_constants.h b/shufflecake-userland-legacy/include/sflc_constants.h deleted file mode 120000 index fab9e42..0000000 --- a/shufflecake-userland-legacy/include/sflc_constants.h +++ /dev/null @@ -1 +0,0 @@ -../../dm-sflc/sflc_constants.h \ No newline at end of file diff --git a/shufflecake-userland-legacy/include/utils/crypto.h b/shufflecake-userland-legacy/include/utils/crypto.h deleted file mode 100644 index 15ac111..0000000 --- a/shufflecake-userland-legacy/include/utils/crypto.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _UTILS_CRYPTO_H_ -#define _UTILS_CRYPTO_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "utils/sflc.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -// Key length, for input into AES-CTR and AES-GCM, and for output from Argon -#define SFLC_CRYPTO_KEYLEN 32 /* bytes */ - -// IV length for AES-CTR -#define SFLC_AESCTR_IVLEN 16 /* bytes */ - -// IV length for AES-GCM -#define SFLC_AESGCM_IVLEN 12 /* bytes */ - -// IVs occupy 16 bytes on-disk, but only the *FIRST* 12 are used for AES-GCM -#define SFLC_AESGCM_PADDED_IVLEN 16 /* bytes */ - -// MAC length for AES-GCM -#define SFLC_AESGCM_TAGLEN 16 /* bytes */ - -// Content of output plaintext upon MAC verification failure -#define SFLC_AESGCM_POISON_PT 0xFF - - -/* Argon parameters */ - -// Argon salt length -#define SFLC_ARGON_SALTLEN 16 /* bytes */ - -// Argon memory parameter -// We assume machines with at least 128 MiB available RAM, so 2^17 kiB -#define SFLC_ARGON_M (1 << 17) /* kibibytes */ - -// Argon iterations count -// We aim for 1-2 seconds on a low-end laptop or mobile (it's a one-time operation) -#define SFLC_ARGON_T 3 - -// Argon parallelism parameter (recommended to be 2 * CPU cores) -// We assume use even on single core devices -#define SFLC_ARGON_P 2 - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Get slow, true random bytes (suited for keys) */ -int sflc_rand_getStrongBytes(char *buf, size_t buflen); -/* Get fast, pseudo random bytes (suited for IVs and padding) */ -int sflc_rand_getWeakBytes(char *buf, size_t buflen); - -/* AES256-CTR encryption, does not touch the IV. Set ct = NULL for in-place. */ -int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct); -/* AES256-CTR decryption, does not touch the IV. Set pt = NULL for in-place. */ -int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt); - -/* AES256-GCM encryption, does not touch the IV */ -int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag); -/* AES256-GCM decryption, does not touch the IV (only decrypts if MAC is valid) */ -int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match); - -/* Compute Argon KDF */ -int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash); - - -#endif /* _UTILS_CRYPTO_H_ */ diff --git a/shufflecake-userland-legacy/include/utils/disk.h b/shufflecake-userland-legacy/include/utils/disk.h deleted file mode 100644 index 16885e3..0000000 --- a/shufflecake-userland-legacy/include/utils/disk.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Disk helper functions - */ - -#ifndef _UTILS_DISK_H_ -#define _UTILS_DISK_H_ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "utils/sflc.h" - - -/***************************************************** - * MACROS * - *****************************************************/ - -/** - * Max slices for given disk size (in 4096-byte blocks). - * - * The bigger a disk is, the more slices it can host. However, the more slices we format it with, - * the bigger the position map needed to index them: the header size grows with the number of slices, - * taking up part of the space that's supposed to host those slices. - * To settle the matter, let us derive an upper bound on the header size, yielding a "safe" value - * for the number of slices (given a disk size). - * - * To index s slices, we need pm := ceil(s/1024) <= s/1024 + 1 PosMap blocks, since each PosMap - * block (4096 bytes) can host 1024 slice indices (4 bytes each). - * - * To encrypt those PosMap blocks, we need iv := ceil(pm/256) <= pm IV blocks, since each IV block - * (4096 bytes) can encrypt 256 data blocks (IVs are 16 bytes). - * - * Therefore, a position map indexing s slices occupies pm+iv <= 2*pm <= 2*s/1024 + 2 blocks. - * - * A single volume's header contains the Volume Master Block and the position map, therefore it - * occupies 1+pm+iv <= 2*s/1024 + 3 blocks. - * - * The entire device's header simply contains 15 volume headers of the same size, therefore it - * occupies h := 15 * (1+pm+iv) <= 15*2*s/1024 + 3*15 <= s + 3*15 blocks. - * The last inequality follows from 15*2/1024 <= 1 (we need to enforce this on the symbolic values). - * - * To actually host the s slices, the data section needs 257*s blocks (256 data blocks + 1 IV block - * per slice). - * - * Therefore, in order to format a disk with s slices, we need at most (s + 3*15) + 257*s = - * = (1 + 257)*s + 3*15 blocks. - * - * If we are given d blocks on the disk, a safe value for s is one that satisfies - * (1 + 257)*s + 3*15 <= d <==> s <= (d - 3*15) / (1 + 257) - */ -#define sflc_disk_maxSlices(size) (size - 3*SFLC_DEV_MAX_VOLUMES) / (1 + SFLC_BLOCKS_PER_PHYS_SLICE) - - -/* Let us enforce, on the symbolic values, the inequality used in the previous bound */ -#if SFLC_DEV_MAX_VOLUMES * 2 > SFLC_SLICE_IDX_PER_BLOCK -#error "Invalid combination of parameters, probably SFLC_DEV_MAX_VOLUMES is too big" -#endif - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -char *sflc_disk_getDeviceName(char *bdev_path); - -/* Checks whether the given path points to a block device */ -bool sflc_disk_isBlockDevice(char *path); - -/* Returns the size in 4096-byte sectors (or < 0 if error) */ -int64_t sflc_disk_getSize(char * bdev_path); - -/* Reads a single 4096-byte sector from the disk */ -int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf); - -/* Writes a single 4096-byte sector to the disk */ -int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf); - -/* Writes many 4096-byte sectors to the disk */ -int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors); - - -#endif /* _UTILS_DISK_H_ */ diff --git a/shufflecake-userland-legacy/include/utils/input.h b/shufflecake-userland-legacy/include/utils/input.h deleted file mode 100644 index 9463999..0000000 --- a/shufflecake-userland-legacy/include/utils/input.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _UTILS_INPUT_H_ -#define _UTILS_INPUT_H_ - - -/***************************************************** - * MACROS * - *****************************************************/ - -/* Clear a line from stdin, to use after a failed scanf (it didn't actually read input) */ -#define sflc_ignoreLine() scanf("%*[^\n]") - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int sflc_safeReadLine(char *buf, size_t bufsize); - -/* Reads a password or passphrase (discarding the newline) from stdin in a secure way (no echo) */ -int sflc_safeReadPassphrase(char *buf, size_t bufsize); - -#endif /* _UTILS_FILE_H_ */ diff --git a/shufflecake-userland-legacy/include/utils/log.h b/shufflecake-userland-legacy/include/utils/log.h deleted file mode 100644 index 2088fbb..0000000 --- a/shufflecake-userland-legacy/include/utils/log.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _UTILS_LOG_H_ -#define _UTILS_LOG_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -// Printf colours (regular text) -#define SFLC_LOG_BLK "\033[0;30m" -#define SFLC_LOG_RED "\033[0;31m" -#define SFLC_LOG_GRN "\033[0;32m" -#define SFLC_LOG_YEL "\033[0;33m" -#define SFLC_LOG_BLU "\033[0;34m" -#define SFLC_LOG_MAG "\033[0;35m" -#define SFLC_LOG_CYN "\033[0;36m" -#define SFLC_LOG_WHT "\033[0;37m" -// Printf colours (bold text) -#define SFLC_LOG_BBLK "\033[1;30m" -#define SFLC_LOG_BRED "\033[1;31m" -#define SFLC_LOG_BGRN "\033[1;32m" -#define SFLC_LOG_BYEL "\033[1;33m" -#define SFLC_LOG_BBLU "\033[1;34m" -#define SFLC_LOG_BMAG "\033[1;35m" -#define SFLC_LOG_BCYN "\033[1;36m" -#define SFLC_LOG_BWHT "\033[1;37m" -// Reset colour -#define SFLC_LOG_RESET "\033[0m" - -// Log level: debug implies detailed logs -#ifdef CONFIG_SFLC_LOG_DEBUG -#define CONFIG_SFLC_LOG_DETAILED -#endif - - -/***************************************************** - * MACROS * - *****************************************************/ - -// Gives the point in the code where it was called -#define sflc_log_detailed(col, ...) do{ \ - printf(SFLC_LOG_GRN "FUNC " SFLC_LOG_RESET "%s() " \ - SFLC_LOG_GRN "FILE " SFLC_LOG_RESET "%s " \ - SFLC_LOG_GRN "LINE " SFLC_LOG_RESET "%d | ", \ - __func__, __FILE__, __LINE__); \ - sflc_log_concise(col, __VA_ARGS__); \ -}while(0) - -// Only writes using the given colour -#define sflc_log_concise(col, ...) do{ \ - printf(col); \ - printf(__VA_ARGS__); \ - printf(SFLC_LOG_RESET "\n"); \ -}while(0) - -// Maps to one or the other, based on a Makefile switch -#ifdef CONFIG_SFLC_LOG_DETAILED - #define sflc_log_colour(...) sflc_log_detailed(__VA_ARGS__) -#else - #define sflc_log_colour(...) sflc_log_concise(__VA_ARGS__) -#endif - -// Using specific colours -#define sflc_log_green(...) sflc_log_colour(SFLC_LOG_GRN, __VA_ARGS__) -#define sflc_log_red(...) sflc_log_colour(SFLC_LOG_RED, __VA_ARGS__) -#define sflc_log_yellow(...) sflc_log_colour(SFLC_LOG_YEL, __VA_ARGS__) -#define sflc_log_blue(...) sflc_log_colour(SFLC_LOG_BLU, __VA_ARGS__) -#define sflc_log_normal(...) sflc_log_colour(SFLC_LOG_RESET, __VA_ARGS__) - -// With log levels -#define sflc_log_error(...) sflc_log_colour(SFLC_LOG_RED, "[ERROR] " __VA_ARGS__) -#define sflc_log_warn(...) sflc_log_colour(SFLC_LOG_MAG, "[WARN] " __VA_ARGS__) -#ifdef CONFIG_SFLC_LOG_DEBUG - #define sflc_log_debug(...) sflc_log_colour(SFLC_LOG_CYN, "[DEBUG] " __VA_ARGS__) -#else - #define sflc_log_debug(...) -#endif - - -/***************************************************** - * INLINE FUNCTIONS * - *****************************************************/ - -// Log a hex string -static inline void sflc_log_hex(char *str, size_t len) -{ - int i; - unsigned char *s = (unsigned char *) str; - - for (i = 0; i < len; i++) { - printf("%02x ", s[i]); - // Nice aligned wrapping - if (i % 16 == 15) { - printf("\n"); - } - } - - // Always end with a newline - if (i % 16 != 0) { - printf("\n"); - } - - return; -} - -#endif /* _UTILS_LOG_H_ */ diff --git a/shufflecake-userland-legacy/include/utils/sflc.h b/shufflecake-userland-legacy/include/utils/sflc.h deleted file mode 100644 index 4bab1ba..0000000 --- a/shufflecake-userland-legacy/include/utils/sflc.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Miscellaneous constants that must match with the definitions in the Kernel module TODO: MOVE TO sflc_constans.h - */ - -#ifndef _UTILS_SFLC_H_ -#define _UTILS_SFLC_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/* Name of the DM target in the kernel */ -#define SFLC_DM_TARGET_NAME "shufflecake" - -/* Disk constants */ -#define SFLC_SECTOR_SIZE 4096 /* bytes */ -#define KERNEL_SECTOR_SIZE 512 /* bytes */ -#define SFLC_SECTOR_SCALE (SFLC_SECTOR_SIZE / KERNEL_SECTOR_SIZE) - -/* Max number of volumes in a device */ -#define SFLC_DEV_MAX_VOLUMES 15 - -/* Max total number of open devices at any given time */ -#define SFLC_TOT_MAX_DEVICES 1024 -/* A volume name is sflc__ */ -#define SFLC_MAX_VOL_NAME_LEN 15 - -/* A slice index is represented over 32 bits */ -#define SFLC_SLICE_IDX_WIDTH 4 /* bytes */ -/* A position map block contains 1024 slice indices */ -#define SFLC_SLICE_IDX_PER_BLOCK (SFLC_SECTOR_SIZE / SFLC_SLICE_IDX_WIDTH) - -// IV length for AES-CTR -#define SFLC_AESCTR_IVLEN 16 /* bytes */ - -/* An IV block can encrypt 256 data blocks */ -#define SFLC_DATA_BLOCKS_PER_IV_BLOCK (SFLC_SECTOR_SIZE / SFLC_AESCTR_IVLEN) -/* A logical slice spans 256 blocks of data (1 MiB) */ -#define SFLC_BLOCKS_PER_LOG_SLICE SFLC_DATA_BLOCKS_PER_IV_BLOCK -/* A physical slice also includes the IV block */ -#define SFLC_BLOCKS_PER_PHYS_SLICE (1 + SFLC_BLOCKS_PER_LOG_SLICE) - -/* A PSI of 0xFFFFFFFF indicates an unassigned LSI */ -#define SFLC_EPM_FILLER 0xFF - -/* The sysfs file containing the next available device ID */ -#define SFLC_SYSFS_NEXTDEVID "/sys/module/dm_sflc/next_dev_id" -/* The sysfs directory containing a subdir for each (underlying) block device */ -#define SFLC_SYSFS_BDEVS_DIR "/sys/module/dm_sflc/bdevs" -/* Within each bdev's subdir, this file lists its open volumes */ -#define SFLC_SYSFS_OPENVOLUMES_FILENAME "volumes" -/* Within each bdev's subdir, this file shows its Shufflecake device ID */ -#define SFLC_SYSFS_DEVID_FILENAME "dev_id" - -/* TODO: reasonable? */ -#define SFLC_BDEV_PATH_MAX_LEN 1024 - -/* For when you can't be bothered to upper-bound a buffer size */ -#define SFLC_BIGBUFSIZE 4096 - - -#endif /* _UTILS_SFLC_H_ */ diff --git a/shufflecake-userland-legacy/src/cli/close.c b/shufflecake-userland-legacy/src/cli/close.c deleted file mode 100644 index fdbaa28..0000000 --- a/shufflecake-userland-legacy/src/cli/close.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "cli.h" -#include "commands.h" -#include "utils/sflc.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* - * Close volumes - * - * @return Error code, 0 on success - */ -int sflc_cli_close(char *block_device) -{ // Requires: block_device is a correct block device path -// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; -// int err; - -// /* Gather (absolute) path to underlying block device */ -// printf("Enter the absolute path to the underlying block device containing the Shufflecake volumes to close: "); -// err = sflc_safeReadLine(bdev_path, SFLC_BDEV_PATH_MAX_LEN + 2); -// if (err) { -// sflc_log_error("Could not read path to underlying block device; error %d", err); -// return err; -// } -// /* Check that it is absolute */ -// if (bdev_path[0] != '/') { -// printf("The path to the block device must be absolute"); -// return EINVAL; -// } -// - - - /* Actually perform the command */ -// return sflc_cmd_closeVolumes(bdev_path); - - - return sflc_cmd_closeVolumes(block_device); - -} diff --git a/shufflecake-userland-legacy/src/cli/dispatch.c b/shufflecake-userland-legacy/src/cli/dispatch.c deleted file mode 100644 index 01da250..0000000 --- a/shufflecake-userland-legacy/src/cli/dispatch.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include - -#include "cli.h" -#include "utils/sflc.h" -#include "utils/disk.h" -#include "utils/log.h" -#include "sflc_constants.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/* Used by argp to provide the automatic "-V" option */ -const char *argp_program_version = SFLC_VERSION; -/* Used by argp to provide the automatic "--help" option */ -const char *argp_program_bug_address = ""; - -/* Signed integer values representing a handle for each option */ -#define SFLC_OPT_NUMVOLS_KEY 'n' // Positive and printable: also serves as short command-line option -#define SFLC_OPT_SKIPRAND_KEY (-'r') // Negative, because we don't want a short option available for this - - -/***************************************************** - * TYPES * - *****************************************************/ - -enum sflc_cli_action { - SFLC_ACT_INIT, - SFLC_ACT_OPEN, - SFLC_ACT_CLOSE, - SFLC_ACT_TESTPWD, - SFLC_ACT_CHANGEPWD -}; - -struct sflc_cli_arguments { - enum sflc_cli_action act; - char *block_device; - int num_volumes; - bool skip_randfill; -}; - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static error_t _parseArgpKey(int key, char *arg, struct argp_state *state); - - -/***************************************************** - * PRIVATE VARIABLES * - *****************************************************/ - -/* Doc strings */ -static char args_doc[] = "ACTION "; -static char doc[] = - "Shufflecake is a plausible deniability (hidden storage) layer for Linux.\n" - "See official website at for more info.\n" - "Possible values for mandatory ACTION are:\n\n" - - "\tinit:\t\tInitialise a block device for Shufflecake use, formatting\n" - "\t\t\theaders with provided passwords and overwriting with random\n" - "\t\t\tdata. WARNING: THIS WILL ERASE THE CONTENT OF THE DEVICE.\n\n" - - "\topen:\t\tOpen a hierarchy of Shufflecake volumes within a device by\n" - "\t\t\tasking a single user password. Virtual devices will appear\n" - "\t\t\tin /dev/mapper. Notice: freshly created device must be\n" - "\t\t\tuser-formatted and mounted in order to be used.\n\n" - - "\tclose:\t\tClose all open Shufflecake volumes supported by given\n" - "\t\t\tdevice.\n\n" - - "\ttestpwd:\tTest whether a given password unlocks any volume within\n" - "\t\t\tthe block device and, if so, show its index.\n\n" - - "\tchangepwd:\tChange the password unlocking a certain volume.\n\n" - - "Possible options are:"; - -/* Description of each option */ -static struct argp_option options[] = { - {"num-volumes", SFLC_OPT_NUMVOLS_KEY, "num", 0, - "Specify number of volumes to be created with `init'. Must be an integer between 1 and 15.", 0 }, // TODO: define MAX_VOLS instead of hardcoding 15 - {"skip-randfill", SFLC_OPT_SKIPRAND_KEY, 0, 0, - "Skip pre-overwriting block device with random data, only valid with `init'. Faster but less secure. Use only for debugging or testing."}, - {0} -}; - -/* Wrapper containing everything */ -static struct argp argp = {options, _parseArgpKey, args_doc, doc}; - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* - * The following is the main dispatch function called by the main to parse - * the arguments and dispatch to the right command. - * - * @param argc The number of command-line arguments supplied to the main - * @param argv The arguments - * - * @return Error code, 0 on success - */ - -int sflc_cli_dispatch(int argc, char **argv) { - struct sflc_cli_arguments arguments; - - arguments.act = -1; - arguments.block_device = NULL; - arguments.num_volumes = 0; - arguments.skip_randfill = false; - - /* Parse */ - argp_parse(&argp, argc, argv, 0, 0, &arguments); - - /* Check options consistency */ - if (arguments.num_volumes && arguments.act != SFLC_ACT_INIT) { - printf("Error: --num-volumes (-n) can only be combined with `init'.\n"); - return EINVAL; - } - /* Check options consistency */ - if (arguments.skip_randfill && arguments.act != SFLC_ACT_INIT) { - printf("Error: --skip-randfill can only be combined with `init'.\n"); - return EINVAL; - } - /* Check that input is actually a block device */ - if (strncmp(arguments.block_device, "/dev/", 5) != 0 || !sflc_disk_isBlockDevice(arguments.block_device)) { - printf("Error: '%s' is not a valid block device.\n", arguments.block_device); - return EINVAL; - } - - /* Dispatch to specific command */ - if (arguments.act == SFLC_ACT_INIT) { - return sflc_cli_init(arguments.block_device, arguments.num_volumes, arguments.skip_randfill); - } - if (arguments.act == SFLC_ACT_OPEN) { - return sflc_cli_open(arguments.block_device); - } - if (arguments.act == SFLC_ACT_CLOSE) { - return sflc_cli_close(arguments.block_device); - } - if (arguments.act == SFLC_ACT_TESTPWD) { - return sflc_cli_testPwd(arguments.block_device); - } - if (arguments.act == SFLC_ACT_CHANGEPWD) { - return sflc_cli_changePwd(arguments.block_device); - } - - printf("\n"); - - return EINVAL; -} - - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -static error_t _parseArgpKey(int key, char *arg, struct argp_state *state) { - struct sflc_cli_arguments *arguments = state->input; - - switch (key) { - /* We are parsing an argument (not an option) */ - case ARGP_KEY_ARG: - /* We are parsing the command */ - if (state->arg_num == 0) { - if (strcmp(arg, SFLC_CLI_INITACT) == 0) { - arguments->act = SFLC_ACT_INIT; - } else if (strcmp(arg, SFLC_CLI_OPENACT) == 0) { - arguments->act = SFLC_ACT_OPEN; - } else if (strcmp(arg, SFLC_CLI_CLOSEACT) == 0) { - arguments->act = SFLC_ACT_CLOSE; - } else if (strcmp(arg, SFLC_CLI_TESTPWDACT) == 0) { - arguments->act = SFLC_ACT_TESTPWD; - } else if (strcmp(arg, SFLC_CLI_CHANGEPWDACT) == 0) { - arguments->act = SFLC_ACT_CHANGEPWD; - } else { - argp_error(state, "Invalid action. Please enter one and only one of: `%s', `%s', `%s', '%s', or '%s'.", - SFLC_CLI_INITACT, SFLC_CLI_OPENACT, SFLC_CLI_CLOSEACT, SFLC_CLI_TESTPWDACT, SFLC_CLI_CHANGEPWDACT); - } - /* We are parsing the block device */ - } else if (state->arg_num == 1) { - arguments->block_device = arg; - /* Too many arguments */ - } else { - argp_usage(state); - } - break; - - /* We are parsing an option */ - case SFLC_OPT_NUMVOLS_KEY: - arguments->num_volumes = atoi(arg); - break; - case SFLC_OPT_SKIPRAND_KEY: - arguments->skip_randfill = true; - break; - - /* End of arg list */ - case ARGP_KEY_END: - if (state->arg_num < 2) { - argp_usage(state); - } - break; - - /* Unrecognised key */ - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} diff --git a/shufflecake-userland-legacy/src/cli/init.c b/shufflecake-userland-legacy/src/cli/init.c deleted file mode 100644 index 302a96d..0000000 --- a/shufflecake-userland-legacy/src/cli/init.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "cli.h" -#include "commands.h" -#include "utils/sflc.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* - * Create volumes - * - * @return Error code, 0 on success - */ -int sflc_cli_init(char *block_device, int num_volumes, int skip_randfill) -{ // Requires: block_device is a correct block device path - sflc_cmd_InitArgs args; - char str_nrvols[SFLC_BIGBUFSIZE]; - char *pwds[SFLC_DEV_MAX_VOLUMES]; - size_t pwd_lens[SFLC_DEV_MAX_VOLUMES]; - int err; - - args.bdev_path = block_device; - - // Check if number of volumes was nonzero passed by command line already - if (num_volumes) { - args.nr_vols = num_volumes; - } else { - // If not, ask user for number of volumes - printf("\nHow many volumes do you want to create (maximum is %d)? ", SFLC_DEV_MAX_VOLUMES); - err = sflc_safeReadLine(str_nrvols, SFLC_BIGBUFSIZE); - if (err) { - sflc_log_error("Error: could not read number of volumes; error %d", err); - return err; - } - /* Parse string */ - if (sscanf(str_nrvols, "%lu\n", &args.nr_vols) != 1) { - sflc_log_error("Error: could not parse number of volumes"); - return EINVAL; - } - } - - /* Bounds check */ - if (args.nr_vols <= 0) { - printf("Error: number of volumes must be a positive integer"); - return EINVAL; - } - if (args.nr_vols > SFLC_DEV_MAX_VOLUMES) { - printf("Number of volumes too high, Shufflecake supports up to %d volumes on a single device", SFLC_DEV_MAX_VOLUMES); - return EINVAL; - } - - /* Collects the passwords */ - printf("\nNow you will be asked to insert the passwords for all the volumes you want to create, \nfrom " - "volume 0 (the least secret) to volume %lu (the most secret).\n\n", args.nr_vols - 1); - size_t i; - for (i = 0; i < args.nr_vols; i++) { - // Allocate pwd - pwds[i] = malloc(SFLC_BIGBUFSIZE); - - /* Read it */ - printf("Choose password for volume %lu (must not be empty): ", i); - err = sflc_safeReadLine(pwds[i], SFLC_BIGBUFSIZE); - if (err) { - sflc_log_error("Could not read password for volume %lu; error %d", i, err); - return err; - } - - /* You can trust the length of strings input this way */ - pwd_lens[i] = strlen(pwds[i]); - /* Check non-empty */ - if (pwd_lens[i] == 0) { - sflc_log_error("Password cannot be empty!"); - return EINVAL; - } - } - /* Assign them */ - args.pwds = pwds; - args.pwd_lens = pwd_lens; - - args.no_randfill = skip_randfill; - - /* Actually perform the command */ - return sflc_cmd_initVolumes(&args); -} diff --git a/shufflecake-userland-legacy/src/cli/open.c b/shufflecake-userland-legacy/src/cli/open.c deleted file mode 100644 index 45464c9..0000000 --- a/shufflecake-userland-legacy/src/cli/open.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "cli.h" -#include "commands.h" -#include "utils/sflc.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* - * Open volumes - * - * @return Error code, 0 on success - */ -int sflc_cli_open(char *block_device) -{ // Requires: block_device is a correct block device path - sflc_cmd_OpenArgs args; - char pwd[SFLC_BIGBUFSIZE]; - size_t pwd_len; - int err; - - args.bdev_path = block_device; - - /* Gather password */ - printf("Enter the password for the most secret volume you want to open: "); - err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); - if (err) { - sflc_log_error("Could not read password; error %d", err); - return err; - } - /* You can trust the length of strings input this way */ - pwd_len = strlen(pwd); - /* Check non-empty */ - if (pwd_len == 0) { - sflc_log_error("Password cannot be empty!"); - return EINVAL; - } - /* Assign them */ - args.pwd = pwd; - args.pwd_len = pwd_len; - - /* Actually perform the command */ - return sflc_cmd_openVolumes(&args); -} diff --git a/shufflecake-userland-legacy/src/commands/change_pwd.c b/shufflecake-userland-legacy/src/commands/change_pwd.c deleted file mode 100644 index 2ef64e0..0000000 --- a/shufflecake-userland-legacy/src/commands/change_pwd.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "commands.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/file.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Changes the specified volume's password. - * - * @param args->bdev_path The underlying block device - * @param args->dmb_cell The DMB cell to re-encrypt - * @param args->new_pwd The new password - * @param args->new_pwd_len Its length - * - * @return Error code, 0 on success - */ -int sflc_cmd_changePwd(sflc_cmd_ChangePwdArgs *args) -{ - /* Delegate entirely to the function reading the DMB */ - return sflc_ops_rewriteDmbCell(args->bdev_path, args->dmb_cell, args->new_pwd, args->new_pwd_len); -} diff --git a/shufflecake-userland-legacy/src/commands/close.c b/shufflecake-userland-legacy/src/commands/close.c deleted file mode 100644 index 73a7605..0000000 --- a/shufflecake-userland-legacy/src/commands/close.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "commands.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/string.h" -#include "utils/file.h" -#include "utils/disk.h" -#include "utils/log.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Reads the list of volumes from sysfs */ -static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols); - -/* Close them all (in reverse order of opening) */ -static int _closeVolumes(char **labels, size_t nr_vols); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Close all volumes on the device (reads the list from sysfs) - * - * @param bdev_path The path to the underlying block device - * - * @return Error code, 0 on success - */ -int sflc_cmd_closeVolumes(char *bdev_path) -{ - char *labels[SFLC_DEV_MAX_VOLUMES]; - size_t nr_vols; - int err; - - /* Allocate labels */ - size_t i; - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { - labels[i] = malloc(SFLC_MAX_VOL_NAME_LEN + 1); - if (!labels[1]) { - sflc_log_error("Could not allocate volume label %lu", i); - return ENOMEM; // Do not free the ones already allocated - } - } - - /* Read them */ - err = _buildVolumesList(bdev_path, labels, &nr_vols); - if (err) { - sflc_log_error("Could not read volume list from sysfs; error %d", err); - goto out; - } - - /* Close the volumes (in reverse order of opening) */ - err = _closeVolumes(labels, nr_vols); - if (err) { - sflc_log_error("Could not close volumes; error %d", err); - goto out; - } - - /* No prob */ - err = 0; - - -out: - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { - free(labels[i]); - } - return err; -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Reads from sysfs to build the volumes list */ -static int _buildVolumesList(char *bdev_path, char **labels, size_t *nr_vols) -{ - char *bdev_name; - char devid_path[SFLC_BIGBUFSIZE]; - char *str_devid; - size_t dev_id; - char nrvolumes_path[SFLC_BIGBUFSIZE]; - char *str_nrvolumes; - - /* Get device name as : */ - bdev_name = sflc_disk_getDeviceName(bdev_path); - if(!bdev_name) { - sflc_log_error("Could not allocate device name"); - return ENOMEM; - } - /* Build path to sysfs file containing device ID */ - sprintf(devid_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name, SFLC_SYSFS_DEVID_FILENAME); - /* Build path to sysfs file containing number of open volumes */ - sprintf(nrvolumes_path, "%s/%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_name, SFLC_SYSFS_OPENVOLUMES_FILENAME); - - /* Read the device ID */ - str_devid = sflc_readFile(devid_path); - if (!str_devid) { - sflc_log_error("Could not read file %s", devid_path); - return EBADF; - } - /* Parse the device ID */ - if (sscanf(str_devid, "%lu", &dev_id) != 1) { - sflc_log_error("Could not parse device ID:\n%s", str_devid); - return EBADF; - } - - /* Read the number of volumes */ - str_nrvolumes = sflc_readFile(nrvolumes_path); - if (!str_nrvolumes) { - sflc_log_error("Could not read file %s", nrvolumes_path); - return EBADF; - } - /* Parse the number of volumes */ - if (sscanf(str_nrvolumes, "%lu", nr_vols) != 1) { - sflc_log_error("Could not parse number of volumes:\n%s", str_nrvolumes); - return EBADF; - } - - /* Just to be sure */ - if (*nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Something is seriously wrong, sysfs file says there are %lu open volumes, that's too many!", *nr_vols); - return EBADF; - } - - /* Build labels */ - size_t i; - for (i = 0; i < *nr_vols; i++) { - sprintf(labels[i], "sflc_%lu_%lu", dev_id, i); - } - - return 0; -} - - -/* Close them all (in reverse order of opening) */ -static int _closeVolumes(char **labels, size_t nr_vols) -{ - int err; - - /* Eazy peazy */ - int i; - for (i = nr_vols-1; i >= 0; i--) { - err = sflc_ops_closeVolume(labels[i]); - if (err) { - sflc_log_error("Could not close volume %s; error %d", labels[i], err); - return err; - } - sflc_log_debug("Closed volume %s", labels[i]); - printf("Closed volume /dev/mapper/%s\n", labels[i]); - } - - return 0; -} - diff --git a/shufflecake-userland-legacy/src/commands/init.c b/shufflecake-userland-legacy/src/commands/init.c deleted file mode 100644 index cd21b03..0000000 --- a/shufflecake-userland-legacy/src/commands/init.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "commands.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/disk.h" -#include "utils/crypto.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -/* The device is randomised in chunks of 1024 blocks (arbitrary number) */ -#define SFLC_BLOCKS_IN_RAND_CHUNK 1024 -/* That's 4 MiB */ -#define SFLC_RAND_CHUNK_SIZE (SFLC_BLOCKS_IN_RAND_CHUNK * SFLC_SECTOR_SIZE) - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Fill the device with random data */ -static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Create N volumes (only formats the device header, does not open the volumes). - * Creates them in order from 0 to N-1, so as to induce a back-linked list on the device. - * - * @param args->bdev_path The path to the underlying block device - * @param args->nr_vols The number of volumes to create - * @param args->pwds The array of passwords for the various volumes - * @param args->pwd_lens The length of each password - * @param args->no_randfill A boolean switch indicating that the volume should not - * be filled entirely with random data prior to formatting. - * - * @return Error code, 0 on success - */ -int sflc_cmd_initVolumes(sflc_cmd_InitArgs *args) -{ - sflc_Dmb dmb; - sflc_Vmb vmb; - int64_t dev_size; - size_t nr_slices; - int err; - - /* Sanity check */ - if (args->nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot create %lu volumes on a single device", args->nr_vols); - return EINVAL; - } - - /* Get device size */ - dev_size = sflc_disk_getSize(args->bdev_path); - if (dev_size < 0) { - err = -dev_size; - sflc_log_error("Could not get device size for %s; error %d", args->bdev_path, err); - return err; - } - /* Convert to number of slices */ - nr_slices = sflc_disk_maxSlices(dev_size); - sflc_log_debug("Device %s has %ld blocks, corresponding to %lu logical slices", args->bdev_path, dev_size, nr_slices); - - /* Fill disk with random bytes, if requested */ - if (!args->no_randfill) { - err = _fillDiskWithRandom(args->bdev_path, (uint64_t) dev_size); - if (err) { - sflc_log_error("Could not fill device %s with random bytes; error %d", args->bdev_path, err); - return err; - } - } - - /* Fill the DMB */ - dmb.nr_vols = args->nr_vols; - /* Sample the VMB keys */ - size_t i; - for (i = 0; i < dmb.nr_vols; i++) { - err = sflc_rand_getStrongBytes(dmb.vmb_keys[i], SFLC_CRYPTO_KEYLEN); - if (err) { - sflc_log_error("Could not sample VMB key number %lu; error %d", i , err); - return err; - } - } - /* And write (encrypted) to disk */ - err = sflc_ops_writeDmb(args->bdev_path, args->pwds, args->pwd_lens, &dmb); - if (err) { - sflc_log_error("Could not create DMB and write it to disk; error %d", err); - return err; - } - - /* Write the volume headers */ - vmb.nr_slices = nr_slices; - for (i = 0; i < args->nr_vols; i++) { - /* This volume's prev_vmb_key */ - if (i > 0) { - memcpy(vmb.prev_vmb_key, dmb.vmb_keys[i-1], SFLC_CRYPTO_KEYLEN); - } - /* Sample this volume's VEK */ - sflc_rand_getStrongBytes(vmb.volume_key, SFLC_CRYPTO_KEYLEN); - - /* Write complete volume header (VMB + PM) */ - err = sflc_ops_writeVolumeHeader(args->bdev_path, dmb.vmb_keys[i], &vmb, i); - if (err) { - sflc_log_error("Error writing volume header %lu on device %s; error %d", i, args->bdev_path, err); - return err; - } - } - printf("Created %lu volumes on device %s\n", args->nr_vols, args->bdev_path); - - return 0; -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Fill the device with random data */ -static int _fillDiskWithRandom(char *bdev_path, uint64_t dev_size) -{ - char *rand_chunk; - int err; - - /* Allocate chunk */ - rand_chunk = malloc(SFLC_RAND_CHUNK_SIZE); - if (!rand_chunk) { - sflc_log_error("Could not allocate %d bytes for chunk of random data", SFLC_RAND_CHUNK_SIZE); - return ENOMEM; - } - - /* Loop to write random data in chunks */ - uint64_t blocks_remaining = dev_size; - uint64_t sector = 0; - while (blocks_remaining > 0) { - uint64_t blocks_to_write = - (blocks_remaining > SFLC_BLOCKS_IN_RAND_CHUNK) ? SFLC_BLOCKS_IN_RAND_CHUNK : blocks_remaining; - uint64_t bytes_to_write = blocks_to_write * SFLC_SECTOR_SIZE; - - /* Sample random bytes */ - err = sflc_rand_getWeakBytes(rand_chunk, bytes_to_write); - if (err) { - sflc_log_error("Could not sample %lu random bytes to write on disk; error %d", bytes_to_write, err); - goto out; - } - - /* Write on disk */ - err = sflc_disk_writeManySectors(bdev_path, sector, rand_chunk, blocks_to_write); - if (err) { - sflc_log_error("Could not write random bytes on disk; error %d", err); - goto out; - } - - /* Advance loop */ - sector += blocks_to_write; - blocks_remaining -= blocks_to_write; - } - - /* No prob */ - err = 0; - - -out: - free(rand_chunk); - return err; -} - diff --git a/shufflecake-userland-legacy/src/commands/open.c b/shufflecake-userland-legacy/src/commands/open.c deleted file mode 100644 index da0c4f0..0000000 --- a/shufflecake-userland-legacy/src/commands/open.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include - -#include "commands.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/disk.h" -#include "utils/file.h" -#include "utils/log.h" -#include "utils/string.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Read the next device ID in sysfs */ -static int _getNextDevId(size_t *next_dev_id); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Open M volumes, from the first one down to the one whose pwd is provided. - * Scans the DMB cells to find which one is unlocked by the provided pwd; then, - * using the decrypted VMB key, unlocks the M-th VMB; then, iteratively using - * the prev_vmb_key field, unlocks all the previous VMBs; then, using the - * decrypted VMB keys, opens the volumes "in order" from 1 to M. - * - * @param args->bdev_path The underlying block device - * @param args->pwd The password - * @param args->pwd_len The password length - * - * @return Error code (also if no volume could be opened), 0 on success - */ -int sflc_cmd_openVolumes(sflc_cmd_OpenArgs *args) -{ - int64_t dev_size; - size_t nr_slices; - sflc_DmbCell dmb_cell; - sflc_Vmb vmbs[SFLC_DEV_MAX_VOLUMES]; - size_t dev_id; - int err; - char bdev_path_noslash[SFLC_BDEV_PATH_MAX_LEN + 1]; - char opendev_path[SFLC_BIGBUFSIZE]; - DIR* opendev_dir; - - /* Check if device is already opened and abort if so. */ - /* Step 1: rebuild sysfs directory name of device to be checked. */ - /* TODO: this is duplicate code from close.c we might want to modularize it. */ - /* Remove the slashes from the bdev_path (replace with underscores). */ - strcpy(bdev_path_noslash, args->bdev_path); - sflc_str_replaceAll(bdev_path_noslash, '/', '_'); - /* Build sysfs path of opened device */ - sprintf(opendev_path, "%s/%s", SFLC_SYSFS_BDEVS_DIR, bdev_path_noslash); - /* Step 2: check if directory exists. */ - opendev_dir = opendir(opendev_path); - if (opendev_dir) { - /* Directory exists. */ - closedir(opendev_dir); - err = EEXIST; - sflc_log_error("Device %s seems to be already open; error %d", args->bdev_path, err); - return err; - } - - /* Get number of slices */ - dev_size = sflc_disk_getSize(args->bdev_path); - if (dev_size < 0) { - err = -dev_size; - sflc_log_error("Could not read device size for %s; error %d", args->bdev_path, err); - return err; - } - nr_slices = sflc_disk_maxSlices(dev_size); - - /* Find volume opened by the pwd */ - err = sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, &dmb_cell); - if (err) { - sflc_log_error("Could not read DMB; error %d", err); - return err; - } - /* Was there one? */ - if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("The provided password opens no volume on the device"); - return EINVAL; - } - printf("Password is correct! Opening volumes...\n"); - - /* Unlock VMBs "backwards" */ - int i; // Needs sign, because loop ends on i>=0 - for (i = dmb_cell.vol_idx; i >= 0; i--) { - /* Which VMB key to use? */ - char *vmb_key; - if (i == dmb_cell.vol_idx) { - // The one unlocked by pwd - vmb_key = dmb_cell.vmb_key; - } else { - // Or the prev_vmb_key from last iteration - vmb_key = vmbs[i+1].prev_vmb_key; - } - - /* Read and unlock VMB */ - err = sflc_ops_readVmb(args->bdev_path, vmb_key, nr_slices, (size_t) i, &vmbs[i]); - if (err) { - sflc_log_error("Could not read VMB %d on device %s; error %d", - i, args->bdev_path, err); - return err; - } - } - - /* Get the ID that will be assigned to the block device */ - err = _getNextDevId(&dev_id); - if (err) { - sflc_log_error("Could not get next device ID; error %d", err); - return err; - } - sflc_log_debug("Next device ID is %lu", dev_id); - - /* Open volumes "in order" */ - for (i = 0; i <= dmb_cell.vol_idx; i++) { - err = sflc_ops_openVolume(args->bdev_path, dev_id, (size_t) i, &vmbs[i]); - if (err) { - sflc_log_error("Could not open volume %d; error %d. " - "Previous volumes on the device might have already " - "been opened, it's recommended you close them", - i, err); - return err; - } - sflc_log_debug("Successfully opened volume %d with VMB key", i); - printf("Opened volume /dev/mapper/sflc_%lu_%d\n", dev_id, i); - } - - return 0; -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Read the next device ID in sysfs */ -static int _getNextDevId(size_t *next_dev_id) -{ - char *str_nextdevid; - int err; - - /* Read sysfs entry */ - str_nextdevid = sflc_readFile(SFLC_SYSFS_NEXTDEVID); - if (!str_nextdevid) { - sflc_log_error("Could not read sysfs entry %s", SFLC_SYSFS_NEXTDEVID); - return EINVAL; - } - - /* Parse integer */ - if (sscanf(str_nextdevid, "%lu", next_dev_id) != 1) { - sflc_log_error("Error parsing content of file %s", SFLC_SYSFS_NEXTDEVID); - err = EINVAL; - goto err_devid; - } - /* Sanity check */ - if (*next_dev_id >= SFLC_TOT_MAX_DEVICES) { - sflc_log_error("There are already %d open devices, this is the maximum allowed", SFLC_TOT_MAX_DEVICES); - err = E2BIG; - goto err_devid; - } - - /* All good */ - err = 0; - - -err_devid: - free(str_nextdevid); - return err; -} - diff --git a/shufflecake-userland-legacy/src/header/device_master_block.c b/shufflecake-userland-legacy/src/header/device_master_block.c deleted file mode 100644 index cdd1f8c..0000000 --- a/shufflecake-userland-legacy/src/header/device_master_block.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "header.h" -#include "utils/crypto.h" -#include "utils/log.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* AES-GCM-encrypt a VMB key with the KDF-generated key */ -static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vmb_key, char *dmb_cell); - -/* AES-GCM-decrypt a VMB key with the KDF-generated key */ -static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool *match); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Builds the on-disk device master block (indistinguishable from random). - * - * @param dmb The list of VMB keys - * @param pwds The passwords of the volumes - * @param pwd_lens Their lengths - * @param disk_block The 4096-byte buffer that will contain the random-looking - * bytes to be written on-disk - * - * @return The error code, 0 on success - */ -int sflc_dmb_seal(sflc_Dmb *dmb, char **pwds, size_t *pwd_lens, char *disk_block) -{ - char *salt; - int err; - - /* Sanity check */ - if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot create DMB with %lu volumes, too many!", dmb->nr_vols); - return EINVAL; - } - - /* Randomise whole block */ - err = sflc_rand_getWeakBytes(disk_block, SFLC_SECTOR_SIZE); - if (err) { - sflc_log_error("Could not randomise DMB; error %d", err); - return err; - } - - /* Assign salt */ - salt = disk_block; - - /* Loop over all VMB keys to encrypt them */ - size_t i; - for (i = 0; i < dmb->nr_vols; i++) { - char *dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); - - /* Encrypt it */ - err = _encryptVmbKeyWithPwd(salt, pwds[i], pwd_lens[i], dmb->vmb_keys[i], dmb_cell); - if (err) { - sflc_log_error("Could not encrypt VMB key number %lu; error %d", i, err); - return err; - } - } - - return 0; -} - - -/** - * "Decrypt" a single VMB key from the on-disk DMB, using its password (perform the KDF). - * - * @param disk_block The on-disk sealed DMB - * @param pwd The password locking the VMB key - * @param pwd_len Its length - * - * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) - * - * @return Error code, 0 on success - */ -int sflc_dmb_unseal(char *disk_block, char *pwd, size_t pwd_len, sflc_DmbCell *dmb_cell) -{ - // KDF salt - char *salt; - // The KDF-derived key - char kek[SFLC_CRYPTO_KEYLEN]; - // The unlocked VMB key - char vmb_key[SFLC_CRYPTO_KEYLEN]; - // Error code - int err; - - /* Derive KEK once and for all */ - salt = disk_block; - err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); - if (err) { - sflc_log_error("Could not perform KDF: error %d", err); - goto bad_kdf; - } - sflc_log_debug("Successfully derived key-encryption-key with KDF"); - - /* Init dmb->vol_idx to invalid */ - dmb_cell->vol_idx = SFLC_DEV_MAX_VOLUMES; - /* Try all DMB cells */ - size_t i; - for (i = 0; i < SFLC_DEV_MAX_VOLUMES; i++) { - char *enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (i * SFLC_DMB_CELL_SIZE); - bool match; - - /* Try to decrypt this one */ - err = _decryptVmbKeyWithPwd(enc_dmb_cell, kek, vmb_key, &match); - if (err) { - sflc_log_error("Error decrypting DMB cell number %lu; error %d", i, err); - goto bad_decrypt; - } - - /* If MAC matched, mark it, but don't break from the loop (timing attacks) */ - if (match) { - sflc_log_debug("The provided password unlocks volume %lu", i); - dmb_cell->vol_idx = i; - memcpy(dmb_cell->vmb_key, vmb_key, SFLC_CRYPTO_KEYLEN); - } - } - - // No prob - err = 0; - - -bad_decrypt: -bad_kdf: - /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLC_CRYPTO_KEYLEN); - return err; -} - -/** - * Re-encrypt the content of the specified DMB cell. - * - * @param disk_block The on-disk sealed DMB - * @param dmb_cell The DMB cell to re-encrypt - * @param pwd The new password - * @param pwd_len The password's length - * - * @return Error code, 0 on success - */ -int sflc_dmb_setCell(char *disk_block, sflc_DmbCell *dmb_cell, char *pwd, size_t pwd_len) -{ - char *salt; - char *enc_dmb_cell; - int err; - - /* Sanity check */ - if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot set DMB cell %lu: out of bounds!", dmb_cell->vol_idx); - return EINVAL; - } - - /* Pointers inside DMB */ - salt = disk_block; - enc_dmb_cell = (salt + SFLC_ARGON_SALTLEN) + (dmb_cell->vol_idx * SFLC_DMB_CELL_SIZE); - /* Encrypt with KDF-derived key */ - err = _encryptVmbKeyWithPwd(salt, pwd, pwd_len, dmb_cell->vmb_key, enc_dmb_cell); - if (err) { - sflc_log_error("Could not re-encrypt VMB key number %lu; error %d", dmb_cell->vol_idx, err); - return err; - } - sflc_log_debug("Successfully re-encrypted VMB key number %lu", dmb_cell->vol_idx); - - return 0; -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* AES-GCM-encrypt a VMB key with the KDF-generated key */ -static int _encryptVmbKeyWithPwd(char *salt, char *pwd, size_t pwd_len, char *vmb_key, char *dmb_cell) -{ - // Pointers inside the block - char *iv = dmb_cell; - char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLC_CRYPTO_KEYLEN; - // Key-encryption-key derived from KDF - char kek[SFLC_CRYPTO_KEYLEN]; - // Error code - int err; - - /* Derive KEK */ - err = sflc_argon2id_derive(pwd, pwd_len, salt, kek); - if (err) { - sflc_log_error("Could not perform KDF: error %d", err); - goto bad_kdf; - } - sflc_log_debug("Successfully derived key-encryption-key with KDF"); - - /* Sample VMB_IV */ - err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); - if (err) { - sflc_log_error("Could not sample prologue IV: error %d", err); - goto bad_sample_iv; - } - sflc_log_debug("Successfully sampled prologue IV"); - - /* Encrypt the VMB key */ - err = sflc_aes256gcm_encrypt(kek, vmb_key, SFLC_CRYPTO_KEYLEN, iv, enc_vmb_key, mac); - if (err) { - sflc_log_error("Could not encrypt the VMB key: error %d", err); - goto bad_encrypt; - } - sflc_log_debug("Successfully encrypted VMB key with key-encryption-key"); - - // No prob - err = 0; - - -bad_encrypt: -bad_sample_iv: -bad_kdf: - /* Always wipe the key from memory, even on success */ - memset(kek, 0, SFLC_CRYPTO_KEYLEN); - return err; -} - -/* AES-GCM-decrypt a VMB key with the KDF-generated key */ -static int _decryptVmbKeyWithPwd(char *dmb_cell, char *kek, char *vmb_key, bool *match) -{ - // Pointers inside the block - char *iv = dmb_cell; - char *enc_vmb_key = iv + SFLC_AESGCM_PADDED_IVLEN; - char *mac = enc_vmb_key + SFLC_CRYPTO_KEYLEN; - // Error code - int err; - - /* Decrypt the VMB key */ - err = sflc_aes256gcm_decrypt(kek, enc_vmb_key, SFLC_CRYPTO_KEYLEN, mac, iv, vmb_key, match); - if (err) { - sflc_log_error("Error while decrypting VMB key: error %d", err); - return err; - } - sflc_log_debug("Decrypted VMB key: MAC match = %d", *match); - - return 0; -} - diff --git a/shufflecake-userland-legacy/src/header/position_map.c b/shufflecake-userland-legacy/src/header/position_map.c deleted file mode 100644 index f2b8144..0000000 --- a/shufflecake-userland-legacy/src/header/position_map.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "header.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/math.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Create an encrypted empty position map for the given number of slices. - * Allocates the internal pointers of the EPM structure. - * On failure, does not free the allocated memory. - * - * @param nr_slices The number of slices the device will be composed of. - * @param volume_key The volume's data section encryption key, used to encrypt the - * position map as well. - * @param epm The EncPosMap struct to be initialised. - * - * @return Error code, 0 on success */ -int sflc_epm_create(size_t nr_slices, char *volume_key, sflc_EncPosMap *epm) -{ - size_t nr_pmbs; - size_t nr_arrays; - int err; - - // Each PosMapBlock holds up to 1024 PSIs (Physical Slice Index) - nr_pmbs = ceil(nr_slices, SFLC_SLICE_IDX_PER_BLOCK); - // Each array holds up to 256 PosMapBlocks - nr_arrays = ceil(nr_pmbs, SFLC_BLOCKS_PER_LOG_SLICE); - - // Fill the EPM numeric fields - epm->nr_arrays = nr_arrays; - // All arrays are full except the last one - epm->nr_last_pmbs = nr_pmbs - (SFLC_BLOCKS_PER_LOG_SLICE * (nr_arrays - 1)); - - // Allocate array of IV blocks - epm->iv_blocks = malloc(nr_arrays * sizeof(char *)); - if (!epm->iv_blocks) { - sflc_log_error("Could not malloc array of IV blocks"); - err = ENOMEM; - goto out; - } - // Allocate array of PosMapBlock arrays - epm->pmb_arrays = malloc(nr_arrays * sizeof(char *)); - if (!epm->pmb_arrays) { - sflc_log_error("Could not malloc array of PosMapBlock arrays"); - err = ENOMEM; - goto out; - } - - // Loop to allocate and encrypt each array - int i; - for (i = 0; i < nr_arrays; i++) { - // The last PMB array might be smaller - size_t nr_pmbs_here = ((i == nr_arrays - 1) ? epm->nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); - size_t pmb_array_size = SFLC_SECTOR_SIZE * nr_pmbs_here; - char *iv_block; - char *pmb_array; - - // Allocate IV block - epm->iv_blocks[i] = malloc(SFLC_SECTOR_SIZE); - if (!epm->iv_blocks[i]) { - sflc_log_error("Could not allocate IV block number %d", i); - err = ENOMEM; - goto out; - } - // Allocate PosMapBlock array - epm->pmb_arrays[i] = malloc(pmb_array_size); - if (!epm->pmb_arrays[i]) { - sflc_log_error("Could not allocate PMB array number %d", i); - err = ENOMEM; - goto out; - } - // Shorthand - iv_block = epm->iv_blocks[i]; - pmb_array = epm->pmb_arrays[i]; - - // Fill the IV block with random data (can ignore return value) - sflc_rand_getWeakBytes(iv_block, SFLC_SECTOR_SIZE); - // Fill the PMB array with 0xFF - memset(pmb_array, SFLC_EPM_FILLER, pmb_array_size); - - // Loop to encrypt each PMB separately with its IV - int j; - for (j = 0; j < nr_pmbs_here; j++) { - char *iv = iv_block + (j * SFLC_AESCTR_IVLEN); - char *pmb = pmb_array + (j * SFLC_SECTOR_SIZE); - - // Encrypt in-place - err = sflc_aes256ctr_encrypt(volume_key, pmb, SFLC_SECTOR_SIZE, iv, NULL); - if (err) { - sflc_log_error("Could not encrypt PMB %d of array %d", j, i); - goto out; - } - } - } - - -out: - return err; -} diff --git a/shufflecake-userland-legacy/src/header/volume_master_block.c b/shufflecake-userland-legacy/src/header/volume_master_block.c deleted file mode 100644 index 9347582..0000000 --- a/shufflecake-userland-legacy/src/header/volume_master_block.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include // Network byte order - -#include "header.h" -#include "utils/crypto.h" -#include "utils/string.h" -#include "utils/log.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Serialise the VMB before encrypting it */ -static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb); - -/* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb); - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Builds the on-disk master block (indistinguishable from random). - * - * @param vmb The useful information stored in this volume master block - * @param vmb_key The key encrypting the VMB - * @param disk_block The 4096-byte buffer that will contain the random-looking - * bytes to be written on-disk - * - * @return The error code, 0 on success - */ -int sflc_vmb_seal(sflc_Vmb *vmb, char *vmb_key, char *disk_block) -{ - // Pointers inside the block - char *iv = disk_block; - char *enc_vmb = iv + SFLC_AESCTR_IVLEN; - // Serialised VMB (dynamically allocated), to be encrypted - char *clear_vmb; - // Error code - int err; - - /* Allocate large buffer on the heap */ - clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); - if (!clear_vmb) { - sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); - err = ENOMEM; - goto bad_clear_alloc; - } - sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); - - /* Serialise the struct */ - _serialiseVmb(vmb, clear_vmb); - sflc_log_debug("Serialised VMB struct"); - - /* Sample VMB IV */ - err = sflc_rand_getWeakBytes(iv, SFLC_AESGCM_PADDED_IVLEN); - if (err) { - sflc_log_error("Could not sample VMB IV: error %d", err); - goto bad_sample_iv; - } - sflc_log_debug("Successfully sampled VMB IV"); - - /* Encrypt the VMB */ - err = sflc_aes256ctr_encrypt(vmb_key, clear_vmb, SFLC_CLEAR_VMB_LEN, iv, enc_vmb); - if (err) { - sflc_log_error("Could not encrypt VMB: error %d", err); - goto bad_encrypt; - } - sflc_log_debug("Successfully encrypted VMB"); - - // No prob - err = 0; - - -bad_encrypt: -bad_sample_iv: - /* Always wipe and free the cleartext VMB, even on success */ - memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); - free(clear_vmb); -bad_clear_alloc: - return err; -} - - -/** - * Decrypt the VMB payload using the VMB key. - * - * @param disk_block The content of the on-disk encrypted VMB - * @param vmb_key The proposed VMB key to unseal its payload - * @param vmb A pointer to the output struct that will contain all the VMB fields - * - * @return An error code, 0 on success - */ -int sflc_vmb_unseal(char *disk_block, char *vmb_key, sflc_Vmb *vmb) -{ - // Pointers inside the block - char *iv = disk_block; - char *enc_vmb = iv + SFLC_AESCTR_IVLEN; - // Decrypted VMB (dynamically allocated), to be deserialised - char *clear_vmb; - // Error code - int err; - - /* Allocate large buffer on the heap */ - clear_vmb = malloc(SFLC_CLEAR_VMB_LEN); - if (!clear_vmb) { - sflc_log_error("Could not allocate %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); - err = ENOMEM; - goto bad_clear_alloc; - } - sflc_log_debug("Successfully allocated %d bytes for VMB cleartext", SFLC_CLEAR_VMB_LEN); - - /* Decrypt the VMB */ - err = sflc_aes256ctr_decrypt(vmb_key, enc_vmb, SFLC_CLEAR_VMB_LEN, iv, clear_vmb); - if (err) { - sflc_log_error("Error while decrypting VMB: error %d", err); - goto bad_decrypt; - } - sflc_log_debug("Successfully decrypted VMB"); - - /* Deserialise the struct */ - err = _deserialiseVmb(clear_vmb, vmb); - if (err) { - sflc_log_error("Error while deserialising VMB: error %d", err); - goto bad_deserialise; - } - sflc_log_debug("Deserialised VMB struct"); - - // No prob - err = 0; - - -bad_deserialise: -bad_decrypt: - /* Always wipe and free the VMB cleartext, even on success */ - memset(clear_vmb, 0, SFLC_CLEAR_VMB_LEN); - free(clear_vmb); -bad_clear_alloc: - return err; -} - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Serialise the payload before encrypting it */ -static void _serialiseVmb(sflc_Vmb *vmb, char *clear_vmb) -{ - // Pointers inside the VMB - char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLC_CRYPTO_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLC_CRYPTO_KEYLEN; - - /* Copy the volume key */ - memcpy(p_vol_key, vmb->volume_key, SFLC_CRYPTO_KEYLEN); - - /* Copy the previous volume's VMB key */ - memcpy(p_prev_vmb_key, vmb->prev_vmb_key, SFLC_CRYPTO_KEYLEN); - - /* Write the number of slices (network byte order) */ - *((uint32_t *) p_nr_slices) = htonl(vmb->nr_slices); - - // Leave the rest uninitialised - - return; -} - - -/* Deserialise the VMB after decrypting it */ -static int _deserialiseVmb(char *clear_vmb, sflc_Vmb *vmb) -{ - // Pointers inside the VMB - char *p_vol_key = clear_vmb; - char *p_prev_vmb_key = p_vol_key + SFLC_CRYPTO_KEYLEN; - char *p_nr_slices = p_prev_vmb_key + SFLC_CRYPTO_KEYLEN; - - /* Copy the volume key */ - memcpy(vmb->volume_key, p_vol_key, SFLC_CRYPTO_KEYLEN); - - /* Copy the previous volume's VMB key */ - memcpy(vmb->prev_vmb_key, p_prev_vmb_key, SFLC_CRYPTO_KEYLEN); - - /* Read number of slices (network byte order) */ - vmb->nr_slices = ntohl( *((uint32_t *) p_nr_slices) ); - - // Ignore the rest - - return 0; -} - diff --git a/shufflecake-userland-legacy/src/operations/devmapper.c b/shufflecake-userland-legacy/src/operations/devmapper.c deleted file mode 100644 index a1bec5a..0000000 --- a/shufflecake-userland-legacy/src/operations/devmapper.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include - -#include "header.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/file.h" -#include "utils/string.h" -#include "utils/dm.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Build parameter list for ctor in dm_sflc, and send DM ioctl to create - * virtual block device. - * - * @param bdev_path The path to the underlying device - * @param dev_id The ID of the underlying block device - * @param vol_idx The index of the volume within the device - * @param vmb Volume metadata - * - * @return Error code, 0 on success - */ -int sflc_ops_openVolume(char *bdev_path, size_t dev_id, size_t vol_idx, sflc_Vmb *vmb) -{ - char label[SFLC_BIGBUFSIZE]; - char *hex_key; - char params[SFLC_BIGBUFSIZE]; - uint64_t num_sectors; - int err; - - /* Build volume label */ - sprintf(label, "sflc_%lu_%lu", dev_id, vol_idx); - - /* Get the hex version of the volume's data section key */ - hex_key = sflc_toHex(vmb->volume_key, SFLC_CRYPTO_KEYLEN); - if (!hex_key) { - sflc_log_error("Could not encode volume key to hexadecimal"); - err = ENOMEM; - goto err_hexkey; - } - - /* Get the number of logical 512-byte sectors composing the volume */ - num_sectors = ((uint64_t) vmb->nr_slices) * SFLC_BLOCKS_PER_LOG_SLICE * SFLC_SECTOR_SCALE; - - /* Build param list */ - sprintf(params, "%d %lu %s %lu %lu %s", SFLC_MODE_LEGACY, dev_id, bdev_path, vol_idx, vmb->nr_slices, hex_key); - - /* Issue ioctl */ - err = sflc_dm_create(label, num_sectors, params); - if (err) { - sflc_log_error("Could not issue ioctl CREATE command to device mapper; error %d", err); - goto err_dmcreate; - } - err = 0; - - -err_dmcreate: - free(hex_key); -err_hexkey: - return err; -} - - -/** - * Close the volume by issuing the appropriate ioctl to the DM. - * - * @param label The only needed parameter: the ID of the volume. - * - * @return Error code, 0 on success - */ -int sflc_ops_closeVolume(char *label) -{ - /* Issue ioctl */ - return sflc_dm_destroy(label); -} diff --git a/shufflecake-userland-legacy/src/operations/dmb.c b/shufflecake-userland-legacy/src/operations/dmb.c deleted file mode 100644 index d529966..0000000 --- a/shufflecake-userland-legacy/src/operations/dmb.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include - -#include "header.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/disk.h" -#include "utils/crypto.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Encrypts and writes the DMB to disk. - * - * @param bdev_path The path to the underlying block device - * @param pwds The array of passwords - * @param pwd_lens Their lengths - * @param dmb->nr_vols - * - * - * @return Error code, 0 on success - */ -int sflc_ops_writeDmb(char *bdev_path, char **pwds, size_t *pwd_lens, sflc_Dmb *dmb) -{ - /* On-disk DMB */ - char enc_dmb[SFLC_SECTOR_SIZE]; - /* Error code */ - int err; - - /* Sanity check */ - if (dmb->nr_vols > SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot create %lu volumes, too many!", dmb->nr_vols); - return EINVAL; - } - - /* Seal DMB */ - err = sflc_dmb_seal(dmb, pwds, pwd_lens, enc_dmb); - if (err) { - sflc_log_error("Coul dnot seal DMB; error %d", err); - return err; - } - - /* Write it to disk (at sector 0) */ - err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); - if (err) { - sflc_log_error("Could not write DMB to disk; error %d", err); - return err; - } - - return 0; -} - - -/** - * Reads the DMB from disk and outputs the unlocked VMB key. - * - * @param bdev_path The path to the underlying block device - * @param pwd The user-provided password - * @param pwd_len Its length - * - * @output dmb_cell->vmb_key The unlocked VMB key - * @output dmb_cell->vol_idx Its index (>= SFLC_DEV_MAX_VOLUMES if none could be unlocked) - * - * @return Error code, 0 on success - */ -int sflc_ops_readDmb(char *bdev_path, char *pwd, size_t pwd_len, sflc_DmbCell *dmb) -{ - char enc_dmb[SFLC_SECTOR_SIZE]; - int err; - - /* Read DMB from disk (at sector 0) */ - err = sflc_disk_readSector(bdev_path, 0, enc_dmb); - if (err) { - sflc_log_error("Could not read DMB from disk; error %d", err); - return err; - } - - /* Unseal it */ - err = sflc_dmb_unseal(enc_dmb, pwd, pwd_len, dmb); - if (err) { - sflc_log_error("Could not unseal DMB; error %d", err); - return err; - } - - return 0; -} - -/** - * Reads the DMB from disk, changes the relevant DMB cell, and writes it back. - * - * @param bdev_path The path to the underlying block device - * @param dmb_cell The index and vmb_key of the DMB cell to re-encrypt - * @param new_pwd The new password of the DMB cell to re-encrypt - * @param new_pwd_len Its length - * - * @return Error code, 0 on success - */ -int sflc_ops_rewriteDmbCell(char *bdev_path, sflc_DmbCell *dmb_cell, char *new_pwd, size_t new_pwd_len) -{ - char enc_dmb[SFLC_SECTOR_SIZE]; - int err; - - /* Sanity check */ - if (dmb_cell->vol_idx >= SFLC_DEV_MAX_VOLUMES) { - sflc_log_error("Cannot re-encrypt DMB cell %lu: out of bounds!", dmb_cell->vol_idx); - return EINVAL; - } - - /* Read DMB from disk (at sector 0) */ - err = sflc_disk_readSector(bdev_path, 0, enc_dmb); - if (err) { - sflc_log_error("Could not read DMB from disk; error %d", err); - return err; - } - - /* Update the relevant cell */ - err = sflc_dmb_setCell(enc_dmb, dmb_cell, new_pwd, new_pwd_len); - if (err) { - sflc_log_error("Could not update DMB cell; error %d", err); - return err; - } - - /* Write it to disk (at sector 0) */ - err = sflc_disk_writeSector(bdev_path, 0, enc_dmb); - if (err) { - sflc_log_error("Could not write DMB to disk; error %d", err); - return err; - } - - return 0; -} - - diff --git a/shufflecake-userland-legacy/src/operations/volume_header.c b/shufflecake-userland-legacy/src/operations/volume_header.c deleted file mode 100644 index 1088290..0000000 --- a/shufflecake-userland-legacy/src/operations/volume_header.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include - -#include "header.h" -#include "header.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/disk.h" -#include "utils/crypto.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Writes a volume header (VMB+PM) on-disk. - * - * @param bdev_path The underlying block device to write the volume header - * @param vmb_key The key to encrypt the VMB - * @param vmb The VMB to encrypt - * @param vol_idx The index of the volume within the device - * - * @return Error code, 0 on success - */ -int sflc_ops_writeVolumeHeader(char *bdev_path, char *vmb_key, sflc_Vmb *vmb, size_t vol_idx) -{ - char enc_vmb[SFLC_SECTOR_SIZE]; - sflc_EncPosMap epm; - uint64_t sector; - int err; - - // Encrypt VMB - err = sflc_vmb_seal(vmb, vmb_key, enc_vmb); - if (err) { - sflc_log_error("Could not seal VMB; error %d", err); - goto out; - } - - // Write it to disk - sector = sflc_vmbPosition(vol_idx, vmb->nr_slices); - err = sflc_disk_writeSector(bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not write VMB to disk; error %d", err); - goto out; - } - sector += 1; - - // Create encrypted empty position map - err = sflc_epm_create(vmb->nr_slices, vmb->volume_key, &epm); - if (err) { - sflc_log_error("Could not create encrypted empty position map; error %d", err); - goto out; - } - - // Loop over PMB arrays to write them to disk - int i; - for (i = 0; i < epm.nr_arrays; i++) { - char *iv_block = epm.iv_blocks[i]; - char *pmb_array = epm.pmb_arrays[i]; - size_t nr_pmbs = ((i == epm.nr_arrays-1) ? epm.nr_last_pmbs : SFLC_BLOCKS_PER_LOG_SLICE); - - // First write the IV block - err = sflc_disk_writeSector(bdev_path, sector, iv_block); - if (err) { - sflc_log_error("Could not write IV block to disk; error %d", err); - goto out; - } - sector += 1; - - // Then the whole PMB array - err = sflc_disk_writeManySectors(bdev_path, sector, pmb_array, nr_pmbs); - if (err) { - sflc_log_error("Could not write PMB array to disk; error %d", err); - goto out; - } - sector += nr_pmbs; - - // Free them both - free(iv_block); - free(pmb_array); - } - - // Free containers - free(epm.iv_blocks); - free(epm.pmb_arrays); - - -out: - return err; -} - - -/** - * Reads a VMB from disk and unlocks it - * - * @param bdev_path The underlying block device - * @param vmb_key The key to decrypt the VMB - * @param nr_slices The number of slices in the device - * @param vol_idx The index of the volume within the device - * - * @output vmb The decrypted VMB - * - * @return Error code, 0 on success - */ -int sflc_ops_readVmb(char *bdev_path, char *vmb_key, size_t nr_slices, size_t vol_idx, sflc_Vmb *vmb) -{ - char enc_vmb[SFLC_SECTOR_SIZE]; - uint64_t sector; - int err; - - /* Read encrypted VMB from disk */ - sector = sflc_vmbPosition(vol_idx, nr_slices); - err = sflc_disk_readSector(bdev_path, sector, enc_vmb); - if (err) { - sflc_log_error("Could not read VMB from disk; error %d", err); - return err; - } - - /* Unseal it */ - err = sflc_vmb_unseal(enc_vmb, vmb_key, vmb); - if (err) { - sflc_log_error("Could not unseal VMB; error %d", err); - return err; - } - - /* Compare the number of slices */ - if (nr_slices != vmb->nr_slices) { - sflc_log_error("Incompatible header size: the device size was different when the volumes" - "were created. Did you resize the device %s since last time?", bdev_path); - return EINVAL; - } - - return 0; -} diff --git a/shufflecake-userland-legacy/src/utils/crypto.c b/shufflecake-userland-legacy/src/utils/crypto.c deleted file mode 100644 index b42f50f..0000000 --- a/shufflecake-userland-legacy/src/utils/crypto.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - -#include "utils/crypto.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - *Fills the given buffer with strong random bytes, suitable for long-term - *cryptographic keys (uses the entropy pool). Always succeeds. - * - *@param buf The buffer to fill - *@param buflen The number of desired random bytes - * - *@return The error code (0 on success) - */ -int sflc_rand_getStrongBytes(char *buf, size_t buflen) -{ - gcry_randomize(buf, buflen, GCRY_VERY_STRONG_RANDOM); - return 0; -} - - -/** - *Faster than the previous one, fills the given buffer with weak random bytes, - *suitable for IVs or block filling (does not use the entropy pool). - *Always succeeds. - * - *@param buf The buffer to fill - *@param buflen The number of desired random bytes - * - *@return The error code (0 on success) - */ -int sflc_rand_getWeakBytes(char *buf, size_t buflen) -{ - gcry_create_nonce(buf, buflen); - return 0; -} - - -/** - *AES-CTR encryption, does not touch the IV. Set ct = NULL for in-place. - * - *@param key The 32-byte AES key - *@param pt The plaintext - *@param pt_len The length of the plaintext, must be a multiple of the AES - * block size (16 bytes) - *@param iv The 16-byte AES-CTR IV - *@param ct A caller-allocated buffer that will contain the output ciphertext, - * cannot overlap with pt. If NULL, in-place encryption. - * - *@return The error code (0 on success) - */ -int sflc_aes256ctr_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct) -{ - gcry_cipher_hd_t hd; - gcry_error_t err; - - // Instantiate the handle - err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); - if (err) { - sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); - goto bad_open; - } - sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); - - // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); - if (err) { - sflc_log_error("Could not set AES key: error %d", err); - goto bad_setkey; - } - sflc_log_debug("Successfully set the AES key"); - - // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); - if (err) { - sflc_log_error("Could not set AES-CTR IV: error %d", err); - goto bad_setctr; - } - sflc_log_debug("Successfully set the IV"); - - // Encrypt - if (ct == NULL) { // In-place - err = gcry_cipher_encrypt(hd, pt, pt_len, NULL, 0); - } - else { // Out-of-place - err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); - } - // Error check - if (err) { - sflc_log_error("Could not encrypt: error %d", err); - goto bad_encrypt; - } - sflc_log_debug("Successfully encrypted"); - - // No prob? - err = 0; - - -bad_encrypt: -bad_setctr: -bad_setkey: - gcry_cipher_close(hd); -bad_open: - return err; -} - -/** - *AES-CTR decryption, does not touch the IV. Set pt = NULL for in-place. - * - *@param key The 32-byte AES key - *@param ct The ciphertext - *@param ct_len The length of the ciphertext, must be a multiple of the AES - * block size (16 bytes) - *@param iv The 16-byte AES-CTR IV - *@param pt A caller-allocated buffer that will contain the output plaintext, - * cannot overlap with ct. If NULL, in-place decryption. - * - *@return The error code (0 on success) - */ -int sflc_aes256ctr_decrypt(char *key, char *ct, size_t ct_len, char *iv, char *pt) -{ - gcry_cipher_hd_t hd; - gcry_error_t err; - - // Instantiate the handle - err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE); - if (err) { - sflc_log_error("Could not instantiate AES256-CTR cipher handle: error %d", err); - goto bad_open; - } - sflc_log_debug("Successfully instantiated AES256-CTR cipher handle"); - - // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); - if (err) { - sflc_log_error("Could not set AES key: error %d", err); - goto bad_setkey; - } - sflc_log_debug("Successfully set AES key"); - - // Set the counter (not an IV, as per Gcrypt docs) - err = gcry_cipher_setctr(hd, iv, SFLC_AESCTR_IVLEN); - if (err) { - sflc_log_error("Could not set AES-CTR IV: error %d", err); - goto bad_setctr; - } - sflc_log_debug("Successfully set IV"); - - // Decrypt - if (pt == NULL) { // In-place - err = gcry_cipher_decrypt(hd, ct, ct_len, NULL, 0); - } - else { // Out-of-place - err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); - } - // Error check - if (err) { - sflc_log_error("Could not decrypt: error %d", err); - goto bad_decrypt; - } - sflc_log_debug("Successfully decrypted"); - - // No prob - err = 0; - - -bad_decrypt: -bad_setctr: -bad_setkey: - gcry_cipher_close(hd); -bad_open: - return err; -} - - -/** - *AES-GCM encryption, does not touch the IV. - * - *@param key The 32-byte AES key - *@param pt The plaintext - *@param pt_len The length of the plaintext, must be a multiple of the AES - * block size (16 bytes) - *@param iv The 12-byte AES-GCM IV - *@param ct A caller-allocated buffer that will contain the output ciphertext, - * cannot overlap with pt - *@param tag A caller-allocated buffer that will contain the 16-byte output MAC - * - *@return The error code (0 on success) - */ -int sflc_aes256gcm_encrypt(char *key, char *pt, size_t pt_len, char *iv, char *ct, char *tag) -{ - gcry_cipher_hd_t hd; - gcry_error_t err; - - // Instantiate the handle - err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); - if (err) { - sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); - goto bad_open; - } - sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); - - // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); - if (err) { - sflc_log_error("Could not set AES key: error %d", err); - goto bad_setkey; - } - sflc_log_debug("Successfully set the AES key"); - - // Set the IV - err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); - if (err) { - sflc_log_error("Could not set AES-GCM IV: error %d", err); - goto bad_setiv; - } - sflc_log_debug("Successfully set the IV"); - - // Encrypt - err = gcry_cipher_encrypt(hd, ct, pt_len, pt, pt_len); - if (err) { - sflc_log_error("Could not encrypt: error %d", err); - goto bad_encrypt; - } - sflc_log_debug("Successfully encrypted"); - - // Get MAC - err = gcry_cipher_gettag(hd, tag, SFLC_AESGCM_TAGLEN); - if (err) { - sflc_log_error("Could not get MAC: error %d", err); - goto bad_gettag; - } - sflc_log_debug("Successfully gotten MAC"); - - // No prob? - err = 0; - - -bad_gettag: -bad_encrypt: -bad_setiv: -bad_setkey: - gcry_cipher_close(hd); -bad_open: - return err; -} - - -/** - *AES-GCM decryption, does not touch the IV. - * - *@param key The 32-byte AES key - *@param ct The ciphertext - *@param ct_len The length of the ciphertext, must be a multiple of the AES - * block size (16 bytes) - *@param tag The 16-byte MAC - *@param iv The 12-byte AES-GCM IV - *@param pt A caller-allocated buffer that will contain the output plaintext, - * cannot overlap with ct - *@param match A pointer to a single output boolean, indicating MAC verification - * success or failure. On failure, pt is filled with poison bytes. - * - *@return The error code (0 on success) - */ -int sflc_aes256gcm_decrypt(char *key, char *ct, size_t ct_len, char *tag, char *iv, char *pt, bool *match) -{ - gcry_cipher_hd_t hd; - gcry_error_t err; - - // Instantiate the handle - err = gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE); - if (err) { - sflc_log_error("Could not instantiate AES256-GCM cipher handle: error %d", err); - goto bad_open; - } - sflc_log_debug("Successfully instantiated AES256-GCM cipher handle"); - - // Set the key - err = gcry_cipher_setkey(hd, key, SFLC_CRYPTO_KEYLEN); - if (err) { - sflc_log_error("Could not set AES key: error %d", err); - goto bad_setkey; - } - sflc_log_debug("Successfully set AES key"); - - // Set the IV - err = gcry_cipher_setiv(hd, iv, SFLC_AESGCM_IVLEN); - if (err) { - sflc_log_error("Could not set AES-GCM IV: error %d", err); - goto bad_setiv; - } - sflc_log_debug("Successfully set IV"); - - // Decrypt - err = gcry_cipher_decrypt(hd, pt, ct_len, ct, ct_len); - if (err) { - sflc_log_error("Could not decrypt: error %d", err); - goto bad_decrypt; - } - sflc_log_debug("Successfully decrypted"); - - // Check MAC - err = gcry_cipher_checktag(hd, tag, SFLC_AESGCM_TAGLEN); - if (gcry_err_code(err) == GPG_ERR_CHECKSUM) { - // Undo decryption - memset(pt, SFLC_AESGCM_POISON_PT, ct_len); - // Flag it - *match = false; - } - else if (err) { - sflc_log_error("Could not check MAC: error %d", err); - goto bad_checktag; - } - else { - // Flag MAC verification success - *match = true; - } - sflc_log_debug("Successfully checked MAC: match = %d", *match); - - // No prob, whether MAC verified or not - err = 0; - - -bad_checktag: -bad_decrypt: -bad_setiv: -bad_setkey: - gcry_cipher_close(hd); -bad_open: - return err; -} - - -/** - * Argon2id KDF. - * - * @param pwd The password - * @param pwd_len The length of the password - * @param salt The 16-byte KDF salt - * @param hash A caller-allocated 32-byte output buffer that will contain the - * password hash - * - * @return The error code (0 on success) - */ -int sflc_argon2id_derive(char *pwd, size_t pwd_len, char *salt, char *hash) -{ - gcry_kdf_hd_t hd; - const unsigned long argon_params[4] = - {SFLC_CRYPTO_KEYLEN, SFLC_ARGON_T, SFLC_ARGON_M, SFLC_ARGON_P}; - gcry_error_t err; - - // Instantiate Argon2id handle - err = gcry_kdf_open( - &hd, GCRY_KDF_ARGON2, GCRY_KDF_ARGON2ID, - argon_params, 4, - pwd, pwd_len, - salt, SFLC_ARGON_SALTLEN, - NULL, 0, /* Optional secret value K */ - NULL, 0 /* Optional associated data X */ - ); - if (err) { - sflc_log_error("Could not open Argon2id handle: error %d", err); - goto bad_open; - } - sflc_log_debug("Successfully opened Argon2id handle"); - - // Run the computation - err = gcry_kdf_compute(hd, NULL); - if (err) { - sflc_log_error("Could not run Argon2id computation: error %d", err); - goto bad_compute; - } - sflc_log_debug("Successfully run Argon2id computation"); - - // Finalise hash - err = gcry_kdf_final(hd, SFLC_CRYPTO_KEYLEN, hash); - if (err) { - sflc_log_error("Could not finalise Argon2id hash: error %d", err); - goto bad_final; - } - sflc_log_debug("Successfully finalised Argon2id hash"); - - // All in order - err = 0; - - -bad_final: -bad_compute: - gcry_kdf_close(hd); -bad_open: - return err; -} diff --git a/shufflecake-userland-legacy/src/utils/disk.c b/shufflecake-userland-legacy/src/utils/disk.c deleted file mode 100644 index c37711a..0000000 --- a/shufflecake-userland-legacy/src/utils/disk.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Disk helper functions - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils/disk.h" -#include "utils/log.h" - - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Returns a malloc'ed string formatted as : - * - * @param bdev_path The path to the block device - * - * @return A string version of the device ID - */ -char *sflc_disk_getDeviceName(char *bdev_path) -{ - struct stat sb; - char *dev_name; - - if (stat(bdev_path, &sb) != 0) - return NULL; - dev_name = malloc(SFLC_BIGBUFSIZE); - if (!dev_name) - return NULL; - - sprintf(dev_name, "%u:%u", major(sb.st_rdev), minor(sb.st_rdev)); - - return dev_name; -} - - -/** - * Checks whether the given path points to a block device. - * - * @param path The path to check - * - * @return true iff it's a block device - */ -bool sflc_disk_isBlockDevice(char *path) -{ - struct stat path_stat; - if (stat(path, &path_stat) != 0) { - return false; - } - return S_ISBLK(path_stat.st_mode); -} - -/** - * Returns the size in 4096-byte sectors (or < 0 if error). - * - * @param bdev_path The path of the block device - * - * @return The size (in 4096-byte sectors) of the disk, or -errno if error - */ -int64_t sflc_disk_getSize(char * bdev_path) -{ - int fd; - uint64_t size_bytes; - int64_t ret; - - /* Open file */ - fd = open(bdev_path, O_RDONLY); - if (fd < 0) { - sflc_log_error("Could not open file %s", bdev_path); - perror("Cause: "); - ret = -errno; - goto bad_open; - } - sflc_log_debug("Opened file %s", bdev_path); - - /* Get size in bytes */ - if (ioctl(fd, BLKGETSIZE64, &size_bytes) < 0) { - sflc_log_error("Could not ioctl file %s", bdev_path); - perror("Cause: "); - ret = -errno; - goto bad_ioctl; - } - sflc_log_debug("Size of %s is %lu bytes", bdev_path, size_bytes); - - /* Compute size in SFLC sectors */ - ret = (size_bytes / SFLC_SECTOR_SIZE); - -bad_ioctl: - close(fd); -bad_open: - return ret; -} - -/** - * Reads a single 4096-byte sector from the disk. - * - * @param bdev_path The path of the block device - * @param sector The index of the desired sector - * @param The caller-allocated buffer (must hold 4096 bytes) where the data - * from the disk will go - * - * @return The error code (0 on success) - */ -int sflc_disk_readSector(char * bdev_path, uint64_t sector, char * buf) -{ - int fd; - int err; - - /* Open file */ - fd = open(bdev_path, O_RDONLY); - if (fd < 0) { - sflc_log_error("Could not open file %s", bdev_path); - perror("Cause: "); - err = errno; - goto bad_open; - } - sflc_log_debug("Opened file %s", bdev_path); - - /* Set offset in bytes */ - if (lseek(fd, sector * SFLC_SECTOR_SIZE, SEEK_SET) < 0) { - sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); - perror("Cause: "); - err = errno; - goto bad_lseek; - } - sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); - - /* Read in a loop */ - size_t bytes_to_read = SFLC_SECTOR_SIZE; - while (bytes_to_read > 0) { - /* Read syscall */ - ssize_t bytes_read = read(fd, buf, bytes_to_read); - if (bytes_read < 0) { - sflc_log_error("Could not read file %s at sector %lu", bdev_path, sector); - perror("Cause: "); - err = errno; - goto bad_read; - } - - /* Partial read? No problem just log */ - if (bytes_read < bytes_to_read) { - sflc_log_debug("Partial read from file %s at sector %lu: %ld bytes instead of %ld", - bdev_path, sector, bytes_read, bytes_to_read); - } - - /* Advance loop */ - bytes_to_read -= bytes_read; - buf += bytes_read; - } - - // No prob - err = 0; - -bad_read: -bad_lseek: - close(fd); -bad_open: - return err; -} - - -/** - * Writes a single 4096-byte sector to the disk. - * - * @param bdev_path The path of the block device - * @param sector The index of the desired sector - * @param The caller-allocated buffer (must hold 4096 bytes) where the data - * comes from - * - * @return The error code (0 on success) - */ -int sflc_disk_writeSector(char * bdev_path, uint64_t sector, char * buf) -{ - return sflc_disk_writeManySectors(bdev_path, sector, buf, 1); -} - - -/** - * Writes many 4096-byte sectors to the disk. - * - * @param bdev_path The path of the block device - * @param sector The index of the starting sector - * @param The caller-allocated buffer where the data - * comes from - * @param num_sectors The number of sectors to write - * - * @return The error code (0 on success) - */ -int sflc_disk_writeManySectors(char * bdev_path, uint64_t sector, char * buf, size_t num_sectors) -{ - int fd; - int err; - - /* Open file */ - fd = open(bdev_path, O_WRONLY); - if (fd < 0) { - sflc_log_error("Could not open file %s", bdev_path); - perror("Cause: "); - err = errno; - goto bad_open; - } - sflc_log_debug("Opened file %s", bdev_path); - - /* Set offset in bytes */ - if (lseek(fd, sector * SFLC_SECTOR_SIZE, SEEK_SET) < 0) { - sflc_log_error("Could not lseek file %s to sector %lu", bdev_path, sector); - perror("Cause: "); - err = errno; - goto bad_lseek; - } - sflc_log_debug("Successful lseek on file %s to sector %lu", bdev_path, sector); - - /* Write in a loop */ - size_t bytes_to_write = SFLC_SECTOR_SIZE * num_sectors; - while (bytes_to_write > 0) { - /* Write syscall */ - ssize_t bytes_written = write(fd, buf, bytes_to_write); - if (bytes_written < 0) { - sflc_log_red("Could not write file %s at sector %lu", bdev_path, sector); - perror("Cause: "); - err = errno; - goto bad_write; - } - - /* Partial write? No problem just log */ - if (bytes_written < bytes_to_write) { - sflc_log_debug("Partial write to file %s at sector %lu: %ld bytes instead of %ld", - bdev_path, sector, bytes_written, bytes_to_write); - } - - /* Advance loop */ - bytes_to_write -= bytes_written; - buf += bytes_written; - } - - // No prob - err = 0; - -bad_write: -bad_lseek: - close(fd); -bad_open: - return err; -} diff --git a/shufflecake-userland-legacy/src/utils/dm.c b/shufflecake-userland-legacy/src/utils/dm.c deleted file mode 100644 index 6c2d054..0000000 --- a/shufflecake-userland-legacy/src/utils/dm.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - - -/** - * Interface to the device mapper. The only example I could find is the - * cryptsetup source, at - * https://kernel.googlesource.com/pub/scm/utils/cryptsetup/cryptsetup/+/v1_6_3/lib/libdevmapper.c - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - -#include "utils/dm.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Create a new Shufflecake virtual device (volume) under /dev/mapper. - * - * @param virt_dev_name The name of the new virtual device, as it will appear - * under /dev/mapper - * @param num_sectors The size of the virtual device, in 512-byte sectors - * @param params The string containing the space-separated paramters that will - * be passed to the Shufflecake constructor in the kernel module - * - * @return The error code (0 on success) - */ -int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params) -{ - struct dm_task *dmt; - uint32_t cookie = 0; - uint16_t udev_flags = 0; - int err; - - /* Just to be sure, let's get them on the heap */ - char * dup_virt_dev_name = strdup(virt_dev_name); - char * dup_params = strdup(params); - - sflc_log_debug("Creating /dev/mapper/%s", dup_virt_dev_name); - - /* Instantiate the DM task (with the CREATE ioctl command) */ - if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) { - sflc_log_error("Cannot create dm_task"); - err = 1; - goto dup_free; - } - sflc_log_debug("Successfully created dm_task"); - - /* Set the name of the target device (to be created) */ - if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - sflc_log_error("Cannot set device name"); - err = 2; - goto out; - } - sflc_log_debug("Successfully set device name"); - - /* State that it is a Shufflecake device, pass the start and size, and the - * constructor parameters */ - if (!dm_task_add_target(dmt, 0, num_sectors, SFLC_DM_TARGET_NAME, dup_params)) { - sflc_log_error("Cannot add DM target and parameters"); - err = 3; - goto out; - } - sflc_log_debug("Successfully added DM target and parameters"); - - /* Say that we want a new node under /dev/mapper */ - if (!dm_task_set_add_node(dmt, DM_ADD_NODE_ON_CREATE)) { - sflc_log_error("Cannot add /dev/mapper node"); - err = 4; - goto out; - } - sflc_log_debug("Successfully set the ADD_NODE flag"); - - /* Get a cookie (request ID, basically) to wait for task completion */ - if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - sflc_log_error("Cannot get cookie"); - err = 5; - goto out; - } - sflc_log_debug("Successfully got a cookie"); - - /* Run the task */ - if (!dm_task_run(dmt)) { - sflc_log_error("Cannot issue ioctl"); - err = 6; - goto out; - } - sflc_log_debug("Successfully run DM task"); - - /* Wait for completion */ - dm_udev_wait(cookie); - sflc_log_debug("Task completed"); - - // No prob - err = 0; - -out: - dm_task_destroy(dmt); -dup_free: - free(dup_virt_dev_name); - free(dup_params); - - return err; -} - -/** - * Close a Shufflecake virtual device (volume) under /dev/mapper. - * - * @param virt_dev_name the name of the virtual device, as it appears under - * /dev/mapper - * - * @return error code (0 on success) - */ -int sflc_dm_destroy(char * virt_dev_name) -{ - struct dm_task *dmt; - uint32_t cookie = 0; - uint16_t udev_flags = 0; - int err = 0; - - /* Just to be sure, let's get it on the heap */ - char * dup_virt_dev_name = strdup(virt_dev_name); - - sflc_log_debug("Closing /dev/mapper/%s", dup_virt_dev_name); - - /* Instantiate the DM task (with the REMOVE ioctl command) */ - if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) { - sflc_log_error("Cannot create dm_task"); - err = 1; - goto dup_free; - } - sflc_log_debug("Successfully created dm_task"); - - /* Set the name of the target device (to be closed) */ - if (!dm_task_set_name(dmt, dup_virt_dev_name)) { - sflc_log_error("Cannot set device name"); - err = 2; - goto out; - } - sflc_log_debug("Successfully set device name"); - - /* Get a cookie (request ID, basically) to wait for task completion */ - if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) { - sflc_log_error("Cannot set cookie"); - err = 3; - goto out; - } - sflc_log_debug("Successfully got a cookie"); - - /* Needed for some reason */ - dm_task_retry_remove(dmt); - sflc_log_debug("Successful retry_remove"); - - /* Run the task */ - if (!dm_task_run(dmt)) { - sflc_log_error("Cannot issue ioctl"); - err = 4; - goto out; - } - sflc_log_debug("Successfully run task"); - - /* Wait for completion */ - dm_udev_wait(cookie); - sflc_log_debug("Task completed"); - - // No prob - err = 0; - -out: - dm_task_destroy(dmt); -dup_free: - free(dup_virt_dev_name); - - return err; -} diff --git a/shufflecake-userland-legacy/test/crypto/test_aes256ctr.c b/shufflecake-userland-legacy/test/crypto/test_aes256ctr.c deleted file mode 100644 index 700a910..0000000 --- a/shufflecake-userland-legacy/test/crypto/test_aes256ctr.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "utils/crypto.h" -#include "test_aes256ctr.h" -#include "minunit.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANT VARIABLES * - *****************************************************/ - -static const char KEY[] = AES256CTR_TEST_KEY; -static const char IV[] = AES256CTR_TEST_IV; -static const char PT[] = AES256CTR_TEST_PT; -static const char CT[] = AES256CTR_TEST_CT; - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -char *test_aes256ctr_encrypt_inplace() -{ - char msg[] = AES256CTR_TEST_PT; - size_t msg_len = sizeof(msg); - char key[] = AES256CTR_TEST_KEY; - char iv[] = AES256CTR_TEST_IV; - int err; - - sflc_log_blue("Testing AES256-CTR encryption in-place"); - - // Encrypt in-place - err = sflc_aes256ctr_encrypt(key, msg, msg_len, iv, NULL); - - // Check error - mu_assert("Error while encrypting", !err); - - // Check outcome - mu_assert("Ciphertext mismatch", memcmp(msg, CT, msg_len) == 0); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - sflc_log_green("OK"); - - return NULL; -} - -char *test_aes256ctr_encrypt_outofplace() -{ - char msg[] = AES256CTR_TEST_PT; - char ct[sizeof(msg)]; - size_t msg_len = sizeof(msg); - char key[] = AES256CTR_TEST_KEY; - char iv[] = AES256CTR_TEST_IV; - int err; - - sflc_log_blue("Testing AES256-CTR encryption out-of-place"); - - // Encrypt out-of-place - err = sflc_aes256ctr_encrypt(key, msg, msg_len, iv, ct); - - // Check error - mu_assert("Error while encrypting", !err); - - // Check outcome - mu_assert("Ciphertext mismatch", memcmp(ct, CT, msg_len) == 0); - - // Check msg untouched - mu_assert("Plaintext changed", memcmp(msg, PT, sizeof(key)) == 0); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - sflc_log_green("OK"); - - return NULL; -} - -char *test_aes256ctr_decrypt_inplace() -{ - char msg[] = AES256CTR_TEST_CT; - size_t msg_len = sizeof(msg); - char key[] = AES256CTR_TEST_KEY; - char iv[] = AES256CTR_TEST_IV; - int err; - - sflc_log_blue("Testing AES256-CTR decryption in-place"); - - // Decrypt in-place - err = sflc_aes256ctr_decrypt(key, msg, msg_len, iv, NULL); - - // Check error - mu_assert("Error while decrypting", !err); - - // Check outcome - mu_assert("Plaintext mismatch", memcmp(msg, PT, msg_len) == 0); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - sflc_log_green("OK"); - - return NULL; -} - -char *test_aes256ctr_decrypt_outofplace() -{ - char msg[] = AES256CTR_TEST_CT; - char pt[sizeof(msg)]; - size_t msg_len = sizeof(msg); - char key[] = AES256CTR_TEST_KEY; - char iv[] = AES256CTR_TEST_IV; - int err; - - sflc_log_blue("Testing AES256-CTR decryption out-of-place"); - - // Decrypt out-of-place - err = sflc_aes256ctr_decrypt(key, msg, msg_len, iv, pt); - - // Check error - mu_assert("Error while decrypting", !err); - - // Check outcome - mu_assert("Plaintext mismatch", memcmp(pt, PT, msg_len) == 0); - - // Check msg untouched - mu_assert("Ciphertext changed", memcmp(msg, CT, sizeof(key)) == 0); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - sflc_log_green("OK"); - - return NULL; -} - diff --git a/shufflecake-userland-legacy/test/crypto/test_aes256gcm.c b/shufflecake-userland-legacy/test/crypto/test_aes256gcm.c deleted file mode 100644 index b332c51..0000000 --- a/shufflecake-userland-legacy/test/crypto/test_aes256gcm.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "utils/crypto.h" -#include "test_aes256gcm.h" -#include "minunit.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANT VARIABLES * - *****************************************************/ - -static const char KEY[] = AES256GCM_TEST_KEY; -static const char IV[] = AES256GCM_TEST_IV; -static const char PT[] = AES256GCM_TEST_PT; -static const char CT[] = AES256GCM_TEST_CT; -static const char TAG[] = AES256GCM_TEST_TAG; - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -char *test_aes256gcm_encrypt() -{ - char pt[] = AES256GCM_TEST_PT; - size_t pt_len = sizeof(pt); - char key[] = AES256GCM_TEST_KEY; - char iv[] = AES256GCM_TEST_IV; - char ct[sizeof(pt)]; - char tag[SFLC_AESGCM_TAGLEN]; - int err; - - sflc_log_blue("Testing AES256-GCM encryption"); - - // Encrypt - err = sflc_aes256gcm_encrypt(key, pt, pt_len, iv, ct, tag); - - // Check error - mu_assert("Error while encrypting", !err); - - // Check outcome - mu_assert("Ciphertext mismatch", memcmp(ct, CT, pt_len) == 0); - mu_assert("MAC mismatch", memcmp(tag, TAG, SFLC_AESGCM_TAGLEN) == 0); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - sflc_log_green("OK"); - - return NULL; -} - -char *test_aes256gcm_decrypt_good() -{ - char ct[] = AES256GCM_TEST_CT; - size_t ct_len = sizeof(ct); - char tag[] = AES256GCM_TEST_TAG; - char key[] = AES256GCM_TEST_KEY; - char iv[] = AES256GCM_TEST_IV; - bool match; - char pt[sizeof(ct)]; - int err; - - sflc_log_blue("Testing AES256-GCM decryption with the proper MAC"); - - // Decrypt - err = sflc_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); - - // Check error - mu_assert("Error while decrypting", !err); - - // Check outcome - mu_assert("MAC verification failed", match); - mu_assert("Plaintext mismatch", memcmp(pt, PT, ct_len) == 0); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - // Check MAC untouched - mu_assert("MAC changed", memcmp(tag, TAG, sizeof(tag)) == 0); - - sflc_log_green("OK"); - - return NULL; -} - -char *test_aes256gcm_decrypt_fail() -{ - char ct[] = AES256GCM_TEST_CT; - size_t ct_len = sizeof(ct); - char tag[] = AES256GCM_TEST_TAG; - char key[] = AES256GCM_TEST_KEY; - char iv[] = AES256GCM_TEST_IV; - bool match; - char pt[sizeof(ct)]; - int err; - - sflc_log_blue("Testing AES256-GCM decryption without the proper MAC"); - - // Corrupt the MAC - tag[0] += 1; - - // Decrypt - err = sflc_aes256gcm_decrypt(key, ct, ct_len, tag, iv, pt, &match); - - // Check error - mu_assert("Error while decrypting", !err); - - // Check outcome - mu_assert("MAC verification succeeded", !match); - - // Check key untouched - mu_assert("Key changed", memcmp(key, KEY, sizeof(key)) == 0); - - // Check IV untouched - mu_assert("IV changed", memcmp(iv, IV, sizeof(iv)) == 0); - - // Check MAC untouched - mu_assert("Tail of MAC changed", memcmp(tag+1, TAG+1, sizeof(tag)-1) == 0); - mu_assert("Head of MAC changed", tag[0] == TAG[0]+1); - - sflc_log_green("OK"); - - return NULL; -} diff --git a/shufflecake-userland-legacy/test/crypto/test_argon2id.c b/shufflecake-userland-legacy/test/crypto/test_argon2id.c deleted file mode 100644 index 0ded58b..0000000 --- a/shufflecake-userland-legacy/test/crypto/test_argon2id.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include - -#include "utils/crypto.h" -#include "test_argon2id.h" -#include "minunit.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * CONSTANT VARIABLES * - *****************************************************/ - -char SALT[SFLC_ARGON_SALTLEN+1] = "Poor Petrol Pump"; - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -char *test_argon2id() -{ - char pwd[SFLC_BIGBUFSIZE]; - char key[SFLC_CRYPTO_KEYLEN]; - int err; - - sflc_log_blue("Testing Argon2id interactively with a fixed salt"); - - // Loop until user breaks out - while (true) { - /* Collect password */ - printf("Choose password to hash (empty to skip): "); - err = sflc_safeReadLine(pwd, SFLC_BIGBUFSIZE); - mu_assert("Could not read password", !err); - - /* Check if empty */ - if (strlen(pwd) == 0) { - break; - } - - /* Hash it */ - err = sflc_argon2id_derive(pwd, strlen(pwd), SALT, key); - mu_assert("Could not hash password", !err); - - /* Print it */ - printf("Salt used ASCII: \"%s\". Hex:\n", SALT); - sflc_log_hex(SALT, SFLC_ARGON_SALTLEN); - printf("Argon2id hash (m = %d, t = %d, p = %d):\n", - SFLC_ARGON_M, SFLC_ARGON_T, SFLC_ARGON_P); - sflc_log_hex(key, SFLC_CRYPTO_KEYLEN); - printf("Go check the result online\n\n"); - } - - return NULL; -} diff --git a/shufflecake-userland-legacy/test/main.c b/shufflecake-userland-legacy/test/main.c deleted file mode 100644 index 565aa2c..0000000 --- a/shufflecake-userland-legacy/test/main.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - - -#include "crypto/test_aes256ctr.h" -#include "crypto/test_aes256gcm.h" -#include "crypto/test_argon2id.h" -#include "minunit.h" -#include "utils/log.h" - - -/***************************************************** - * PRIVATE FUNCTIONS PROTOTYPES * - *****************************************************/ - -static char *all_tests(); - - -/***************************************************** - * MAIN * - *****************************************************/ - -int main() -{ - char *result = all_tests(); - - if (result != NULL) { - sflc_log_red("\nTEST FAILED: %s", result); - } - else { - sflc_log_green("\nALL TESTS PASSED"); - } - - return result != NULL; -} - - -/***************************************************** - * PRIVATE FUNCTIONS DEFINITIONS * - *****************************************************/ - -static char *all_tests() -{ - sflc_log_yellow("Running crypto tests"); - mu_run_test(test_aes256ctr_encrypt_inplace); - mu_run_test(test_aes256ctr_encrypt_outofplace); - mu_run_test(test_aes256ctr_decrypt_inplace); - mu_run_test(test_aes256ctr_decrypt_outofplace); - mu_run_test(test_aes256gcm_encrypt); - mu_run_test(test_aes256gcm_decrypt_good); - mu_run_test(test_aes256gcm_decrypt_fail); - mu_run_test(test_argon2id); - - return 0; -} - diff --git a/shufflecake-userland-lite/.gitignore b/shufflecake-userland-lite/.gitignore deleted file mode 100644 index ca8a718..0000000 --- a/shufflecake-userland-lite/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -proj_build/ -test_build/ -.proj_deps/ -.test_deps/ -build/ -.cproject -.project -.settings/ -tests -shufflecake -disks/ diff --git a/shufflecake-userland-lite/include/utils/dm.h b/shufflecake-userland-lite/include/utils/dm.h deleted file mode 100644 index 3334852..0000000 --- a/shufflecake-userland-lite/include/utils/dm.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/* - * Interface to the device mapper - */ - -#ifndef _UTILS_DM_H_ -#define _UTILS_DM_H_ - - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include - -#include "utils/sflc.h" - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Create a new Shufflecake virtual device (volume) under /dev/mapper */ -int sflc_dm_create(char * virt_dev_name, uint64_t num_sectors, char * params); -/* Destroy the virtual device under /dev/mapper */ -int sflc_dm_destroy(char * virt_dev_name); - - -#endif /* _UTILS_DM_H_ */ diff --git a/shufflecake-userland-lite/include/utils/file.h b/shufflecake-userland-lite/include/utils/file.h deleted file mode 100644 index fb03078..0000000 --- a/shufflecake-userland-lite/include/utils/file.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _UTILS_FILE_H_ -#define _UTILS_FILE_H_ - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Malloc's the buffer for the file contents */ -char *sflc_readFile(char *path); - - -#endif /* _UTILS_FILE_H_ */ diff --git a/shufflecake-userland-lite/include/utils/math.h b/shufflecake-userland-lite/include/utils/math.h deleted file mode 100644 index db5e397..0000000 --- a/shufflecake-userland-lite/include/utils/math.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _UTILS_MATH_H_ -#define _UTILS_MATH_H_ - - -/***************************************************** - * MACROS * - *****************************************************/ - -// Function ceil(a/b) = floor((a+b-1)/b) -#define ceil(a, b) ( ((a)+(b)-1) / (b) ) - - -#endif /* _UTILS_MATH_H_ */ diff --git a/shufflecake-userland-lite/include/utils/string.h b/shufflecake-userland-lite/include/utils/string.h deleted file mode 100644 index ca42c0e..0000000 --- a/shufflecake-userland-lite/include/utils/string.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -#ifndef _UTILS_STRING_H_ -#define _UTILS_STRING_H_ - - -/***************************************************** - * PUBLIC FUNCTIONS PROTOTYPES * - *****************************************************/ - -/* Malloc's the buffer for the hex string */ -char *sflc_toHex(char *buf, size_t len); - -/* Replaces all occurrences of character in-place */ -void sflc_str_replaceAll(char *str, char old, char new); - - -#endif /* _UTILS_STRING_H_ */ diff --git a/shufflecake-userland-lite/src/cli/changepwd.c b/shufflecake-userland-lite/src/cli/changepwd.c deleted file mode 100644 index de37779..0000000 --- a/shufflecake-userland-lite/src/cli/changepwd.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "cli.h" -#include "commands.h" -#include "utils/sflc.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* - * Change volume password - * - * @return Error code, 0 on success - */ -int sflc_cli_changePwd(char *block_device) -{ // Requires: block_device is a correct block device path - sflc_cmd_OpenArgs open_args; - sflc_cmd_ChangePwdArgs change_pwd_args; - sflc_DmbCell dmb_cell; - char old_pwd[SFLC_BIGBUFSIZE]; - size_t old_pwd_len; - char new_pwd[SFLC_BIGBUFSIZE]; - size_t new_pwd_len; - int err; - - open_args.bdev_path = block_device; - - /* Gather password */ - printf("Enter the password you want to change: "); - err = sflc_safeReadPassphrase(old_pwd, SFLC_BIGBUFSIZE); - if (err) { - sflc_log_error("Could not read password; error %d", err); - return err; - } - /* You can trust the length of strings input this way */ - old_pwd_len = strlen(old_pwd); - /* Assign fields */ - open_args.pwd = old_pwd; - open_args.pwd_len = old_pwd_len; - - /* Test the password */ - err = sflc_cmd_testPwd(&open_args, &dmb_cell); - if (err) { - sflc_log_error("Could not test password; error %d", err); - return err; - } - - /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { - printf("This password does not unlock any volume.\n"); - return 0; - } - - /* Gather new password (no secure shell) */ - printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); - printf("Choose new password for volume %lu: ", dmb_cell.vol_idx); - err = sflc_safeReadLine(new_pwd, SFLC_BIGBUFSIZE); - if (err) { - sflc_log_error("Could not read new password; error %d", err); - return err; - } - /* You can trust the length of strings input this way */ - new_pwd_len = strlen(new_pwd); - - /* Assign fields */ - change_pwd_args.bdev_path = block_device; - change_pwd_args.dmb_cell = &dmb_cell; - change_pwd_args.new_pwd = new_pwd; - change_pwd_args.new_pwd_len = new_pwd_len; - - /* Change password */ - err = sflc_cmd_changePwd(&change_pwd_args); - if (err) { - sflc_log_error("Could not change password; error %d", err); - return err; - } - printf("Password changed successfully.\n"); - return err; -} diff --git a/shufflecake-userland-lite/src/cli/testpwd.c b/shufflecake-userland-lite/src/cli/testpwd.c deleted file mode 100644 index 550df25..0000000 --- a/shufflecake-userland-lite/src/cli/testpwd.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "cli.h" -#include "commands.h" -#include "utils/sflc.h" -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* - * Test volume password - * - * @return Error code, 0 on success - */ -int sflc_cli_testPwd(char *block_device) -{ // Requires: block_device is a correct block device path - sflc_cmd_OpenArgs args; - sflc_DmbCell dmb_cell; -// char bdev_path[SFLC_BDEV_PATH_MAX_LEN + 2]; - char pwd[SFLC_BIGBUFSIZE]; - size_t pwd_len; - int err; - - args.bdev_path = block_device; - - /* Gather password */ - printf("Enter the password you want to test: "); - err = sflc_safeReadPassphrase(pwd, SFLC_BIGBUFSIZE); - if (err) { - sflc_log_error("Could not read password; error %d", err); - return err; - } - /* You can trust the length of strings input this way */ - pwd_len = strlen(pwd); - /* Assign them */ - args.pwd = pwd; - args.pwd_len = pwd_len; - - /* Actually perform the command */ - err = sflc_cmd_testPwd(&args, &dmb_cell); - if (err) { - sflc_log_error("Could not test password; error %d", err); - return err; - } - - /* Does this password open any volumes? */ - if (dmb_cell.vol_idx >= SFLC_DEV_MAX_VOLUMES) { - printf("This password does not unlock any volume.\n"); - } else { - printf("This password opens volume number %lu .\n", dmb_cell.vol_idx); - } - - return 0; -} diff --git a/shufflecake-userland-lite/src/commands/test_pwd.c b/shufflecake-userland-lite/src/commands/test_pwd.c deleted file mode 100644 index f794347..0000000 --- a/shufflecake-userland-lite/src/commands/test_pwd.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "commands.h" -#include "operations.h" -#include "utils/sflc.h" -#include "utils/crypto.h" -#include "utils/file.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/** - * Tests which volume is unlocked by the given password - * - * @param args->bdev_path The underlying block device - * @param pwd The password - * @param pwd_len The password length - * - * @output dmb_cell The unlocked DMB cell - * - * @return Error code, 0 on success - */ -int sflc_cmd_testPwd(sflc_cmd_OpenArgs *args, sflc_DmbCell *dmb_cell) -{ - /* Delegate entirely to the function reading the DMB */ - return sflc_ops_readDmb(args->bdev_path, args->pwd, args->pwd_len, dmb_cell); -} diff --git a/shufflecake-userland-lite/src/main.c b/shufflecake-userland-lite/src/main.c deleted file mode 100644 index 737b57e..0000000 --- a/shufflecake-userland-lite/src/main.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - - -/* - * Shufflecake userland tool - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include "cli.h" - - -/***************************************************** - * MAIN * - *****************************************************/ - -int main(int argc, char **argv) -{ - return sflc_cli_dispatch(argc, argv); -} - diff --git a/shufflecake-userland-lite/src/utils/file.c b/shufflecake-userland-lite/src/utils/file.c deleted file mode 100644 index a8e70e2..0000000 --- a/shufflecake-userland-lite/src/utils/file.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "utils/file.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Reads the entire content of a file in a malloc-ed string */ -char *sflc_readFile(char *path) -{ - int filesize; - FILE *fp; - char *content; - - /* Open file */ - fp = fopen(path, "r"); - if (fp == NULL) { - sflc_log_error("Could not open file %s", path); - perror("Reason: "); - goto bad_fopen; - } - - /* Get size (overestimated) */ - fseek(fp, 0L, SEEK_END); - filesize = ftell(fp); - rewind(fp); - - /* Allocate */ - content = malloc(filesize + 1); - if (content == NULL) { - sflc_log_error("Could not malloc %d bytes for file content", filesize); - goto bad_malloc; - } - - /* Read (adjust filesize) */ - filesize = fread(content, 1, filesize, fp); - content[filesize] = '\0'; - - /* Close */ - fclose(fp); - - return content; - - -bad_malloc: - fclose(fp); -bad_fopen: - return NULL; -} diff --git a/shufflecake-userland-lite/src/utils/input.c b/shufflecake-userland-lite/src/utils/input.c deleted file mode 100644 index ffc0b02..0000000 --- a/shufflecake-userland-lite/src/utils/input.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "utils/input.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Reads a line (discarding the newline) from stdin. No buffer overflow */ -int sflc_safeReadLine(char *buf, size_t bufsize) -{ - size_t len; - - /* Read from stdin */ - if (fgets(buf, bufsize, stdin) == NULL) { - sflc_log_error("Could not read from stdin"); - return EBADFD; - } - - /* Discard newline */ - len = strlen(buf); - if (buf[len - 1] == '\n') { - buf[len - 1] = '\0'; - } - - return 0; -} - - -/* Reads a password/passphrase in a secure way (no echo) */ -int sflc_safeReadPassphrase(char *buf, size_t bufsize) -{ - size_t len; - struct termios old, new; - - fflush(stdout); // Ensure stdout is flushed is printed immediately - - // Turn off echoing - tcgetattr(STDIN_FILENO, &old); - new = old; - new.c_lflag &= ~ECHO; - tcsetattr(STDIN_FILENO, TCSAFLUSH, &new); - - /* Read from stdin */ - if (fgets(buf, bufsize, stdin) == NULL) { - // If reading the password failed, ensure echoing is turned back on - tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); - sflc_log_error("Could not read from stdin"); - return EBADFD; - } - - // Turn echoing back on - tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); - - /* Discard newline */ - len = strlen(buf); - if (buf[len - 1] == '\n') { - buf[len - 1] = '\0'; - } - - /* Newline on screen */ - printf("\n"); - - return 0; -} - - diff --git a/shufflecake-userland-lite/src/utils/string.c b/shufflecake-userland-lite/src/utils/string.c deleted file mode 100644 index c6cf998..0000000 --- a/shufflecake-userland-lite/src/utils/string.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -/***************************************************** - * INCLUDE SECTION * - *****************************************************/ - -#include -#include -#include - -#include "utils/string.h" -#include "utils/log.h" - - -/***************************************************** - * PUBLIC FUNCTIONS DEFINITIONS * - *****************************************************/ - -/* Malloc's the buffer for the hex string */ -char *sflc_toHex(char *buf, size_t len) -{ - unsigned char *u = (unsigned char *) buf; - char *hex; - - /* Allocate buffer */ - hex = malloc((len * 2) + 1); - if (!hex) { - sflc_log_error("Could not allocate buffer for hex string"); - return NULL; - } - - /* To hex */ - int i; - for(i = 0; i < len; i++) { - sprintf(hex + (i * 2), "%02x", u[i]); - } - hex[len*2] = '\0'; - - return hex; -} - - -void sflc_str_replaceAll(char * str, char old, char new) -{ - int i; - for (i = 0; str[i] != '\0'; i++) { - if (str[i] == old) { - str[i] = new; - } - } - - return; -} diff --git a/shufflecake-userland-lite/test/crypto/test_aes256ctr.h b/shufflecake-userland-lite/test/crypto/test_aes256ctr.h deleted file mode 100644 index c1070f8..0000000 --- a/shufflecake-userland-lite/test/crypto/test_aes256ctr.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -// Test vectors taken from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf - -#ifndef _TEST_CRYPTO_AES256CTR_H_ -#define _TEST_CRYPTO_AES256CTR_H_ - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define AES256CTR_TEST_KEY \ -{ \ - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, \ - 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, \ - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, \ - 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 \ -} - -#define AES256CTR_TEST_IV \ -{ \ - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, \ - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff \ -} - -#define AES256CTR_TEST_PT \ -{ \ - 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, \ - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, \ - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, \ - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, \ - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, \ - 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, \ - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, \ - 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 \ -} - -#define AES256CTR_TEST_CT \ -{ \ - 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, \ - 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, \ - 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, \ - 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, \ - 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, \ - 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, \ - 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, \ - 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6 \ -} - - -/***************************************************** - * PUBLIC FUNCTIONS DECLARATIONS * - *****************************************************/ - -// Exported test cases - -char *test_aes256ctr_encrypt_inplace(); -char *test_aes256ctr_encrypt_outofplace(); -char *test_aes256ctr_decrypt_inplace(); -char *test_aes256ctr_decrypt_outofplace(); - - -#endif /* _TEST_CRYPTO_AES256CTR_H_ */ diff --git a/shufflecake-userland-lite/test/crypto/test_aes256gcm.h b/shufflecake-userland-lite/test/crypto/test_aes256gcm.h deleted file mode 100644 index 9ad445b..0000000 --- a/shufflecake-userland-lite/test/crypto/test_aes256gcm.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - -// Test vectors taken from test case 15 at -// https://luca-giuzzi.unibs.it/corsi/Support/papers-cryptography/gcm-spec.pdf - -#ifndef _TEST_CRYPTO_AES256GCM_H_ -#define _TEST_CRYPTO_AES256GCM_H_ - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - -#define AES256GCM_TEST_KEY \ -{ \ - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, \ - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, \ - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, \ - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 \ -} - -#define AES256GCM_TEST_IV \ -{ \ - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, \ - 0xde, 0xca, 0xf8, 0x88 \ -} - -#define AES256GCM_TEST_PT \ -{ \ - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, \ - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, \ - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, \ - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, \ - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, \ - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, \ - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, \ - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 \ -} - -#define AES256GCM_TEST_CT \ -{ \ - 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, \ - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, \ - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, \ - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, \ - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, \ - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, \ - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, \ - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad, \ -} - -#define AES256GCM_TEST_TAG \ -{ \ - 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, \ - 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c, \ -} - - -/***************************************************** - * PUBLIC FUNCTIONS DECLARATIONS * - *****************************************************/ - -// Exported test cases - -char *test_aes256gcm_encrypt(); -char *test_aes256gcm_decrypt_good(); -char *test_aes256gcm_decrypt_fail(); - - -#endif /* _TEST_CRYPTO_AES256GCM_H_ */ diff --git a/shufflecake-userland-lite/test/crypto/test_argon2id.h b/shufflecake-userland-lite/test/crypto/test_argon2id.h deleted file mode 100644 index 12bd2c0..0000000 --- a/shufflecake-userland-lite/test/crypto/test_argon2id.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The Shufflecake Project Authors (2022) - * Copyright The Shufflecake Project Contributors (2022) - * Copyright Contributors to the The Shufflecake Project. - * - * See the AUTHORS file at the top-level directory of this distribution and at - * - * - * This file is part of the program shufflecake-c, which is part of the - * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) - * layer for Linux. See . - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 2 of the License, or (at your option) - * any later version. 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, see . - */ - - -#ifndef _TEST_CRYPTO_ARGON2ID_H_ -#define _TEST_CRYPTO_ARGON2ID_H_ - - -/***************************************************** - * CONSTANTS * - *****************************************************/ - - -/***************************************************** - * PUBLIC FUNCTIONS DECLARATIONS * - *****************************************************/ - -// Exported test cases - -char *test_argon2id(); - - -#endif /* _TEST_CRYPTO_ARGON2ID_H_ */ diff --git a/shufflecake-userland-lite/test/minunit.h b/shufflecake-userland-lite/test/minunit.h deleted file mode 100644 index 4181aa1..0000000 --- a/shufflecake-userland-lite/test/minunit.h +++ /dev/null @@ -1,10 +0,0 @@ -// MinUnit -- a minimal unit testing framework for C. Slightly modified. -// https://jera.com/techinfo/jtns/jtn002 - -#ifndef _MINUNIT_H_ -#define _MINUNIT_H_ - -#define mu_assert(message, test) do { if (!(test)) return message; } while (0) -#define mu_run_test(test) do { char *message = test(); if (message) return message; } while (0) - -#endif // _MINUNIT_H_ diff --git a/shufflecake-userland-legacy/.gitignore b/shufflecake-userland/.gitignore similarity index 100% rename from shufflecake-userland-legacy/.gitignore rename to shufflecake-userland/.gitignore diff --git a/shufflecake-userland-lite/Makefile b/shufflecake-userland/Makefile similarity index 100% rename from shufflecake-userland-lite/Makefile rename to shufflecake-userland/Makefile diff --git a/shufflecake-userland-lite/Makefile.sources b/shufflecake-userland/Makefile.sources similarity index 100% rename from shufflecake-userland-lite/Makefile.sources rename to shufflecake-userland/Makefile.sources diff --git a/shufflecake-userland-lite/include/cli.h b/shufflecake-userland/include/cli.h similarity index 100% rename from shufflecake-userland-lite/include/cli.h rename to shufflecake-userland/include/cli.h diff --git a/shufflecake-userland-lite/include/commands.h b/shufflecake-userland/include/commands.h similarity index 100% rename from shufflecake-userland-lite/include/commands.h rename to shufflecake-userland/include/commands.h diff --git a/shufflecake-userland-lite/include/header.h b/shufflecake-userland/include/header.h similarity index 100% rename from shufflecake-userland-lite/include/header.h rename to shufflecake-userland/include/header.h diff --git a/shufflecake-userland-lite/include/operations.h b/shufflecake-userland/include/operations.h similarity index 100% rename from shufflecake-userland-lite/include/operations.h rename to shufflecake-userland/include/operations.h diff --git a/shufflecake-userland-lite/include/utils/crypto.h b/shufflecake-userland/include/utils/crypto.h similarity index 100% rename from shufflecake-userland-lite/include/utils/crypto.h rename to shufflecake-userland/include/utils/crypto.h diff --git a/shufflecake-userland-lite/include/utils/disk.h b/shufflecake-userland/include/utils/disk.h similarity index 100% rename from shufflecake-userland-lite/include/utils/disk.h rename to shufflecake-userland/include/utils/disk.h diff --git a/shufflecake-userland-legacy/include/utils/dm.h b/shufflecake-userland/include/utils/dm.h similarity index 100% rename from shufflecake-userland-legacy/include/utils/dm.h rename to shufflecake-userland/include/utils/dm.h diff --git a/shufflecake-userland-legacy/include/utils/file.h b/shufflecake-userland/include/utils/file.h similarity index 100% rename from shufflecake-userland-legacy/include/utils/file.h rename to shufflecake-userland/include/utils/file.h diff --git a/shufflecake-userland-lite/include/utils/input.h b/shufflecake-userland/include/utils/input.h similarity index 100% rename from shufflecake-userland-lite/include/utils/input.h rename to shufflecake-userland/include/utils/input.h diff --git a/shufflecake-userland-lite/include/utils/log.h b/shufflecake-userland/include/utils/log.h similarity index 100% rename from shufflecake-userland-lite/include/utils/log.h rename to shufflecake-userland/include/utils/log.h diff --git a/shufflecake-userland-legacy/include/utils/math.h b/shufflecake-userland/include/utils/math.h similarity index 100% rename from shufflecake-userland-legacy/include/utils/math.h rename to shufflecake-userland/include/utils/math.h diff --git a/shufflecake-userland-lite/include/utils/sflc.h b/shufflecake-userland/include/utils/sflc.h similarity index 100% rename from shufflecake-userland-lite/include/utils/sflc.h rename to shufflecake-userland/include/utils/sflc.h diff --git a/shufflecake-userland-legacy/include/utils/string.h b/shufflecake-userland/include/utils/string.h similarity index 100% rename from shufflecake-userland-legacy/include/utils/string.h rename to shufflecake-userland/include/utils/string.h diff --git a/shufflecake-userland-legacy/src/cli/changepwd.c b/shufflecake-userland/src/cli/changepwd.c similarity index 100% rename from shufflecake-userland-legacy/src/cli/changepwd.c rename to shufflecake-userland/src/cli/changepwd.c diff --git a/shufflecake-userland-lite/src/cli/close.c b/shufflecake-userland/src/cli/close.c similarity index 100% rename from shufflecake-userland-lite/src/cli/close.c rename to shufflecake-userland/src/cli/close.c diff --git a/shufflecake-userland-lite/src/cli/dispatch.c b/shufflecake-userland/src/cli/dispatch.c similarity index 100% rename from shufflecake-userland-lite/src/cli/dispatch.c rename to shufflecake-userland/src/cli/dispatch.c diff --git a/shufflecake-userland-lite/src/cli/init.c b/shufflecake-userland/src/cli/init.c similarity index 100% rename from shufflecake-userland-lite/src/cli/init.c rename to shufflecake-userland/src/cli/init.c diff --git a/shufflecake-userland-lite/src/cli/open.c b/shufflecake-userland/src/cli/open.c similarity index 100% rename from shufflecake-userland-lite/src/cli/open.c rename to shufflecake-userland/src/cli/open.c diff --git a/shufflecake-userland-legacy/src/cli/testpwd.c b/shufflecake-userland/src/cli/testpwd.c similarity index 100% rename from shufflecake-userland-legacy/src/cli/testpwd.c rename to shufflecake-userland/src/cli/testpwd.c diff --git a/shufflecake-userland-lite/src/commands/change_pwd.c b/shufflecake-userland/src/commands/change_pwd.c similarity index 100% rename from shufflecake-userland-lite/src/commands/change_pwd.c rename to shufflecake-userland/src/commands/change_pwd.c diff --git a/shufflecake-userland-lite/src/commands/close.c b/shufflecake-userland/src/commands/close.c similarity index 100% rename from shufflecake-userland-lite/src/commands/close.c rename to shufflecake-userland/src/commands/close.c diff --git a/shufflecake-userland-lite/src/commands/init_legacy.c b/shufflecake-userland/src/commands/init_legacy.c similarity index 100% rename from shufflecake-userland-lite/src/commands/init_legacy.c rename to shufflecake-userland/src/commands/init_legacy.c diff --git a/shufflecake-userland-lite/src/commands/init_lite.c b/shufflecake-userland/src/commands/init_lite.c similarity index 100% rename from shufflecake-userland-lite/src/commands/init_lite.c rename to shufflecake-userland/src/commands/init_lite.c diff --git a/shufflecake-userland-lite/src/commands/open_legacy.c b/shufflecake-userland/src/commands/open_legacy.c similarity index 100% rename from shufflecake-userland-lite/src/commands/open_legacy.c rename to shufflecake-userland/src/commands/open_legacy.c diff --git a/shufflecake-userland-lite/src/commands/open_lite.c b/shufflecake-userland/src/commands/open_lite.c similarity index 100% rename from shufflecake-userland-lite/src/commands/open_lite.c rename to shufflecake-userland/src/commands/open_lite.c diff --git a/shufflecake-userland-legacy/src/commands/test_pwd.c b/shufflecake-userland/src/commands/test_pwd.c similarity index 100% rename from shufflecake-userland-legacy/src/commands/test_pwd.c rename to shufflecake-userland/src/commands/test_pwd.c diff --git a/shufflecake-userland-lite/src/header/device_master_block.c b/shufflecake-userland/src/header/device_master_block.c similarity index 100% rename from shufflecake-userland-lite/src/header/device_master_block.c rename to shufflecake-userland/src/header/device_master_block.c diff --git a/shufflecake-userland-lite/src/header/position_map_legacy.c b/shufflecake-userland/src/header/position_map_legacy.c similarity index 100% rename from shufflecake-userland-lite/src/header/position_map_legacy.c rename to shufflecake-userland/src/header/position_map_legacy.c diff --git a/shufflecake-userland-lite/src/header/position_map_lite.c b/shufflecake-userland/src/header/position_map_lite.c similarity index 100% rename from shufflecake-userland-lite/src/header/position_map_lite.c rename to shufflecake-userland/src/header/position_map_lite.c diff --git a/shufflecake-userland-lite/src/header/volume_master_block_legacy.c b/shufflecake-userland/src/header/volume_master_block_legacy.c similarity index 100% rename from shufflecake-userland-lite/src/header/volume_master_block_legacy.c rename to shufflecake-userland/src/header/volume_master_block_legacy.c diff --git a/shufflecake-userland-lite/src/header/volume_master_block_lite.c b/shufflecake-userland/src/header/volume_master_block_lite.c similarity index 100% rename from shufflecake-userland-lite/src/header/volume_master_block_lite.c rename to shufflecake-userland/src/header/volume_master_block_lite.c diff --git a/shufflecake-userland-legacy/src/main.c b/shufflecake-userland/src/main.c similarity index 100% rename from shufflecake-userland-legacy/src/main.c rename to shufflecake-userland/src/main.c diff --git a/shufflecake-userland-lite/src/operations/devmapper_legacy.c b/shufflecake-userland/src/operations/devmapper_legacy.c similarity index 100% rename from shufflecake-userland-lite/src/operations/devmapper_legacy.c rename to shufflecake-userland/src/operations/devmapper_legacy.c diff --git a/shufflecake-userland-lite/src/operations/devmapper_lite.c b/shufflecake-userland/src/operations/devmapper_lite.c similarity index 100% rename from shufflecake-userland-lite/src/operations/devmapper_lite.c rename to shufflecake-userland/src/operations/devmapper_lite.c diff --git a/shufflecake-userland-lite/src/operations/dmb.c b/shufflecake-userland/src/operations/dmb.c similarity index 100% rename from shufflecake-userland-lite/src/operations/dmb.c rename to shufflecake-userland/src/operations/dmb.c diff --git a/shufflecake-userland-lite/src/operations/volume_header_legacy.c b/shufflecake-userland/src/operations/volume_header_legacy.c similarity index 100% rename from shufflecake-userland-lite/src/operations/volume_header_legacy.c rename to shufflecake-userland/src/operations/volume_header_legacy.c diff --git a/shufflecake-userland-lite/src/operations/volume_header_lite.c b/shufflecake-userland/src/operations/volume_header_lite.c similarity index 100% rename from shufflecake-userland-lite/src/operations/volume_header_lite.c rename to shufflecake-userland/src/operations/volume_header_lite.c diff --git a/shufflecake-userland-lite/src/utils/crypto.c b/shufflecake-userland/src/utils/crypto.c similarity index 100% rename from shufflecake-userland-lite/src/utils/crypto.c rename to shufflecake-userland/src/utils/crypto.c diff --git a/shufflecake-userland-lite/src/utils/disk.c b/shufflecake-userland/src/utils/disk.c similarity index 100% rename from shufflecake-userland-lite/src/utils/disk.c rename to shufflecake-userland/src/utils/disk.c diff --git a/shufflecake-userland-lite/src/utils/dm.c b/shufflecake-userland/src/utils/dm.c similarity index 100% rename from shufflecake-userland-lite/src/utils/dm.c rename to shufflecake-userland/src/utils/dm.c diff --git a/shufflecake-userland-legacy/src/utils/file.c b/shufflecake-userland/src/utils/file.c similarity index 100% rename from shufflecake-userland-legacy/src/utils/file.c rename to shufflecake-userland/src/utils/file.c diff --git a/shufflecake-userland-legacy/src/utils/input.c b/shufflecake-userland/src/utils/input.c similarity index 100% rename from shufflecake-userland-legacy/src/utils/input.c rename to shufflecake-userland/src/utils/input.c diff --git a/shufflecake-userland-legacy/src/utils/string.c b/shufflecake-userland/src/utils/string.c similarity index 100% rename from shufflecake-userland-legacy/src/utils/string.c rename to shufflecake-userland/src/utils/string.c diff --git a/shufflecake-userland-lite/test/crypto/test_aes256ctr.c b/shufflecake-userland/test/crypto/test_aes256ctr.c similarity index 100% rename from shufflecake-userland-lite/test/crypto/test_aes256ctr.c rename to shufflecake-userland/test/crypto/test_aes256ctr.c diff --git a/shufflecake-userland-legacy/test/crypto/test_aes256ctr.h b/shufflecake-userland/test/crypto/test_aes256ctr.h similarity index 100% rename from shufflecake-userland-legacy/test/crypto/test_aes256ctr.h rename to shufflecake-userland/test/crypto/test_aes256ctr.h diff --git a/shufflecake-userland-lite/test/crypto/test_aes256gcm.c b/shufflecake-userland/test/crypto/test_aes256gcm.c similarity index 100% rename from shufflecake-userland-lite/test/crypto/test_aes256gcm.c rename to shufflecake-userland/test/crypto/test_aes256gcm.c diff --git a/shufflecake-userland-legacy/test/crypto/test_aes256gcm.h b/shufflecake-userland/test/crypto/test_aes256gcm.h similarity index 100% rename from shufflecake-userland-legacy/test/crypto/test_aes256gcm.h rename to shufflecake-userland/test/crypto/test_aes256gcm.h diff --git a/shufflecake-userland-lite/test/crypto/test_argon2id.c b/shufflecake-userland/test/crypto/test_argon2id.c similarity index 100% rename from shufflecake-userland-lite/test/crypto/test_argon2id.c rename to shufflecake-userland/test/crypto/test_argon2id.c diff --git a/shufflecake-userland-legacy/test/crypto/test_argon2id.h b/shufflecake-userland/test/crypto/test_argon2id.h similarity index 100% rename from shufflecake-userland-legacy/test/crypto/test_argon2id.h rename to shufflecake-userland/test/crypto/test_argon2id.h diff --git a/shufflecake-userland-lite/test/main.c b/shufflecake-userland/test/main.c similarity index 100% rename from shufflecake-userland-lite/test/main.c rename to shufflecake-userland/test/main.c diff --git a/shufflecake-userland-legacy/test/minunit.h b/shufflecake-userland/test/minunit.h similarity index 100% rename from shufflecake-userland-legacy/test/minunit.h rename to shufflecake-userland/test/minunit.h From f0e48edb8da28047cb6dea6f9ec264290faab278 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 27 Aug 2024 20:14:32 +0200 Subject: [PATCH 69/75] fix Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 6d3666a..4c88d2f 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ default: make -C dm-sflc - cp dm-sflc/bin/dm-sflc.ko ./dm-sflc.ko + cp dm-sflc/bin/dm_sflc.ko ./dm_sflc.ko make -C shufflecake-userland cp shufflecake-userland/bin/proj_build/shufflecake ./shufflecake @@ -48,7 +48,7 @@ clean: make -C dm-sflc clean make -C shufflecake-userland clean rm ./shufflecake - rm ./dm-sflc.ko + rm ./dm_sflc.ko From d84ebfaebc75e9dae05076632df1386cae8e418e Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Aug 2024 20:02:24 +0200 Subject: [PATCH 70/75] Temporary build solution --- dm-sflc/.Kbuild | 53 +++++++++++++++++++ dm-sflc/.gitignore | 6 ++- dm-sflc/Makefile | 28 +++++----- dm-sflc/{ => bin}/Kbuild | 1 + dm-sflc/bin/dev_vol.c | 1 + dm-sflc/bin/lite/crypto.c | 1 + dm-sflc/bin/lite/device.c | 1 + dm-sflc/bin/lite/posmap.c | 1 + dm-sflc/bin/lite/read.c | 1 + dm-sflc/bin/lite/sflc_lite.c | 1 + dm-sflc/bin/lite/sflc_lite.h | 1 + dm-sflc/bin/lite/sflite_constants.h | 1 + dm-sflc/bin/lite/sysfs.c | 1 + dm-sflc/bin/lite/volume.c | 1 + dm-sflc/bin/lite/write.c | 1 + dm-sflc/bin/old/crypto/rand/rand.c | 1 + dm-sflc/bin/old/crypto/rand/rand.h | 1 + dm-sflc/bin/old/crypto/symkey/skreq_pool.c | 1 + dm-sflc/bin/old/crypto/symkey/skreq_pool.h | 1 + dm-sflc/bin/old/crypto/symkey/symkey.c | 1 + dm-sflc/bin/old/crypto/symkey/symkey.h | 1 + dm-sflc/bin/old/device/device.c | 1 + dm-sflc/bin/old/device/device.h | 1 + dm-sflc/bin/old/device/iv.c | 1 + dm-sflc/bin/old/device/rawio.c | 1 + dm-sflc/bin/old/device/rmap.c | 1 + dm-sflc/bin/old/device/volumes.c | 1 + dm-sflc/bin/old/log/log.h | 1 + dm-sflc/bin/old/sflc_old.c | 1 + dm-sflc/bin/old/sflc_old.h | 1 + dm-sflc/bin/old/sysfs.c | 1 + dm-sflc/bin/old/target.c | 1 + dm-sflc/bin/old/utils/bio.c | 1 + dm-sflc/bin/old/utils/bio.h | 1 + dm-sflc/bin/old/utils/pools.c | 1 + dm-sflc/bin/old/utils/pools.h | 1 + dm-sflc/bin/old/utils/string.c | 1 + dm-sflc/bin/old/utils/string.h | 1 + dm-sflc/bin/old/utils/vector.c | 1 + dm-sflc/bin/old/utils/vector.h | 1 + dm-sflc/bin/old/utils/workqueues.c | 1 + dm-sflc/bin/old/utils/workqueues.h | 1 + dm-sflc/bin/old/volume/fmap.c | 1 + dm-sflc/bin/old/volume/io.c | 1 + dm-sflc/bin/old/volume/read.c | 1 + dm-sflc/bin/old/volume/volume.c | 1 + dm-sflc/bin/old/volume/volume.h | 1 + dm-sflc/bin/old/volume/write.c | 1 + dm-sflc/bin/sflc.c | 1 + dm-sflc/bin/sflc.h | 1 + dm-sflc/bin/sflc_constants.h | 1 + dm-sflc/bin/sysfs.c | 1 + dm-sflc/{ => src}/dev_vol.c | 0 dm-sflc/{ => src}/lite/crypto.c | 0 dm-sflc/{ => src}/lite/device.c | 0 dm-sflc/{ => src}/lite/posmap.c | 0 dm-sflc/{ => src}/lite/read.c | 0 dm-sflc/{ => src}/lite/sflc_lite.c | 0 dm-sflc/{ => src}/lite/sflc_lite.h | 0 dm-sflc/{ => src}/lite/sflite_constants.h | 0 dm-sflc/{ => src}/lite/sysfs.c | 0 dm-sflc/{ => src}/lite/volume.c | 0 dm-sflc/{ => src}/lite/write.c | 0 dm-sflc/{ => src}/old/crypto/rand/rand.c | 0 dm-sflc/{ => src}/old/crypto/rand/rand.h | 0 .../{ => src}/old/crypto/symkey/skreq_pool.c | 0 .../{ => src}/old/crypto/symkey/skreq_pool.h | 0 dm-sflc/{ => src}/old/crypto/symkey/symkey.c | 0 dm-sflc/{ => src}/old/crypto/symkey/symkey.h | 0 dm-sflc/{ => src}/old/device/device.c | 0 dm-sflc/{ => src}/old/device/device.h | 0 dm-sflc/{ => src}/old/device/iv.c | 0 dm-sflc/{ => src}/old/device/rawio.c | 0 dm-sflc/{ => src}/old/device/rmap.c | 0 dm-sflc/{ => src}/old/device/volumes.c | 0 dm-sflc/{ => src}/old/log/log.h | 0 dm-sflc/{ => src}/old/sflc_old.c | 0 dm-sflc/{ => src}/old/sflc_old.h | 0 dm-sflc/{ => src}/old/sysfs.c | 0 dm-sflc/{ => src}/old/target.c | 0 dm-sflc/{ => src}/old/utils/bio.c | 0 dm-sflc/{ => src}/old/utils/bio.h | 0 dm-sflc/{ => src}/old/utils/pools.c | 0 dm-sflc/{ => src}/old/utils/pools.h | 0 dm-sflc/{ => src}/old/utils/string.c | 0 dm-sflc/{ => src}/old/utils/string.h | 0 dm-sflc/{ => src}/old/utils/vector.c | 0 dm-sflc/{ => src}/old/utils/vector.h | 0 dm-sflc/{ => src}/old/utils/workqueues.c | 0 dm-sflc/{ => src}/old/utils/workqueues.h | 0 dm-sflc/{ => src}/old/volume/fmap.c | 0 dm-sflc/{ => src}/old/volume/io.c | 0 dm-sflc/{ => src}/old/volume/read.c | 0 dm-sflc/{ => src}/old/volume/volume.c | 0 dm-sflc/{ => src}/old/volume/volume.h | 0 dm-sflc/{ => src}/old/volume/write.c | 0 dm-sflc/{ => src}/sflc.c | 0 dm-sflc/{ => src}/sflc.h | 0 dm-sflc/{ => src}/sflc_constants.h | 0 dm-sflc/{ => src}/sysfs.c | 0 100 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 dm-sflc/.Kbuild rename dm-sflc/{ => bin}/Kbuild (99%) create mode 120000 dm-sflc/bin/dev_vol.c create mode 120000 dm-sflc/bin/lite/crypto.c create mode 120000 dm-sflc/bin/lite/device.c create mode 120000 dm-sflc/bin/lite/posmap.c create mode 120000 dm-sflc/bin/lite/read.c create mode 120000 dm-sflc/bin/lite/sflc_lite.c create mode 120000 dm-sflc/bin/lite/sflc_lite.h create mode 120000 dm-sflc/bin/lite/sflite_constants.h create mode 120000 dm-sflc/bin/lite/sysfs.c create mode 120000 dm-sflc/bin/lite/volume.c create mode 120000 dm-sflc/bin/lite/write.c create mode 120000 dm-sflc/bin/old/crypto/rand/rand.c create mode 120000 dm-sflc/bin/old/crypto/rand/rand.h create mode 120000 dm-sflc/bin/old/crypto/symkey/skreq_pool.c create mode 120000 dm-sflc/bin/old/crypto/symkey/skreq_pool.h create mode 120000 dm-sflc/bin/old/crypto/symkey/symkey.c create mode 120000 dm-sflc/bin/old/crypto/symkey/symkey.h create mode 120000 dm-sflc/bin/old/device/device.c create mode 120000 dm-sflc/bin/old/device/device.h create mode 120000 dm-sflc/bin/old/device/iv.c create mode 120000 dm-sflc/bin/old/device/rawio.c create mode 120000 dm-sflc/bin/old/device/rmap.c create mode 120000 dm-sflc/bin/old/device/volumes.c create mode 120000 dm-sflc/bin/old/log/log.h create mode 120000 dm-sflc/bin/old/sflc_old.c create mode 120000 dm-sflc/bin/old/sflc_old.h create mode 120000 dm-sflc/bin/old/sysfs.c create mode 120000 dm-sflc/bin/old/target.c create mode 120000 dm-sflc/bin/old/utils/bio.c create mode 120000 dm-sflc/bin/old/utils/bio.h create mode 120000 dm-sflc/bin/old/utils/pools.c create mode 120000 dm-sflc/bin/old/utils/pools.h create mode 120000 dm-sflc/bin/old/utils/string.c create mode 120000 dm-sflc/bin/old/utils/string.h create mode 120000 dm-sflc/bin/old/utils/vector.c create mode 120000 dm-sflc/bin/old/utils/vector.h create mode 120000 dm-sflc/bin/old/utils/workqueues.c create mode 120000 dm-sflc/bin/old/utils/workqueues.h create mode 120000 dm-sflc/bin/old/volume/fmap.c create mode 120000 dm-sflc/bin/old/volume/io.c create mode 120000 dm-sflc/bin/old/volume/read.c create mode 120000 dm-sflc/bin/old/volume/volume.c create mode 120000 dm-sflc/bin/old/volume/volume.h create mode 120000 dm-sflc/bin/old/volume/write.c create mode 120000 dm-sflc/bin/sflc.c create mode 120000 dm-sflc/bin/sflc.h create mode 120000 dm-sflc/bin/sflc_constants.h create mode 120000 dm-sflc/bin/sysfs.c rename dm-sflc/{ => src}/dev_vol.c (100%) rename dm-sflc/{ => src}/lite/crypto.c (100%) rename dm-sflc/{ => src}/lite/device.c (100%) rename dm-sflc/{ => src}/lite/posmap.c (100%) rename dm-sflc/{ => src}/lite/read.c (100%) rename dm-sflc/{ => src}/lite/sflc_lite.c (100%) rename dm-sflc/{ => src}/lite/sflc_lite.h (100%) rename dm-sflc/{ => src}/lite/sflite_constants.h (100%) rename dm-sflc/{ => src}/lite/sysfs.c (100%) rename dm-sflc/{ => src}/lite/volume.c (100%) rename dm-sflc/{ => src}/lite/write.c (100%) rename dm-sflc/{ => src}/old/crypto/rand/rand.c (100%) rename dm-sflc/{ => src}/old/crypto/rand/rand.h (100%) rename dm-sflc/{ => src}/old/crypto/symkey/skreq_pool.c (100%) rename dm-sflc/{ => src}/old/crypto/symkey/skreq_pool.h (100%) rename dm-sflc/{ => src}/old/crypto/symkey/symkey.c (100%) rename dm-sflc/{ => src}/old/crypto/symkey/symkey.h (100%) rename dm-sflc/{ => src}/old/device/device.c (100%) rename dm-sflc/{ => src}/old/device/device.h (100%) rename dm-sflc/{ => src}/old/device/iv.c (100%) rename dm-sflc/{ => src}/old/device/rawio.c (100%) rename dm-sflc/{ => src}/old/device/rmap.c (100%) rename dm-sflc/{ => src}/old/device/volumes.c (100%) rename dm-sflc/{ => src}/old/log/log.h (100%) rename dm-sflc/{ => src}/old/sflc_old.c (100%) rename dm-sflc/{ => src}/old/sflc_old.h (100%) rename dm-sflc/{ => src}/old/sysfs.c (100%) rename dm-sflc/{ => src}/old/target.c (100%) rename dm-sflc/{ => src}/old/utils/bio.c (100%) rename dm-sflc/{ => src}/old/utils/bio.h (100%) rename dm-sflc/{ => src}/old/utils/pools.c (100%) rename dm-sflc/{ => src}/old/utils/pools.h (100%) rename dm-sflc/{ => src}/old/utils/string.c (100%) rename dm-sflc/{ => src}/old/utils/string.h (100%) rename dm-sflc/{ => src}/old/utils/vector.c (100%) rename dm-sflc/{ => src}/old/utils/vector.h (100%) rename dm-sflc/{ => src}/old/utils/workqueues.c (100%) rename dm-sflc/{ => src}/old/utils/workqueues.h (100%) rename dm-sflc/{ => src}/old/volume/fmap.c (100%) rename dm-sflc/{ => src}/old/volume/io.c (100%) rename dm-sflc/{ => src}/old/volume/read.c (100%) rename dm-sflc/{ => src}/old/volume/volume.c (100%) rename dm-sflc/{ => src}/old/volume/volume.h (100%) rename dm-sflc/{ => src}/old/volume/write.c (100%) rename dm-sflc/{ => src}/sflc.c (100%) rename dm-sflc/{ => src}/sflc.h (100%) rename dm-sflc/{ => src}/sflc_constants.h (100%) rename dm-sflc/{ => src}/sysfs.c (100%) diff --git a/dm-sflc/.Kbuild b/dm-sflc/.Kbuild new file mode 100644 index 0000000..89a38fe --- /dev/null +++ b/dm-sflc/.Kbuild @@ -0,0 +1,53 @@ + # + # Copyright The Shufflecake Project Authors (2022) + # Copyright The Shufflecake Project Contributors (2022) + # Copyright Contributors to the The Shufflecake Project. + # + # See the AUTHORS file at the top-level directory of this distribution and at + # + # + # This file is part of the program shufflecake-c, which is part of the + # Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + # layer for Linux. See . + # + # This program is free software: you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by the Free + # Software Foundation, either version 2 of the License, or (at your option) + # any later version. 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, see . + # + +MODULE_NAME := dm_sflc +obj-m := $(MODULE_NAME).o + + +OBJ_LIST := sflc.o dev_vol.o sysfs.o + +OBJ_LIST += old/sflc_old.o old/target.o old/sysfs.o +OBJ_LIST += old/device/device.o old/device/volumes.o old/device/rawio.o old/device/rmap.o old/device/iv.o +OBJ_LIST += old/volume/volume.o old/volume/io.o old/volume/read.o old/volume/write.o old/volume/fmap.o +OBJ_LIST += old/utils/string.o old/utils/bio.o old/utils/pools.o old/utils/workqueues.o old/utils/vector.o +OBJ_LIST += old/crypto/rand/rand.o +OBJ_LIST += old/crypto/symkey/symkey.o old/crypto/symkey/skreq_pool.o + +OBJ_LIST += lite/sflc_lite.o lite/sysfs.o +OBJ_LIST += lite/device.o lite/volume.o +OBJ_LIST += lite/posmap.o lite/read.o lite/write.o lite/crypto.o + +$(MODULE_NAME)-y += $(OBJ_LIST) + + +# Normal CC flags +ccflags-y := -O2 +ccflags-y += -I$(src) +ccflags-y += -Wall -Wno-declaration-after-statement + +# Debug CC flags +ccflags-$(CONFIG_SFLC_DEBUG) += -DDEBUG +ccflags-$(CONFIG_SFLC_DEBUG) += -Og -g +ccflags-$(CONFIG_SFLC_DEBUG) += -fsanitize=kernel-address -fno-omit-frame-pointer + diff --git a/dm-sflc/.gitignore b/dm-sflc/.gitignore index ee31866..1ee0110 100644 --- a/dm-sflc/.gitignore +++ b/dm-sflc/.gitignore @@ -1,4 +1,8 @@ .project .cproject .settings/ -bin/ + +!bin/ +*.o +*.symvers +*.ko diff --git a/dm-sflc/Makefile b/dm-sflc/Makefile index b75f428..45a4f1e 100644 --- a/dm-sflc/Makefile +++ b/dm-sflc/Makefile @@ -22,25 +22,27 @@ # KERNEL_DIR = /lib/modules/$(shell uname -r)/build -SRC_DIR = $(shell pwd) -BUILD_DIR = $(shell pwd)/bin -BUILD_DIR_MAKEFILE = $(BUILD_DIR)/Makefile +ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) -default: $(BUILD_DIR_MAKEFILE) - make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) modules - -$(BUILD_DIR_MAKEFILE): $(BUILD_DIR) - echo "# This Makefile is here because of Kbuild" > $@ - -$(BUILD_DIR): - mkdir -p $@ +default: + make -C $(KERNEL_DIR) M=$(ROOT_DIR)/bin CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) modules debug: CONFIG_SFLC_DEBUG=y debug: default install: - make -C $(KERNEL_DIR) M=$(BUILD_DIR) src=$(SRC_DIR) modules_install + make -C $(KERNEL_DIR) M=$(BUILD_DIR) CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) modules_install clean: - rm -rf $(BUILD_DIR) + make -C $(KERNEL_DIR) M=$(BUILD_DIR) CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) clean + +# Reserved +ORIGINALS = $(shell find src/ -type f) +SYMLINKS = $(patsubst src/%, bin/%, $(ORIGINALS)) + +symlinks: $(SYMLINKS) + +bin/%: src/% + @mkdir -p "$(@D)" + ln -s $(shell realpath -m --relative-to=$(@D) $<) $@ diff --git a/dm-sflc/Kbuild b/dm-sflc/bin/Kbuild similarity index 99% rename from dm-sflc/Kbuild rename to dm-sflc/bin/Kbuild index 8b39934..89a38fe 100644 --- a/dm-sflc/Kbuild +++ b/dm-sflc/bin/Kbuild @@ -50,3 +50,4 @@ ccflags-y += -Wall -Wno-declaration-after-statement ccflags-$(CONFIG_SFLC_DEBUG) += -DDEBUG ccflags-$(CONFIG_SFLC_DEBUG) += -Og -g ccflags-$(CONFIG_SFLC_DEBUG) += -fsanitize=kernel-address -fno-omit-frame-pointer + diff --git a/dm-sflc/bin/dev_vol.c b/dm-sflc/bin/dev_vol.c new file mode 120000 index 0000000..a35e5d5 --- /dev/null +++ b/dm-sflc/bin/dev_vol.c @@ -0,0 +1 @@ +../src/dev_vol.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/crypto.c b/dm-sflc/bin/lite/crypto.c new file mode 120000 index 0000000..1f775dc --- /dev/null +++ b/dm-sflc/bin/lite/crypto.c @@ -0,0 +1 @@ +../../src/lite/crypto.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/device.c b/dm-sflc/bin/lite/device.c new file mode 120000 index 0000000..d2bcea5 --- /dev/null +++ b/dm-sflc/bin/lite/device.c @@ -0,0 +1 @@ +../../src/lite/device.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/posmap.c b/dm-sflc/bin/lite/posmap.c new file mode 120000 index 0000000..e60d53b --- /dev/null +++ b/dm-sflc/bin/lite/posmap.c @@ -0,0 +1 @@ +../../src/lite/posmap.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/read.c b/dm-sflc/bin/lite/read.c new file mode 120000 index 0000000..db9620e --- /dev/null +++ b/dm-sflc/bin/lite/read.c @@ -0,0 +1 @@ +../../src/lite/read.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/sflc_lite.c b/dm-sflc/bin/lite/sflc_lite.c new file mode 120000 index 0000000..1f2a01a --- /dev/null +++ b/dm-sflc/bin/lite/sflc_lite.c @@ -0,0 +1 @@ +../../src/lite/sflc_lite.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/sflc_lite.h b/dm-sflc/bin/lite/sflc_lite.h new file mode 120000 index 0000000..23798f5 --- /dev/null +++ b/dm-sflc/bin/lite/sflc_lite.h @@ -0,0 +1 @@ +../../src/lite/sflc_lite.h \ No newline at end of file diff --git a/dm-sflc/bin/lite/sflite_constants.h b/dm-sflc/bin/lite/sflite_constants.h new file mode 120000 index 0000000..3900993 --- /dev/null +++ b/dm-sflc/bin/lite/sflite_constants.h @@ -0,0 +1 @@ +../../src/lite/sflite_constants.h \ No newline at end of file diff --git a/dm-sflc/bin/lite/sysfs.c b/dm-sflc/bin/lite/sysfs.c new file mode 120000 index 0000000..4fd0f32 --- /dev/null +++ b/dm-sflc/bin/lite/sysfs.c @@ -0,0 +1 @@ +../../src/lite/sysfs.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/volume.c b/dm-sflc/bin/lite/volume.c new file mode 120000 index 0000000..2242793 --- /dev/null +++ b/dm-sflc/bin/lite/volume.c @@ -0,0 +1 @@ +../../src/lite/volume.c \ No newline at end of file diff --git a/dm-sflc/bin/lite/write.c b/dm-sflc/bin/lite/write.c new file mode 120000 index 0000000..665a955 --- /dev/null +++ b/dm-sflc/bin/lite/write.c @@ -0,0 +1 @@ +../../src/lite/write.c \ No newline at end of file diff --git a/dm-sflc/bin/old/crypto/rand/rand.c b/dm-sflc/bin/old/crypto/rand/rand.c new file mode 120000 index 0000000..cd1f529 --- /dev/null +++ b/dm-sflc/bin/old/crypto/rand/rand.c @@ -0,0 +1 @@ +../../../../src/old/crypto/rand/rand.c \ No newline at end of file diff --git a/dm-sflc/bin/old/crypto/rand/rand.h b/dm-sflc/bin/old/crypto/rand/rand.h new file mode 120000 index 0000000..f515491 --- /dev/null +++ b/dm-sflc/bin/old/crypto/rand/rand.h @@ -0,0 +1 @@ +../../../../src/old/crypto/rand/rand.h \ No newline at end of file diff --git a/dm-sflc/bin/old/crypto/symkey/skreq_pool.c b/dm-sflc/bin/old/crypto/symkey/skreq_pool.c new file mode 120000 index 0000000..86e2c3a --- /dev/null +++ b/dm-sflc/bin/old/crypto/symkey/skreq_pool.c @@ -0,0 +1 @@ +../../../../src/old/crypto/symkey/skreq_pool.c \ No newline at end of file diff --git a/dm-sflc/bin/old/crypto/symkey/skreq_pool.h b/dm-sflc/bin/old/crypto/symkey/skreq_pool.h new file mode 120000 index 0000000..26bf22c --- /dev/null +++ b/dm-sflc/bin/old/crypto/symkey/skreq_pool.h @@ -0,0 +1 @@ +../../../../src/old/crypto/symkey/skreq_pool.h \ No newline at end of file diff --git a/dm-sflc/bin/old/crypto/symkey/symkey.c b/dm-sflc/bin/old/crypto/symkey/symkey.c new file mode 120000 index 0000000..f9290b7 --- /dev/null +++ b/dm-sflc/bin/old/crypto/symkey/symkey.c @@ -0,0 +1 @@ +../../../../src/old/crypto/symkey/symkey.c \ No newline at end of file diff --git a/dm-sflc/bin/old/crypto/symkey/symkey.h b/dm-sflc/bin/old/crypto/symkey/symkey.h new file mode 120000 index 0000000..9db23d7 --- /dev/null +++ b/dm-sflc/bin/old/crypto/symkey/symkey.h @@ -0,0 +1 @@ +../../../../src/old/crypto/symkey/symkey.h \ No newline at end of file diff --git a/dm-sflc/bin/old/device/device.c b/dm-sflc/bin/old/device/device.c new file mode 120000 index 0000000..597ebc4 --- /dev/null +++ b/dm-sflc/bin/old/device/device.c @@ -0,0 +1 @@ +../../../src/old/device/device.c \ No newline at end of file diff --git a/dm-sflc/bin/old/device/device.h b/dm-sflc/bin/old/device/device.h new file mode 120000 index 0000000..17a90f4 --- /dev/null +++ b/dm-sflc/bin/old/device/device.h @@ -0,0 +1 @@ +../../../src/old/device/device.h \ No newline at end of file diff --git a/dm-sflc/bin/old/device/iv.c b/dm-sflc/bin/old/device/iv.c new file mode 120000 index 0000000..ba70509 --- /dev/null +++ b/dm-sflc/bin/old/device/iv.c @@ -0,0 +1 @@ +../../../src/old/device/iv.c \ No newline at end of file diff --git a/dm-sflc/bin/old/device/rawio.c b/dm-sflc/bin/old/device/rawio.c new file mode 120000 index 0000000..d1e7e2b --- /dev/null +++ b/dm-sflc/bin/old/device/rawio.c @@ -0,0 +1 @@ +../../../src/old/device/rawio.c \ No newline at end of file diff --git a/dm-sflc/bin/old/device/rmap.c b/dm-sflc/bin/old/device/rmap.c new file mode 120000 index 0000000..1b346c1 --- /dev/null +++ b/dm-sflc/bin/old/device/rmap.c @@ -0,0 +1 @@ +../../../src/old/device/rmap.c \ No newline at end of file diff --git a/dm-sflc/bin/old/device/volumes.c b/dm-sflc/bin/old/device/volumes.c new file mode 120000 index 0000000..531eab0 --- /dev/null +++ b/dm-sflc/bin/old/device/volumes.c @@ -0,0 +1 @@ +../../../src/old/device/volumes.c \ No newline at end of file diff --git a/dm-sflc/bin/old/log/log.h b/dm-sflc/bin/old/log/log.h new file mode 120000 index 0000000..be4c94e --- /dev/null +++ b/dm-sflc/bin/old/log/log.h @@ -0,0 +1 @@ +../../../src/old/log/log.h \ No newline at end of file diff --git a/dm-sflc/bin/old/sflc_old.c b/dm-sflc/bin/old/sflc_old.c new file mode 120000 index 0000000..f003fde --- /dev/null +++ b/dm-sflc/bin/old/sflc_old.c @@ -0,0 +1 @@ +../../src/old/sflc_old.c \ No newline at end of file diff --git a/dm-sflc/bin/old/sflc_old.h b/dm-sflc/bin/old/sflc_old.h new file mode 120000 index 0000000..17e112f --- /dev/null +++ b/dm-sflc/bin/old/sflc_old.h @@ -0,0 +1 @@ +../../src/old/sflc_old.h \ No newline at end of file diff --git a/dm-sflc/bin/old/sysfs.c b/dm-sflc/bin/old/sysfs.c new file mode 120000 index 0000000..a61025a --- /dev/null +++ b/dm-sflc/bin/old/sysfs.c @@ -0,0 +1 @@ +../../src/old/sysfs.c \ No newline at end of file diff --git a/dm-sflc/bin/old/target.c b/dm-sflc/bin/old/target.c new file mode 120000 index 0000000..d853b61 --- /dev/null +++ b/dm-sflc/bin/old/target.c @@ -0,0 +1 @@ +../../src/old/target.c \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/bio.c b/dm-sflc/bin/old/utils/bio.c new file mode 120000 index 0000000..3290da9 --- /dev/null +++ b/dm-sflc/bin/old/utils/bio.c @@ -0,0 +1 @@ +../../../src/old/utils/bio.c \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/bio.h b/dm-sflc/bin/old/utils/bio.h new file mode 120000 index 0000000..287e38d --- /dev/null +++ b/dm-sflc/bin/old/utils/bio.h @@ -0,0 +1 @@ +../../../src/old/utils/bio.h \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/pools.c b/dm-sflc/bin/old/utils/pools.c new file mode 120000 index 0000000..fe89f0f --- /dev/null +++ b/dm-sflc/bin/old/utils/pools.c @@ -0,0 +1 @@ +../../../src/old/utils/pools.c \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/pools.h b/dm-sflc/bin/old/utils/pools.h new file mode 120000 index 0000000..ccc41b3 --- /dev/null +++ b/dm-sflc/bin/old/utils/pools.h @@ -0,0 +1 @@ +../../../src/old/utils/pools.h \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/string.c b/dm-sflc/bin/old/utils/string.c new file mode 120000 index 0000000..7e3ad7b --- /dev/null +++ b/dm-sflc/bin/old/utils/string.c @@ -0,0 +1 @@ +../../../src/old/utils/string.c \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/string.h b/dm-sflc/bin/old/utils/string.h new file mode 120000 index 0000000..8391130 --- /dev/null +++ b/dm-sflc/bin/old/utils/string.h @@ -0,0 +1 @@ +../../../src/old/utils/string.h \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/vector.c b/dm-sflc/bin/old/utils/vector.c new file mode 120000 index 0000000..f340f39 --- /dev/null +++ b/dm-sflc/bin/old/utils/vector.c @@ -0,0 +1 @@ +../../../src/old/utils/vector.c \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/vector.h b/dm-sflc/bin/old/utils/vector.h new file mode 120000 index 0000000..ee1ff17 --- /dev/null +++ b/dm-sflc/bin/old/utils/vector.h @@ -0,0 +1 @@ +../../../src/old/utils/vector.h \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/workqueues.c b/dm-sflc/bin/old/utils/workqueues.c new file mode 120000 index 0000000..d60d1a3 --- /dev/null +++ b/dm-sflc/bin/old/utils/workqueues.c @@ -0,0 +1 @@ +../../../src/old/utils/workqueues.c \ No newline at end of file diff --git a/dm-sflc/bin/old/utils/workqueues.h b/dm-sflc/bin/old/utils/workqueues.h new file mode 120000 index 0000000..b8d2f7e --- /dev/null +++ b/dm-sflc/bin/old/utils/workqueues.h @@ -0,0 +1 @@ +../../../src/old/utils/workqueues.h \ No newline at end of file diff --git a/dm-sflc/bin/old/volume/fmap.c b/dm-sflc/bin/old/volume/fmap.c new file mode 120000 index 0000000..5b46520 --- /dev/null +++ b/dm-sflc/bin/old/volume/fmap.c @@ -0,0 +1 @@ +../../../src/old/volume/fmap.c \ No newline at end of file diff --git a/dm-sflc/bin/old/volume/io.c b/dm-sflc/bin/old/volume/io.c new file mode 120000 index 0000000..d7221c0 --- /dev/null +++ b/dm-sflc/bin/old/volume/io.c @@ -0,0 +1 @@ +../../../src/old/volume/io.c \ No newline at end of file diff --git a/dm-sflc/bin/old/volume/read.c b/dm-sflc/bin/old/volume/read.c new file mode 120000 index 0000000..efdcf3b --- /dev/null +++ b/dm-sflc/bin/old/volume/read.c @@ -0,0 +1 @@ +../../../src/old/volume/read.c \ No newline at end of file diff --git a/dm-sflc/bin/old/volume/volume.c b/dm-sflc/bin/old/volume/volume.c new file mode 120000 index 0000000..8e26280 --- /dev/null +++ b/dm-sflc/bin/old/volume/volume.c @@ -0,0 +1 @@ +../../../src/old/volume/volume.c \ No newline at end of file diff --git a/dm-sflc/bin/old/volume/volume.h b/dm-sflc/bin/old/volume/volume.h new file mode 120000 index 0000000..8f28ef6 --- /dev/null +++ b/dm-sflc/bin/old/volume/volume.h @@ -0,0 +1 @@ +../../../src/old/volume/volume.h \ No newline at end of file diff --git a/dm-sflc/bin/old/volume/write.c b/dm-sflc/bin/old/volume/write.c new file mode 120000 index 0000000..24e67c7 --- /dev/null +++ b/dm-sflc/bin/old/volume/write.c @@ -0,0 +1 @@ +../../../src/old/volume/write.c \ No newline at end of file diff --git a/dm-sflc/bin/sflc.c b/dm-sflc/bin/sflc.c new file mode 120000 index 0000000..d090f9d --- /dev/null +++ b/dm-sflc/bin/sflc.c @@ -0,0 +1 @@ +../src/sflc.c \ No newline at end of file diff --git a/dm-sflc/bin/sflc.h b/dm-sflc/bin/sflc.h new file mode 120000 index 0000000..0b7ccf2 --- /dev/null +++ b/dm-sflc/bin/sflc.h @@ -0,0 +1 @@ +../src/sflc.h \ No newline at end of file diff --git a/dm-sflc/bin/sflc_constants.h b/dm-sflc/bin/sflc_constants.h new file mode 120000 index 0000000..69cd0ab --- /dev/null +++ b/dm-sflc/bin/sflc_constants.h @@ -0,0 +1 @@ +../src/sflc_constants.h \ No newline at end of file diff --git a/dm-sflc/bin/sysfs.c b/dm-sflc/bin/sysfs.c new file mode 120000 index 0000000..e250188 --- /dev/null +++ b/dm-sflc/bin/sysfs.c @@ -0,0 +1 @@ +../src/sysfs.c \ No newline at end of file diff --git a/dm-sflc/dev_vol.c b/dm-sflc/src/dev_vol.c similarity index 100% rename from dm-sflc/dev_vol.c rename to dm-sflc/src/dev_vol.c diff --git a/dm-sflc/lite/crypto.c b/dm-sflc/src/lite/crypto.c similarity index 100% rename from dm-sflc/lite/crypto.c rename to dm-sflc/src/lite/crypto.c diff --git a/dm-sflc/lite/device.c b/dm-sflc/src/lite/device.c similarity index 100% rename from dm-sflc/lite/device.c rename to dm-sflc/src/lite/device.c diff --git a/dm-sflc/lite/posmap.c b/dm-sflc/src/lite/posmap.c similarity index 100% rename from dm-sflc/lite/posmap.c rename to dm-sflc/src/lite/posmap.c diff --git a/dm-sflc/lite/read.c b/dm-sflc/src/lite/read.c similarity index 100% rename from dm-sflc/lite/read.c rename to dm-sflc/src/lite/read.c diff --git a/dm-sflc/lite/sflc_lite.c b/dm-sflc/src/lite/sflc_lite.c similarity index 100% rename from dm-sflc/lite/sflc_lite.c rename to dm-sflc/src/lite/sflc_lite.c diff --git a/dm-sflc/lite/sflc_lite.h b/dm-sflc/src/lite/sflc_lite.h similarity index 100% rename from dm-sflc/lite/sflc_lite.h rename to dm-sflc/src/lite/sflc_lite.h diff --git a/dm-sflc/lite/sflite_constants.h b/dm-sflc/src/lite/sflite_constants.h similarity index 100% rename from dm-sflc/lite/sflite_constants.h rename to dm-sflc/src/lite/sflite_constants.h diff --git a/dm-sflc/lite/sysfs.c b/dm-sflc/src/lite/sysfs.c similarity index 100% rename from dm-sflc/lite/sysfs.c rename to dm-sflc/src/lite/sysfs.c diff --git a/dm-sflc/lite/volume.c b/dm-sflc/src/lite/volume.c similarity index 100% rename from dm-sflc/lite/volume.c rename to dm-sflc/src/lite/volume.c diff --git a/dm-sflc/lite/write.c b/dm-sflc/src/lite/write.c similarity index 100% rename from dm-sflc/lite/write.c rename to dm-sflc/src/lite/write.c diff --git a/dm-sflc/old/crypto/rand/rand.c b/dm-sflc/src/old/crypto/rand/rand.c similarity index 100% rename from dm-sflc/old/crypto/rand/rand.c rename to dm-sflc/src/old/crypto/rand/rand.c diff --git a/dm-sflc/old/crypto/rand/rand.h b/dm-sflc/src/old/crypto/rand/rand.h similarity index 100% rename from dm-sflc/old/crypto/rand/rand.h rename to dm-sflc/src/old/crypto/rand/rand.h diff --git a/dm-sflc/old/crypto/symkey/skreq_pool.c b/dm-sflc/src/old/crypto/symkey/skreq_pool.c similarity index 100% rename from dm-sflc/old/crypto/symkey/skreq_pool.c rename to dm-sflc/src/old/crypto/symkey/skreq_pool.c diff --git a/dm-sflc/old/crypto/symkey/skreq_pool.h b/dm-sflc/src/old/crypto/symkey/skreq_pool.h similarity index 100% rename from dm-sflc/old/crypto/symkey/skreq_pool.h rename to dm-sflc/src/old/crypto/symkey/skreq_pool.h diff --git a/dm-sflc/old/crypto/symkey/symkey.c b/dm-sflc/src/old/crypto/symkey/symkey.c similarity index 100% rename from dm-sflc/old/crypto/symkey/symkey.c rename to dm-sflc/src/old/crypto/symkey/symkey.c diff --git a/dm-sflc/old/crypto/symkey/symkey.h b/dm-sflc/src/old/crypto/symkey/symkey.h similarity index 100% rename from dm-sflc/old/crypto/symkey/symkey.h rename to dm-sflc/src/old/crypto/symkey/symkey.h diff --git a/dm-sflc/old/device/device.c b/dm-sflc/src/old/device/device.c similarity index 100% rename from dm-sflc/old/device/device.c rename to dm-sflc/src/old/device/device.c diff --git a/dm-sflc/old/device/device.h b/dm-sflc/src/old/device/device.h similarity index 100% rename from dm-sflc/old/device/device.h rename to dm-sflc/src/old/device/device.h diff --git a/dm-sflc/old/device/iv.c b/dm-sflc/src/old/device/iv.c similarity index 100% rename from dm-sflc/old/device/iv.c rename to dm-sflc/src/old/device/iv.c diff --git a/dm-sflc/old/device/rawio.c b/dm-sflc/src/old/device/rawio.c similarity index 100% rename from dm-sflc/old/device/rawio.c rename to dm-sflc/src/old/device/rawio.c diff --git a/dm-sflc/old/device/rmap.c b/dm-sflc/src/old/device/rmap.c similarity index 100% rename from dm-sflc/old/device/rmap.c rename to dm-sflc/src/old/device/rmap.c diff --git a/dm-sflc/old/device/volumes.c b/dm-sflc/src/old/device/volumes.c similarity index 100% rename from dm-sflc/old/device/volumes.c rename to dm-sflc/src/old/device/volumes.c diff --git a/dm-sflc/old/log/log.h b/dm-sflc/src/old/log/log.h similarity index 100% rename from dm-sflc/old/log/log.h rename to dm-sflc/src/old/log/log.h diff --git a/dm-sflc/old/sflc_old.c b/dm-sflc/src/old/sflc_old.c similarity index 100% rename from dm-sflc/old/sflc_old.c rename to dm-sflc/src/old/sflc_old.c diff --git a/dm-sflc/old/sflc_old.h b/dm-sflc/src/old/sflc_old.h similarity index 100% rename from dm-sflc/old/sflc_old.h rename to dm-sflc/src/old/sflc_old.h diff --git a/dm-sflc/old/sysfs.c b/dm-sflc/src/old/sysfs.c similarity index 100% rename from dm-sflc/old/sysfs.c rename to dm-sflc/src/old/sysfs.c diff --git a/dm-sflc/old/target.c b/dm-sflc/src/old/target.c similarity index 100% rename from dm-sflc/old/target.c rename to dm-sflc/src/old/target.c diff --git a/dm-sflc/old/utils/bio.c b/dm-sflc/src/old/utils/bio.c similarity index 100% rename from dm-sflc/old/utils/bio.c rename to dm-sflc/src/old/utils/bio.c diff --git a/dm-sflc/old/utils/bio.h b/dm-sflc/src/old/utils/bio.h similarity index 100% rename from dm-sflc/old/utils/bio.h rename to dm-sflc/src/old/utils/bio.h diff --git a/dm-sflc/old/utils/pools.c b/dm-sflc/src/old/utils/pools.c similarity index 100% rename from dm-sflc/old/utils/pools.c rename to dm-sflc/src/old/utils/pools.c diff --git a/dm-sflc/old/utils/pools.h b/dm-sflc/src/old/utils/pools.h similarity index 100% rename from dm-sflc/old/utils/pools.h rename to dm-sflc/src/old/utils/pools.h diff --git a/dm-sflc/old/utils/string.c b/dm-sflc/src/old/utils/string.c similarity index 100% rename from dm-sflc/old/utils/string.c rename to dm-sflc/src/old/utils/string.c diff --git a/dm-sflc/old/utils/string.h b/dm-sflc/src/old/utils/string.h similarity index 100% rename from dm-sflc/old/utils/string.h rename to dm-sflc/src/old/utils/string.h diff --git a/dm-sflc/old/utils/vector.c b/dm-sflc/src/old/utils/vector.c similarity index 100% rename from dm-sflc/old/utils/vector.c rename to dm-sflc/src/old/utils/vector.c diff --git a/dm-sflc/old/utils/vector.h b/dm-sflc/src/old/utils/vector.h similarity index 100% rename from dm-sflc/old/utils/vector.h rename to dm-sflc/src/old/utils/vector.h diff --git a/dm-sflc/old/utils/workqueues.c b/dm-sflc/src/old/utils/workqueues.c similarity index 100% rename from dm-sflc/old/utils/workqueues.c rename to dm-sflc/src/old/utils/workqueues.c diff --git a/dm-sflc/old/utils/workqueues.h b/dm-sflc/src/old/utils/workqueues.h similarity index 100% rename from dm-sflc/old/utils/workqueues.h rename to dm-sflc/src/old/utils/workqueues.h diff --git a/dm-sflc/old/volume/fmap.c b/dm-sflc/src/old/volume/fmap.c similarity index 100% rename from dm-sflc/old/volume/fmap.c rename to dm-sflc/src/old/volume/fmap.c diff --git a/dm-sflc/old/volume/io.c b/dm-sflc/src/old/volume/io.c similarity index 100% rename from dm-sflc/old/volume/io.c rename to dm-sflc/src/old/volume/io.c diff --git a/dm-sflc/old/volume/read.c b/dm-sflc/src/old/volume/read.c similarity index 100% rename from dm-sflc/old/volume/read.c rename to dm-sflc/src/old/volume/read.c diff --git a/dm-sflc/old/volume/volume.c b/dm-sflc/src/old/volume/volume.c similarity index 100% rename from dm-sflc/old/volume/volume.c rename to dm-sflc/src/old/volume/volume.c diff --git a/dm-sflc/old/volume/volume.h b/dm-sflc/src/old/volume/volume.h similarity index 100% rename from dm-sflc/old/volume/volume.h rename to dm-sflc/src/old/volume/volume.h diff --git a/dm-sflc/old/volume/write.c b/dm-sflc/src/old/volume/write.c similarity index 100% rename from dm-sflc/old/volume/write.c rename to dm-sflc/src/old/volume/write.c diff --git a/dm-sflc/sflc.c b/dm-sflc/src/sflc.c similarity index 100% rename from dm-sflc/sflc.c rename to dm-sflc/src/sflc.c diff --git a/dm-sflc/sflc.h b/dm-sflc/src/sflc.h similarity index 100% rename from dm-sflc/sflc.h rename to dm-sflc/src/sflc.h diff --git a/dm-sflc/sflc_constants.h b/dm-sflc/src/sflc_constants.h similarity index 100% rename from dm-sflc/sflc_constants.h rename to dm-sflc/src/sflc_constants.h diff --git a/dm-sflc/sysfs.c b/dm-sflc/src/sysfs.c similarity index 100% rename from dm-sflc/sysfs.c rename to dm-sflc/src/sysfs.c From d66667ed2a7b66d761520c8432de653a771c7b9d Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Aug 2024 23:09:55 +0200 Subject: [PATCH 71/75] fix Makefile --- dm-sflc/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dm-sflc/Makefile b/dm-sflc/Makefile index 45a4f1e..29c9b12 100644 --- a/dm-sflc/Makefile +++ b/dm-sflc/Makefile @@ -31,10 +31,10 @@ debug: CONFIG_SFLC_DEBUG=y debug: default install: - make -C $(KERNEL_DIR) M=$(BUILD_DIR) CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) modules_install + make -C $(KERNEL_DIR) M=$(ROOT_DIR)/bin CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) modules_install clean: - make -C $(KERNEL_DIR) M=$(BUILD_DIR) CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) clean + make -C $(KERNEL_DIR) M=$(ROOT_DIR)/bin CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) clean # Reserved From fb5cad845113919df050ae5f0f170ae8e2619db8 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Aug 2024 23:58:49 +0200 Subject: [PATCH 72/75] Fix dm_io --- dm-sflc/bin/lite/dm_io_helper.h | 1 + dm-sflc/src/lite/dm_io_helper.h | 56 +++++++++++++++++++++++++++++++++ dm-sflc/src/lite/posmap.c | 3 +- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 120000 dm-sflc/bin/lite/dm_io_helper.h create mode 100644 dm-sflc/src/lite/dm_io_helper.h diff --git a/dm-sflc/bin/lite/dm_io_helper.h b/dm-sflc/bin/lite/dm_io_helper.h new file mode 120000 index 0000000..ec2aa8e --- /dev/null +++ b/dm-sflc/bin/lite/dm_io_helper.h @@ -0,0 +1 @@ +../../src/lite/dm_io_helper.h \ No newline at end of file diff --git a/dm-sflc/src/lite/dm_io_helper.h b/dm-sflc/src/lite/dm_io_helper.h new file mode 100644 index 0000000..7e0d915 --- /dev/null +++ b/dm-sflc/src/lite/dm_io_helper.h @@ -0,0 +1,56 @@ +/* + * Copyright The Shufflecake Project Authors (2022) + * Copyright The Shufflecake Project Contributors (2022) + * Copyright Contributors to the The Shufflecake Project. + * + * See the AUTHORS file at the top-level directory of this distribution and at + * + * + * This file is part of the program shufflecake-c, which is part of the + * Shufflecake Project. Shufflecake is a plausible deniability (hidden storage) + * layer for Linux. See . + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your option) + * any later version. 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, see . + */ + +#ifndef _SFLITE_DMIOHELPER_H +#define _SFLITE_DMIOHELPER_H + +#include +#include + +/** + * The function dm_io() has changed signature in recent kernels. + * Here we provide a version-independent adapter, which uses a default value + * for the fifth parameter (the new one). + * The new signature is present for kernel 6.1.x with x>=83, 6.6.x with x>=23, + * 6.7.x with x>=11, 6.8.x with x>=2, 6.x with x>=9 + */ +#if LINUX_VERSION_MAJOR <= 5 // Old +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err) +#elif LINUX_VERSION_MAJOR >= 7 // New +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err, IOPRIO_DEFAULT) +// Ok LINUX_VERSION_MAJOR is 6 +#elif LINUX_VERSION_PATCHLEVEL >= 9 // New +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err, IOPRIO_DEFAULT) +#elif LINUX_VERSION_PATCHLEVEL == 8 && LINUX_VERSION_SUBLEVEL >= 2 // New +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err, IOPRIO_DEFAULT) +#elif LINUX_VERSION_PATCHLEVEL == 7 && LINUX_VERSION_SUBLEVEL >= 11 // New +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err, IOPRIO_DEFAULT) +#elif LINUX_VERSION_PATCHLEVEL == 6 && LINUX_VERSION_SUBLEVEL >= 23 // New +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err, IOPRIO_DEFAULT) +#elif LINUX_VERSION_PATCHLEVEL == 1 && LINUX_VERSION_SUBLEVEL >= 83 // New +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err, IOPRIO_DEFAULT) +#else // Old +#define sflc_dm_io(ioreq, numreg, region, err) dm_io(ioreq, numreg, region, err) +#endif + +#endif /* _SFLITE_DMIOHELPER_H */ diff --git a/dm-sflc/src/lite/posmap.c b/dm-sflc/src/lite/posmap.c index eb57072..3ee2551 100644 --- a/dm-sflc/src/lite/posmap.c +++ b/dm-sflc/src/lite/posmap.c @@ -23,6 +23,7 @@ #include #include +#include "dm_io_helper.h" #include "sflc_lite.h" @@ -268,7 +269,7 @@ static int read_encrypted_posmap(struct sflite_volume *svol) .count = svol->sdev->posmap_size_sectors }; - return dm_io(&io_req, 1, &io_region, NULL); + return sflc_dm_io(&io_req, 1, &io_region, NULL); } /** From 92d787530100f56dd98a4aed8bda2d01449df196 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 30 Aug 2024 00:27:01 +0200 Subject: [PATCH 73/75] Mah --- Makefile | 4 ++-- dm-sflc/bin/Kbuild | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4c88d2f..6d3666a 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ default: make -C dm-sflc - cp dm-sflc/bin/dm_sflc.ko ./dm_sflc.ko + cp dm-sflc/bin/dm-sflc.ko ./dm-sflc.ko make -C shufflecake-userland cp shufflecake-userland/bin/proj_build/shufflecake ./shufflecake @@ -48,7 +48,7 @@ clean: make -C dm-sflc clean make -C shufflecake-userland clean rm ./shufflecake - rm ./dm_sflc.ko + rm ./dm-sflc.ko diff --git a/dm-sflc/bin/Kbuild b/dm-sflc/bin/Kbuild index 89a38fe..5e5aa11 100644 --- a/dm-sflc/bin/Kbuild +++ b/dm-sflc/bin/Kbuild @@ -21,7 +21,7 @@ # If not, see . # -MODULE_NAME := dm_sflc +MODULE_NAME := dm-sflc obj-m := $(MODULE_NAME).o From d157647057c2d02e37fc2b3bef1c433c3adb63ca Mon Sep 17 00:00:00 2001 From: Tommaso Gagliardoni Date: Fri, 30 Aug 2024 00:27:54 +0200 Subject: [PATCH 74/75] chore:Update benchmark script --- sflc-benchmark-suite/sflc-benchmark.sh | 63 +++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/sflc-benchmark-suite/sflc-benchmark.sh b/sflc-benchmark-suite/sflc-benchmark.sh index 8c980d3..d703e84 100755 --- a/sflc-benchmark-suite/sflc-benchmark.sh +++ b/sflc-benchmark-suite/sflc-benchmark.sh @@ -42,7 +42,7 @@ NC='\033[0m' # No color # Help print_help() { # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars - echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]...${NC}" + echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]${NC}" echo " " echo "This script is used to benchmark Shufflecake on this machine." echo "This script is part of the Shufflecake benchmark suite." @@ -54,8 +54,7 @@ print_help() { echo "1) Creates a Shufflecake device with two volumes." echo "2) Opens the second (hidden) one, formats it with ext4 and mounts it." echo "3) Performs various fio r/w stress operations on it." - echo "4) Checks fragmentation status." - echo "5) Unmounts and closes the used volume." + echo "4) Unmounts and closes the used volume." echo " " # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars echo "You must have already compiled and installed Shufflecake in order to run this." @@ -71,7 +70,7 @@ print_help() { echo "formatted with the appropriate tools. The file will be removed at the end." echo " " # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars - echo "WARNING: ALL CONTENT OF THE PROVIDED BLOCK DEVICE WILL BE ERASED!" + echo -e "${BLUE}WARNING: ALL CONTENT OF THE PROVIDED BLOCK DEVICE WILL BE ERASED!${NC}" echo " " exit 0 } @@ -94,7 +93,7 @@ usage() { # Check that this is run as root check_sudo() { if [[ $EUID -ne 0 ]]; then - echo -e "${RED}Error: This script must be run as root${NC}" + echo -e "${RED}Error: This script must be run as root.${NC}" usage exit 1 fi @@ -129,7 +128,7 @@ find_sflc_path() { done # If the command was not found, print an error message - echo -e "${RED}ERROR: Command '$cmd' not found${NC}" >&2 + echo -e "${RED}ERROR: Command '$cmd' not found${NC}." >&2 exit 1 } @@ -162,14 +161,13 @@ load_dmsflc() { fi # If the module file was not found, print an error message - echo -e "${RED} ERROR: Module file '$mod_file' not found.${NC}" >&2 + echo -e "${RED} ERROR: Module file '$mod_file' not found.${NC}." >&2 exit 1 } # Unload dm-sflc if it was loaded locally unload_dmsflc() { local mod="dm-sflc" - # Only unload dm-sflc if it was loaded manually when the script was invoked if ! $DMSFLC_INSTALLED; then rmmod $mod || exit 1 @@ -193,15 +191,15 @@ check_block_device() { # Function to create loop device create_loop_device() { - echo "I will now try to create a file $LOOP_FILENAME" >&2 + echo "I will now try to create a file $LOOP_FILENAME ..." >&2 if [ -e "$LOOP_FILENAME" ]; then - echo -e "${RED}Error: Impossible to generate file, $LOOP_FILENAME already exists${NC}" + echo -e "${RED}Error: Impossible to generate file, $LOOP_FILENAME already exists.${NC}" exit 1 fi sudo dd if=/dev/zero of="$LOOP_FILENAME" bs=1M count=1024 > /dev/null echo "Writing of empty file complete. I will now try to attach it to a new loop device..." >&2 LOOP_DEVICE=$(sudo losetup -f --show "$LOOP_FILENAME") - echo "Successfully created loop device $LOOP_DEVICE" >&2 + echo "Successfully created loop device $LOOP_DEVICE ." >&2 echo "$LOOP_DEVICE" } @@ -222,7 +220,7 @@ find_sflcvolname() { # Function for user confirmation confirm() { while true; do - echo -e "${RED}Are you sure you want to proceed? All data on disk $BLOCK_DEVICE will be erased. (y/n)${NC}" + echo -e "${BLUE}Are you sure you want to proceed? All data on disk $BLOCK_DEVICE will be erased. (y/n)${NC}" read -r response case "$response" in [yY]|[yY][eE][sS]) # Responded Yes @@ -232,7 +230,7 @@ confirm() { return 1 # Return 1 for No (error, convention for bash scripting) ;; *) # Responded something else - echo "Please press only y or n." + echo "Please press only (y)es or (n)o." ;; esac done @@ -243,7 +241,11 @@ benchmark() { SFLCVOLUME="" MNTPOINT="" - echo -e "Starting benchmark for Shufflecake." + TESTNAME="sflc" + RUNTIME="20" # running time in seconds FOR EACH TEST + DATASIZE="500M" + TESTFILENAME="testfile" + echo "Starting benchmark for Shufflecake..." echo "Initializing block device $BLOCK_DEVICE with two Shufflecake volumes (--skip-randfill)..." etime=$( (time echo -e "passwd1\npasswd2" | $SFLCNAME --skip-randfill -n 2 init $BLOCK_DEVICE > /dev/null) 2>&1 ) echo -e "${GREEN}Action init took $etime seconds.${NC}" @@ -264,20 +266,20 @@ benchmark() { echo "Volume mounted at $MNTPOINT. Starting fio tests..." # TESTS HERE # test 01: random read - echo "Test 01: random read with a queue of 32 4kiB blocks on a file (20s)..." - OUTPUT=$(fio --name=sflc-r-rnd --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=1 --size=500M --runtime=20 --time_based --end_fsync=1 --filename=$MNTPOINT/testfile --output-format=json | jq '.jobs[] | {name: .jobname, read_iops: .read.iops, read_bw: .read.bw}') + echo "Test 01: random read with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..." + OUTPUT=$(fio --name=$TESTNAME-r-rnd --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, read_iops: .read.iops, read_bw: .read.bw}') echo -e "${GREEN}${OUTPUT}${NC}" # test 02: random write - echo "Test 02: random write with a queue of 32 4kiB blocks on a file (20s)..." - OUTPUT=$(fio --name=sflc-w-rnd --ioengine=libaio --iodepth=32 --rw=randwrite --bs=4k --numjobs=1 --size=500M --runtime=20 --time_based --end_fsync=1 --filename=$MNTPOINT/testfile --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}') + echo "Test 02: random write with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..." + OUTPUT=$(fio --name=$TESTNAME-w-rnd --ioengine=libaio --iodepth=32 --rw=randwrite --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}') echo -e "${GREEN}${OUTPUT}${NC}" # test 03: sequential read - echo "Test 03: sequential read with a queue of 32 4kiB blocks on a file (20s)..." - OUTPUT=$(fio --name=sflc-r-seq --ioengine=libaio --iodepth=32 --rw=read --bs=4k --numjobs=1 --size=500M --runtime=20 --time_based --end_fsync=1 --filename=$MNTPOINT/testfile --output-format=json | jq '.jobs[] | {name: .jobname, read_iops: .read.iops, read_bw: .read.bw}') + echo "Test 03: sequential read with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..." + OUTPUT=$(fio --name=$TESTNAME-r-seq --ioengine=libaio --iodepth=32 --rw=read --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, read_iops: .read.iops, read_bw: .read.bw}') echo -e "${GREEN}${OUTPUT}${NC}" # test 04: sequential write - echo "Test 04: sequential write with a queue of 32 4kiB blocks on a file (20s)..." - OUTPUT=$(fio --name=sflc-w-seq --ioengine=libaio --iodepth=32 --rw=write --bs=4k --numjobs=1 --size=500M --runtime=20 --time_based --end_fsync=1 --filename=$MNTPOINT/testfile --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}') + echo "Test 04: sequential write with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..." + OUTPUT=$(fio --name=$TESTNAME-w-seq --ioengine=libaio --iodepth=32 --rw=write --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}') echo -e "${GREEN}${OUTPUT}${NC}" # END TESTS echo "Shufflecake fio tests ended. Unmounting volume." @@ -295,11 +297,10 @@ benchmark() { # Clean up cleanup() { echo "Exiting and cleaning..." - # TODO clean other stuff if necessary if [[ -n $LOOP_DEVICE ]]; then - echo "Detaching $LOOP_DEVICE" + echo "Detaching $LOOP_DEVICE ..." sudo losetup -d "$LOOP_DEVICE" - echo "Deleting $LOOP_FILENAME" + echo "Deleting $LOOP_FILENAME ..." sudo rm -f "$LOOP_FILENAME" echo "Loop device detached and backing file deleted." fi @@ -314,12 +315,12 @@ cleanup() { # BANNER # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars -echo -e "${GREEN}===============================================================================${NC}" -echo -e "${GREEN} Benchmark Suite Script for Shufflecake${NC}" -echo -e "${GREEN}===============================================================================${NC}" +echo -e "${BLUE}===============================================================================${NC}" +echo -e "${BLUE} Benchmark Suite Script for Shufflecake${NC}" +echo -e "${BLUE}===============================================================================${NC}" -# PRELIMINARY: PARSE HELP AND LOAD SHUFFLECAKE +# PRELIMINARY: PARSE HELP, SUDO, AND LOAD SHUFFLECAKE (IF IT EXISTS, OTHERWISE ERROR) case "$1" in # help @@ -331,7 +332,7 @@ esac check_sudo -echo -e "${GREEN}Initializing Shufflecake...${NC}" +echo -e "${BLUE}Initializing Shufflecake...${NC}" echo "Searching Shufflecake executable..." find_sflc_path echo "Shufflecake executable found at $SFLCNAME ." @@ -373,7 +374,7 @@ check_block_device "$BLOCK_DEVICE" # MAIN PROGRAM if confirm; then - benchmark # Call your disk formatting function here + benchmark else echo "Aborting..." fi From 2a53c4fdd7ab59a0b3ad02c7fe35c6bac59671f7 Mon Sep 17 00:00:00 2001 From: Tommaso Gagliardoni Date: Sat, 31 Aug 2024 10:47:20 +0200 Subject: [PATCH 75/75] chore:Renamed benchmark-suite directory --- {sflc-benchmark-suite => benchmark-suite}/INSTRUCTIONS.md | 0 {sflc-benchmark-suite => benchmark-suite}/luks-benchmark.sh | 0 {sflc-benchmark-suite => benchmark-suite}/sflc-benchmark.sh | 0 {sflc-benchmark-suite => benchmark-suite}/veracrypt-benchmark.sh | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {sflc-benchmark-suite => benchmark-suite}/INSTRUCTIONS.md (100%) rename {sflc-benchmark-suite => benchmark-suite}/luks-benchmark.sh (100%) rename {sflc-benchmark-suite => benchmark-suite}/sflc-benchmark.sh (100%) rename {sflc-benchmark-suite => benchmark-suite}/veracrypt-benchmark.sh (100%) diff --git a/sflc-benchmark-suite/INSTRUCTIONS.md b/benchmark-suite/INSTRUCTIONS.md similarity index 100% rename from sflc-benchmark-suite/INSTRUCTIONS.md rename to benchmark-suite/INSTRUCTIONS.md diff --git a/sflc-benchmark-suite/luks-benchmark.sh b/benchmark-suite/luks-benchmark.sh similarity index 100% rename from sflc-benchmark-suite/luks-benchmark.sh rename to benchmark-suite/luks-benchmark.sh diff --git a/sflc-benchmark-suite/sflc-benchmark.sh b/benchmark-suite/sflc-benchmark.sh similarity index 100% rename from sflc-benchmark-suite/sflc-benchmark.sh rename to benchmark-suite/sflc-benchmark.sh diff --git a/sflc-benchmark-suite/veracrypt-benchmark.sh b/benchmark-suite/veracrypt-benchmark.sh similarity index 100% rename from sflc-benchmark-suite/veracrypt-benchmark.sh rename to benchmark-suite/veracrypt-benchmark.sh