mirror of
https://codeberg.org/shufflecake/shufflecake-c.git
synced 2026-01-07 03:25:26 -05:00
merge!:Test merge feature\rewrite-kernel-mod into copy dev2
This commit is contained in:
commit
b79805c361
151 changed files with 5633 additions and 2918 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -55,9 +55,18 @@ dkms.conf
|
|||
# Eclipse project files
|
||||
.project
|
||||
.cproject
|
||||
.settings/
|
||||
|
||||
# Shufflecake binaries
|
||||
shufflecake
|
||||
shufflecake-lite
|
||||
shufflecake-legacy
|
||||
|
||||
# Build directory
|
||||
bin/
|
||||
|
||||
# Test images
|
||||
disks/
|
||||
|
||||
# Temporary working directories
|
||||
dm-vvz/
|
||||
|
|
|
|||
|
|
@ -26,7 +26,12 @@
|
|||
# Variables
|
||||
SCRIPTNAME=$(basename "$0")
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
<<<<<<< HEAD
|
||||
CONTAINER_FILENAME=""
|
||||
=======
|
||||
LOOP_FILENAME="$SCRIPT_DIR/veracrypt-benchmark-loop-file.img"
|
||||
LOOP_DEVICE=""
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
TIMEFORMAT='%3R'
|
||||
|
||||
# Colors
|
||||
|
|
@ -38,7 +43,11 @@ NC='\033[0m' # No color
|
|||
# Help
|
||||
print_help() {
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
<<<<<<< HEAD
|
||||
echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]${NC}"
|
||||
=======
|
||||
echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]...${NC}"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
echo " "
|
||||
echo "This script is used to benchmark VeraCrypt on this machine."
|
||||
echo "This script is part of the Shufflecake benchmark suite."
|
||||
|
|
@ -47,6 +56,7 @@ print_help() {
|
|||
echo " "
|
||||
echo "This script requires root because it operates on block devices, please run it "
|
||||
echo -e "with ${BLUE}sudo${NC}. It does the following:"
|
||||
<<<<<<< HEAD
|
||||
echo "1) Creates a standard and unformatted VeraCrypt volumes within a given device."
|
||||
echo "2) Creates a hidden ext4 VeraCrypt volume within the standard one."
|
||||
echo "3) Opens the hidden volume, and mounts it."
|
||||
|
|
@ -61,6 +71,22 @@ print_help() {
|
|||
echo " "
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}WARNING: ALL CONTENT OF THE PROVIDED BLOCK DEVICE WILL BE ERASED!${NC}"
|
||||
=======
|
||||
echo "1) Creates standard and hidden VeraCrypt volumes within a given device."
|
||||
echo "2) Opens the hidden volume, formats it with ext4 and mounts it."
|
||||
echo "3) Performs various fio r/w stress operations on it."
|
||||
echo "4) Unmounts and closes the used volume."
|
||||
echo " "
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo "You can pass the path to a block device as an optional argument, otherwise the "
|
||||
echo "script will ask for one. If no path is provided, the script will create a 1 GiB"
|
||||
echo "local file and use it to back a loop device as a virtual block device to be "
|
||||
echo "formatted with the appropriate tools. The file will be removed at the end."
|
||||
echo " "
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo "NOTICE: This script has been tested only with VeraCrypt v 1.25.9."
|
||||
echo -e "${RED}WARNING: ALL CONTENT OF THE PROVIDED BLOCK DEVICE WILL BE ERASED!${NC}"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
echo " "
|
||||
exit 0
|
||||
}
|
||||
|
|
@ -84,7 +110,11 @@ usage() {
|
|||
# Check that this is run as root
|
||||
check_sudo() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
<<<<<<< HEAD
|
||||
echo -e "${RED}Error: This script must be run as root.${NC}"
|
||||
=======
|
||||
echo -e "${RED}Error: This script must be run as root${NC}"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -101,6 +131,7 @@ check_block_device() {
|
|||
fi
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
check_not_loopdevice() {
|
||||
DEVCHECK=$1
|
||||
if [[ $DEVCHECK == /dev/loop* ]]; then
|
||||
|
|
@ -121,12 +152,36 @@ create_container_file() {
|
|||
#dd if=/dev/zero of="$CONTAINER_FILENAME" bs=1M count=1024 > /dev/null
|
||||
#echo "Writing of empty file complete." >&2
|
||||
echo "$CONTAINER_FILENAME"
|
||||
=======
|
||||
# Function to create loop device
|
||||
create_loop_device() {
|
||||
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}"
|
||||
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 "$LOOP_DEVICE"
|
||||
}
|
||||
|
||||
# Generate a suitable VeraCrypt volume name
|
||||
find_veracryptvolname() {
|
||||
volname="/dev/mapper/vc01" #placeholder
|
||||
echo "$volname"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
}
|
||||
|
||||
# Function for user confirmation
|
||||
confirm() {
|
||||
while true; do
|
||||
<<<<<<< HEAD
|
||||
echo -e "${BLUE}Are you sure you want to proceed? All data in $BLOCK_DEVICE will be erased. (y/n)${NC}"
|
||||
=======
|
||||
echo -e "${RED}Are you sure you want to proceed? All data on disk $BLOCK_DEVICE will be erased. (y/n)${NC}"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
read -r response
|
||||
case "$response" in
|
||||
[yY]|[yY][eE][sS]) # Responded Yes
|
||||
|
|
@ -136,7 +191,11 @@ confirm() {
|
|||
return 1 # Return 1 for No (error, convention for bash scripting)
|
||||
;;
|
||||
*) # Responded something else
|
||||
<<<<<<< HEAD
|
||||
echo "Please press only (y)es or (n)o."
|
||||
=======
|
||||
echo "Please press only y or n."
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
|
@ -145,6 +204,7 @@ confirm() {
|
|||
# Benchmarks
|
||||
benchmark() {
|
||||
|
||||
<<<<<<< HEAD
|
||||
MNTPOINT=""
|
||||
TESTNAME="vc"
|
||||
RUNTIME="20" # running time in seconds FOR EACH TEST
|
||||
|
|
@ -194,15 +254,35 @@ benchmark() {
|
|||
rmdir $MNTPOINT
|
||||
echo "Volume detached and local mountpoint removed."
|
||||
#end
|
||||
=======
|
||||
VOLUME="veracrypt-test"
|
||||
MNTPOINT=""
|
||||
PASSPHRASE="mypassword"
|
||||
echo "Starting benchmark for VeraCrypt"
|
||||
# TESTS HERE
|
||||
bpx "THIS IS JUST A SKELETON, VERACRYPT SCRIPT NOT IMPLEMENTED YET, DOING NOTHING..."
|
||||
# END TESTS
|
||||
#end
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
}
|
||||
|
||||
# Clean up
|
||||
cleanup() {
|
||||
echo "Exiting and cleaning..."
|
||||
<<<<<<< HEAD
|
||||
if [[ -n $CONTAINER_FILENAME ]]; then
|
||||
echo "Deleting $CONTAINER_FILENAME..."
|
||||
rm -f "$CONTAINER_FILENAME"
|
||||
echo "Container file deleted."
|
||||
=======
|
||||
# TODO clean other stuff if necessary
|
||||
if [[ -n $LOOP_DEVICE ]]; then
|
||||
echo "Detaching $LOOP_DEVICE"
|
||||
sudo losetup -d "$LOOP_DEVICE"
|
||||
echo "Deleting $LOOP_FILENAME"
|
||||
sudo rm -f "$LOOP_FILENAME"
|
||||
echo "Loop device detached and backing file deleted."
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -215,9 +295,15 @@ cleanup() {
|
|||
|
||||
# BANNER
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
<<<<<<< HEAD
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
echo -e "${BLUE} Benchmark Suite Script for VeraCrypt${NC}"
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
=======
|
||||
echo -e "${GREEN}===============================================================================${NC}"
|
||||
echo -e "${GREEN} Benchmark Suite Script for VeraCrypt${NC}"
|
||||
echo -e "${GREEN}===============================================================================${NC}"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
|
||||
|
||||
# PRELIMINARY: PARSE HELP, SUDO, AND CHECK VERACRYPT EXISTS
|
||||
|
|
@ -243,12 +329,17 @@ echo " "
|
|||
# PARSER
|
||||
|
||||
case "$1" in
|
||||
<<<<<<< HEAD
|
||||
"") # no argument passed
|
||||
=======
|
||||
"")
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
|
||||
echo "Now you will be asked to enter the path for a block device to be used for the "
|
||||
echo "benchmarks (all content will be erased). If no path is provided (default"
|
||||
echo "choice), then the script will create a 1 GiB file in the current directory and "
|
||||
<<<<<<< HEAD
|
||||
echo "use it a VeraCrypt container instead, then the file will be removed at the end."
|
||||
echo " "
|
||||
echo -n "Please enter the path for a (non-loop) block device (default: none): "
|
||||
|
|
@ -262,6 +353,16 @@ case "$1" in
|
|||
BLOCK_DEVICE="$CONTAINER_FILENAME"
|
||||
else
|
||||
check_block_device "$BLOCK_DEVICE"
|
||||
=======
|
||||
echo "use it to back a loop device instead, then the file will be removed at the end."
|
||||
echo " "
|
||||
echo -n "Please enter the path for a block device (default: none): "
|
||||
read BLOCK_DEVICE
|
||||
if [ -z "$BLOCK_DEVICE" ]; then
|
||||
echo "No path provided, creating a local file and loop device..."
|
||||
LOOP_DEVICE=$(create_loop_device)
|
||||
BLOCK_DEVICE=$LOOP_DEVICE
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
fi
|
||||
|
||||
;;
|
||||
|
|
@ -269,16 +370,27 @@ case "$1" in
|
|||
# argument passed
|
||||
*)
|
||||
BLOCK_DEVICE="$1"
|
||||
<<<<<<< HEAD
|
||||
check_block_device "$BLOCK_DEVICE"
|
||||
;;
|
||||
esac
|
||||
|
||||
check_not_loopdevice "$BLOCK_DEVICE"
|
||||
=======
|
||||
;;
|
||||
esac
|
||||
|
||||
check_block_device "$BLOCK_DEVICE"
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
|
||||
# MAIN PROGRAM
|
||||
|
||||
if confirm; then
|
||||
<<<<<<< HEAD
|
||||
benchmark
|
||||
=======
|
||||
benchmark # Call your disk formatting function here
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
else
|
||||
echo "Aborting..."
|
||||
fi
|
||||
|
|
@ -286,3 +398,8 @@ fi
|
|||
cleanup
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
|
||||
>>>>>>> feature/rewrite-kernel-mod
|
||||
|
|
|
|||
53
dm-sflc/.Kbuild
Normal file
53
dm-sflc/.Kbuild
Normal file
|
|
@ -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
|
||||
# <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
#
|
||||
# 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 <https://www.shufflecake.net>.
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
6
dm-sflc/.gitignore
vendored
6
dm-sflc/.gitignore
vendored
|
|
@ -1,4 +1,8 @@
|
|||
.project
|
||||
.cproject
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
!bin/
|
||||
*.o
|
||||
*.symvers
|
||||
*.ko
|
||||
|
|
|
|||
|
|
@ -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=$(ROOT_DIR)/bin CONFIG_SFLC_DEBUG=$(CONFIG_SFLC_DEBUG) modules_install
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
make -C $(KERNEL_DIR) M=$(ROOT_DIR)/bin 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) $<) $@
|
||||
|
|
|
|||
|
|
@ -25,14 +25,18 @@ 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
|
||||
|
||||
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)
|
||||
|
||||
|
|
@ -41,9 +45,9 @@ $(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
|
||||
ccflags-$(CONFIG_SFLC_DEBUG) += -Og -g
|
||||
ccflags-$(CONFIG_SFLC_DEBUG) += -fsanitize=kernel-address -fno-omit-frame-pointer
|
||||
|
||||
1
dm-sflc/bin/dev_vol.c
Symbolic link
1
dm-sflc/bin/dev_vol.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../src/dev_vol.c
|
||||
1
dm-sflc/bin/lite/crypto.c
Symbolic link
1
dm-sflc/bin/lite/crypto.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/crypto.c
|
||||
1
dm-sflc/bin/lite/device.c
Symbolic link
1
dm-sflc/bin/lite/device.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/device.c
|
||||
1
dm-sflc/bin/lite/dm_io_helper.h
Symbolic link
1
dm-sflc/bin/lite/dm_io_helper.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/dm_io_helper.h
|
||||
1
dm-sflc/bin/lite/posmap.c
Symbolic link
1
dm-sflc/bin/lite/posmap.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/posmap.c
|
||||
1
dm-sflc/bin/lite/read.c
Symbolic link
1
dm-sflc/bin/lite/read.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/read.c
|
||||
1
dm-sflc/bin/lite/sflc_lite.c
Symbolic link
1
dm-sflc/bin/lite/sflc_lite.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/sflc_lite.c
|
||||
1
dm-sflc/bin/lite/sflc_lite.h
Symbolic link
1
dm-sflc/bin/lite/sflc_lite.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/sflc_lite.h
|
||||
1
dm-sflc/bin/lite/sflite_constants.h
Symbolic link
1
dm-sflc/bin/lite/sflite_constants.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/sflite_constants.h
|
||||
1
dm-sflc/bin/lite/sysfs.c
Symbolic link
1
dm-sflc/bin/lite/sysfs.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/sysfs.c
|
||||
1
dm-sflc/bin/lite/volume.c
Symbolic link
1
dm-sflc/bin/lite/volume.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/volume.c
|
||||
1
dm-sflc/bin/lite/write.c
Symbolic link
1
dm-sflc/bin/lite/write.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/lite/write.c
|
||||
1
dm-sflc/bin/old/crypto/rand/rand.c
Symbolic link
1
dm-sflc/bin/old/crypto/rand/rand.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/old/crypto/rand/rand.c
|
||||
1
dm-sflc/bin/old/crypto/rand/rand.h
Symbolic link
1
dm-sflc/bin/old/crypto/rand/rand.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/old/crypto/rand/rand.h
|
||||
1
dm-sflc/bin/old/crypto/symkey/skreq_pool.c
Symbolic link
1
dm-sflc/bin/old/crypto/symkey/skreq_pool.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/old/crypto/symkey/skreq_pool.c
|
||||
1
dm-sflc/bin/old/crypto/symkey/skreq_pool.h
Symbolic link
1
dm-sflc/bin/old/crypto/symkey/skreq_pool.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/old/crypto/symkey/skreq_pool.h
|
||||
1
dm-sflc/bin/old/crypto/symkey/symkey.c
Symbolic link
1
dm-sflc/bin/old/crypto/symkey/symkey.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/old/crypto/symkey/symkey.c
|
||||
1
dm-sflc/bin/old/crypto/symkey/symkey.h
Symbolic link
1
dm-sflc/bin/old/crypto/symkey/symkey.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/old/crypto/symkey/symkey.h
|
||||
1
dm-sflc/bin/old/device/device.c
Symbolic link
1
dm-sflc/bin/old/device/device.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/device/device.c
|
||||
1
dm-sflc/bin/old/device/device.h
Symbolic link
1
dm-sflc/bin/old/device/device.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/device/device.h
|
||||
1
dm-sflc/bin/old/device/iv.c
Symbolic link
1
dm-sflc/bin/old/device/iv.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/device/iv.c
|
||||
1
dm-sflc/bin/old/device/rawio.c
Symbolic link
1
dm-sflc/bin/old/device/rawio.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/device/rawio.c
|
||||
1
dm-sflc/bin/old/device/rmap.c
Symbolic link
1
dm-sflc/bin/old/device/rmap.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/device/rmap.c
|
||||
1
dm-sflc/bin/old/device/volumes.c
Symbolic link
1
dm-sflc/bin/old/device/volumes.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/device/volumes.c
|
||||
1
dm-sflc/bin/old/log/log.h
Symbolic link
1
dm-sflc/bin/old/log/log.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/log/log.h
|
||||
1
dm-sflc/bin/old/sflc_old.c
Symbolic link
1
dm-sflc/bin/old/sflc_old.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/old/sflc_old.c
|
||||
1
dm-sflc/bin/old/sflc_old.h
Symbolic link
1
dm-sflc/bin/old/sflc_old.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/old/sflc_old.h
|
||||
1
dm-sflc/bin/old/sysfs.c
Symbolic link
1
dm-sflc/bin/old/sysfs.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/old/sysfs.c
|
||||
1
dm-sflc/bin/old/target.c
Symbolic link
1
dm-sflc/bin/old/target.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/old/target.c
|
||||
1
dm-sflc/bin/old/utils/bio.c
Symbolic link
1
dm-sflc/bin/old/utils/bio.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/bio.c
|
||||
1
dm-sflc/bin/old/utils/bio.h
Symbolic link
1
dm-sflc/bin/old/utils/bio.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/bio.h
|
||||
1
dm-sflc/bin/old/utils/pools.c
Symbolic link
1
dm-sflc/bin/old/utils/pools.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/pools.c
|
||||
1
dm-sflc/bin/old/utils/pools.h
Symbolic link
1
dm-sflc/bin/old/utils/pools.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/pools.h
|
||||
1
dm-sflc/bin/old/utils/string.c
Symbolic link
1
dm-sflc/bin/old/utils/string.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/string.c
|
||||
1
dm-sflc/bin/old/utils/string.h
Symbolic link
1
dm-sflc/bin/old/utils/string.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/string.h
|
||||
1
dm-sflc/bin/old/utils/vector.c
Symbolic link
1
dm-sflc/bin/old/utils/vector.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/vector.c
|
||||
1
dm-sflc/bin/old/utils/vector.h
Symbolic link
1
dm-sflc/bin/old/utils/vector.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/vector.h
|
||||
1
dm-sflc/bin/old/utils/workqueues.c
Symbolic link
1
dm-sflc/bin/old/utils/workqueues.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/workqueues.c
|
||||
1
dm-sflc/bin/old/utils/workqueues.h
Symbolic link
1
dm-sflc/bin/old/utils/workqueues.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/utils/workqueues.h
|
||||
1
dm-sflc/bin/old/volume/fmap.c
Symbolic link
1
dm-sflc/bin/old/volume/fmap.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/volume/fmap.c
|
||||
1
dm-sflc/bin/old/volume/io.c
Symbolic link
1
dm-sflc/bin/old/volume/io.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/volume/io.c
|
||||
1
dm-sflc/bin/old/volume/read.c
Symbolic link
1
dm-sflc/bin/old/volume/read.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/volume/read.c
|
||||
1
dm-sflc/bin/old/volume/volume.c
Symbolic link
1
dm-sflc/bin/old/volume/volume.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/volume/volume.c
|
||||
1
dm-sflc/bin/old/volume/volume.h
Symbolic link
1
dm-sflc/bin/old/volume/volume.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/volume/volume.h
|
||||
1
dm-sflc/bin/old/volume/write.c
Symbolic link
1
dm-sflc/bin/old/volume/write.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/old/volume/write.c
|
||||
1
dm-sflc/bin/sflc.c
Symbolic link
1
dm-sflc/bin/sflc.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../src/sflc.c
|
||||
1
dm-sflc/bin/sflc.h
Symbolic link
1
dm-sflc/bin/sflc.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../src/sflc.h
|
||||
1
dm-sflc/bin/sflc_constants.h
Symbolic link
1
dm-sflc/bin/sflc_constants.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../src/sflc_constants.h
|
||||
1
dm-sflc/bin/sysfs.c
Symbolic link
1
dm-sflc/bin/sysfs.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../src/sysfs.c
|
||||
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file only implements the device-related device management functions.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "device.h"
|
||||
#include "sysfs/sysfs.h"
|
||||
#include "utils/vector.h"
|
||||
#include "log/log.h"
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC VARIABLES DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* The next available device ID */
|
||||
size_t sflc_dev_nextId;
|
||||
|
||||
LIST_HEAD(sflc_dev_list);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,0)
|
||||
DEFINE_SEMAPHORE(sflc_dev_mutex, 1);
|
||||
#else
|
||||
DEFINE_SEMAPHORE(sflc_dev_mutex);
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* 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);
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Inits global variables */
|
||||
int sflc_dev_init(void)
|
||||
{
|
||||
/* 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;
|
||||
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);
|
||||
if (!dev) {
|
||||
pr_err("Could not allocate %lu bytes for sflc_Device\n", sizeof(sflc_Device));
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_dev;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Set backing real device */
|
||||
err = dm_get_device(ti, real_dev_path, 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;
|
||||
}
|
||||
/* And its path */
|
||||
dev->bdev_path = kmalloc(strlen(real_dev_path) + 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);
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_real_dev_path;
|
||||
}
|
||||
strcpy(dev->bdev_path, real_dev_path);
|
||||
|
||||
/* Init volumes */
|
||||
for (i = 0; i < SFLC_DEV_MAX_VOLUMES; ++i) {
|
||||
dev->vol[i] = NULL;
|
||||
}
|
||||
dev->vol_cnt = 0;
|
||||
|
||||
/* Set slices info */
|
||||
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);
|
||||
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);
|
||||
|
||||
/* Init slices lock */
|
||||
mutex_init(&dev->slices_lock);
|
||||
/* Allocate reverse slice map */
|
||||
dev->rmap = vmalloc(dev->tot_slices * sizeof(u8));
|
||||
if (!dev->rmap) {
|
||||
pr_err("Could not allocate reverse slice map\n");
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_rmap;
|
||||
}
|
||||
/* Initialise it */
|
||||
memset(dev->rmap, SFLC_DEV_RMAP_INVALID_VOL, dev->tot_slices * sizeof(u8));
|
||||
/* Allocate PSI array */
|
||||
dev->prmslices = vmalloc(dev->tot_slices * sizeof(u32));
|
||||
if (!dev->prmslices) {
|
||||
pr_err("Could not allocate PSI array\n");
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_psi_array;
|
||||
}
|
||||
/* Initialise it and pre-shuffle it */
|
||||
err = sflc_dev_initAndShufflePsiArray(dev->prmslices, dev->tot_slices);
|
||||
if (err) {
|
||||
pr_err("Could not init-and-shuffle PSI array: error %d", err);
|
||||
goto err_initshuffle_psi_array;
|
||||
}
|
||||
/* Init related counter */
|
||||
dev->prmslices_octr = 0;
|
||||
|
||||
/* Init IV cache lock */
|
||||
mutex_init(&dev->iv_cache_lock);
|
||||
/* Init IV cache waitqueue */
|
||||
init_waitqueue_head(&dev->iv_cache_waitqueue);
|
||||
/* Allocate IV cache */
|
||||
dev->iv_cache = vzalloc(dev->tot_slices * sizeof(sflc_dev_IvCacheEntry *));
|
||||
if (!dev->iv_cache) {
|
||||
pr_err("Could not allocate IV cache\n");
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_iv_cache;
|
||||
}
|
||||
/* Set it empty */
|
||||
dev->iv_cache_nr_entries = 0;
|
||||
/* 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);
|
||||
goto err_sysfs;
|
||||
}
|
||||
|
||||
/* Create dm_io_client */
|
||||
dev->dmio_client = dm_io_client_create();
|
||||
if (IS_ERR(dev->dmio_client)) {
|
||||
err = PTR_ERR(dev->dmio_client);
|
||||
pr_err("Could not create dm_io_client; error %d\n", err);
|
||||
goto err_dmio;
|
||||
}
|
||||
|
||||
/* Add to device list */
|
||||
list_add_tail(&dev->list_node, &sflc_dev_list);
|
||||
|
||||
return dev;
|
||||
|
||||
|
||||
err_dmio:
|
||||
sflc_sysfs_putDev(dev->kobj);
|
||||
err_sysfs:
|
||||
vfree(dev->iv_cache);
|
||||
err_alloc_iv_cache:
|
||||
err_initshuffle_psi_array:
|
||||
vfree(dev->prmslices);
|
||||
err_alloc_psi_array:
|
||||
vfree(dev->rmap);
|
||||
err_alloc_rmap:
|
||||
kfree(dev->bdev_path);
|
||||
err_alloc_real_dev_path:
|
||||
dm_put_device(ti, dev->bdev);
|
||||
err_dm_get_dev:
|
||||
sflc_dev_releaseId(dev->dev_id);
|
||||
err_dev_id:
|
||||
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)
|
||||
{
|
||||
/* Check if we actually have to put this device */
|
||||
if (!dev) {
|
||||
return false;
|
||||
}
|
||||
if (dev->vol_cnt > 0) {
|
||||
pr_warn("Called while still holding %d volumes\n", dev->vol_cnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Flush all IVs */
|
||||
sflc_dev_flushIvs(dev);
|
||||
|
||||
/* List */
|
||||
list_del(&dev->list_node);
|
||||
|
||||
/* dm_io */
|
||||
dm_io_client_destroy(dev->dmio_client);
|
||||
|
||||
/* Sysfs */
|
||||
sflc_sysfs_putDev(dev->kobj);
|
||||
|
||||
/* IV cache */
|
||||
vfree(dev->iv_cache);
|
||||
|
||||
/* PSI array */
|
||||
vfree(dev->prmslices);
|
||||
|
||||
/* Reverse slice map */
|
||||
vfree(dev->rmap);
|
||||
|
||||
/* Backing device */
|
||||
dm_put_device(ti, dev->bdev);
|
||||
kfree(dev->bdev_path);
|
||||
|
||||
/* Release device ID */
|
||||
sflc_dev_releaseId(dev->dev_id);
|
||||
|
||||
/* Free the device itself */
|
||||
kfree(dev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* 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)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
/* Init to the identity map */
|
||||
for (i = 0; i < len; i++) {
|
||||
psi_array[i] = i;
|
||||
}
|
||||
|
||||
/* Permute */
|
||||
return sflc_vec_u32shuffle(psi_array, len);
|
||||
}
|
||||
|
||||
151
dm-sflc/module.c
151
dm-sflc/module.c
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device-mapper.h>
|
||||
|
||||
#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"
|
||||
|
||||
/*****************************************************
|
||||
* 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 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();
|
||||
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();
|
||||
if (ret) {
|
||||
pr_err("Could not init memory pools; error %d\n", ret);
|
||||
goto err_pools;
|
||||
}
|
||||
|
||||
/* Init the workqueues */
|
||||
ret = sflc_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();
|
||||
err_pools:
|
||||
sflc_sysfs_exit();
|
||||
err_sysfs:
|
||||
err_rand_selftest:
|
||||
err_sk:
|
||||
sflc_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)
|
||||
{
|
||||
dm_unregister_target(&sflc_target);
|
||||
sflc_queues_exit();
|
||||
sflc_pools_exit();
|
||||
sflc_sysfs_exit();
|
||||
sflc_rand_exit();
|
||||
sflc_dev_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");
|
||||
209
dm-sflc/src/dev_vol.c
Normal file
209
dm-sflc/src/dev_vol.c
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* 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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#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;
|
||||
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;
|
||||
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;
|
||||
case SFLC_MODE_LITE:
|
||||
sflite_dev_destroy(sdev->sflite_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);
|
||||
svol->sdev = sdev;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
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;
|
||||
case SFLC_MODE_LITE:
|
||||
sflite_vol_destroy(svol->sflite_vol);
|
||||
break;
|
||||
default:
|
||||
DMCRIT("Destroying volume with invalid Shufflecake mode %d", svol->mode);
|
||||
return;
|
||||
}
|
||||
|
||||
sflc_sysfs_unregister_volume(svol);
|
||||
kfree(svol);
|
||||
}
|
||||
125
dm-sflc/src/lite/crypto.c
Normal file
125
dm-sflc/src/lite/crypto.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
204
dm-sflc/src/lite/device.c
Normal file
204
dm-sflc/src/lite/device.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/minmax.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
56
dm-sflc/src/lite/dm_io_helper.h
Normal file
56
dm-sflc/src/lite/dm_io_helper.h
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SFLITE_DMIOHELPER_H
|
||||
#define _SFLITE_DMIOHELPER_H
|
||||
|
||||
#include <linux/dm-io.h>
|
||||
#include <generated/uapi/linux/version.h>
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
377
dm-sflc/src/lite/posmap.c
Normal file
377
dm-sflc/src/lite/posmap.c
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* 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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/delay.h>
|
||||
#include "dm_io_helper.h"
|
||||
#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 sflc_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;
|
||||
}
|
||||
|
||||
168
dm-sflc/src/lite/read.c
Normal file
168
dm-sflc/src/lite/read.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sflc_lite.h"
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
161
dm-sflc/src/lite/sflc_lite.c
Normal file
161
dm-sflc/src/lite/sflc_lite.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device-mapper.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "sflite_constants.h"
|
||||
#include "sflc_lite.h"
|
||||
|
||||
// Only to import the definition of struct sflc_volume
|
||||
#include "sflc.h"
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------
|
||||
* 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;
|
||||
}
|
||||
|
||||
182
dm-sflc/src/lite/sflc_lite.h
Normal file
182
dm-sflc/src/lite/sflc_lite.h
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SFLITE_SFLITE_H
|
||||
#define _SFLITE_SFLITE_H
|
||||
|
||||
#include <linux/device-mapper.h>
|
||||
#include <linux/dm-io.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include "sflite_constants.h"
|
||||
#include "sflc_constants.h"
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------
|
||||
* Structs
|
||||
*----------------------------
|
||||
*/
|
||||
|
||||
struct sflite_device
|
||||
{
|
||||
/* Shufflecake-unique device ID */
|
||||
u32 dev_id;
|
||||
/* <MAJOR>:<MINOR> */
|
||||
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_<devID>_<volIdx> */
|
||||
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 */
|
||||
53
dm-sflc/src/lite/sflite_constants.h
Normal file
53
dm-sflc/src/lite/sflite_constants.h
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* 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_ */
|
||||
116
dm-sflc/src/lite/sysfs.c
Normal file
116
dm-sflc/src/lite/sysfs.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
163
dm-sflc/src/lite/volume.c
Normal file
163
dm-sflc/src/lite/volume.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
#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 */
|
||||
svol->kobj_parent = kobj;
|
||||
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;
|
||||
}
|
||||
148
dm-sflc/src/lite/write.c
Normal file
148
dm-sflc/src/lite/write.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sflc_lite.h"
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -28,55 +28,55 @@
|
|||
#include <crypto/rng.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#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;
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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 <linux/mempool.h>
|
||||
|
||||
#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_ */
|
||||
|
|
@ -27,66 +27,66 @@
|
|||
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#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);
|
||||
|
|
@ -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_ */
|
||||
259
dm-sflc/src/old/device/device.c
Normal file
259
dm-sflc/src/old/device/device.c
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* 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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file only implements the device-related device management functions.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "old/sflc_old.h"
|
||||
#include "old/device/device.h"
|
||||
#include "old/utils/vector.h"
|
||||
#include "old/log/log.h"
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC VARIABLES DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
|
||||
/* Initialises and pre-shuffles the PSI array */
|
||||
static int sfold_dev_initAndShufflePsiArray(u32 *psi_array, u32 len);
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/**
|
||||
* Creates 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_Device *sfold_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj)
|
||||
{
|
||||
sfold_Device * dev;
|
||||
u32 tot_slices;
|
||||
u32 dev_id;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
/* Allocate device */
|
||||
dev = kzalloc(sizeof(sfold_Device), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
pr_err("Could not allocate %lu bytes for sfold_Device\n", sizeof(sfold_Device));
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_dev;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
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 = dev_id;
|
||||
|
||||
/* Set backing real device */
|
||||
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(argv[2]) + 1, GFP_KERNEL);
|
||||
if (!dev->bdev_path) {
|
||||
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, argv[2]);
|
||||
|
||||
/* Init volumes */
|
||||
for (i = 0; i < SFOLD_DEV_MAX_VOLUMES; ++i) {
|
||||
dev->vol[i] = NULL;
|
||||
}
|
||||
dev->vol_cnt = 0;
|
||||
|
||||
/* Set slices info */
|
||||
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, 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 + (SFOLD_DEV_MAX_VOLUMES * dev->vol_header_size);
|
||||
|
||||
/* Init slices lock */
|
||||
mutex_init(&dev->slices_lock);
|
||||
/* Allocate reverse slice map */
|
||||
dev->rmap = vmalloc(dev->tot_slices * sizeof(u8));
|
||||
if (!dev->rmap) {
|
||||
pr_err("Could not allocate reverse slice map\n");
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_rmap;
|
||||
}
|
||||
/* Initialise it */
|
||||
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) {
|
||||
pr_err("Could not allocate PSI array\n");
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_psi_array;
|
||||
}
|
||||
/* Initialise it and pre-shuffle it */
|
||||
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;
|
||||
}
|
||||
/* Init related counter */
|
||||
dev->shuffled_psi_ctr = 0;
|
||||
|
||||
/* Init IV cache lock */
|
||||
mutex_init(&dev->iv_cache_lock);
|
||||
/* Init IV cache waitqueue */
|
||||
init_waitqueue_head(&dev->iv_cache_waitqueue);
|
||||
/* Allocate IV cache */
|
||||
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;
|
||||
goto err_alloc_iv_cache;
|
||||
}
|
||||
/* Set it empty */
|
||||
dev->iv_cache_nr_entries = 0;
|
||||
/* Init list head */
|
||||
INIT_LIST_HEAD(&dev->iv_lru_list);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return dev;
|
||||
|
||||
|
||||
err_sysfs:
|
||||
kfree(dev->iv_cache);
|
||||
err_alloc_iv_cache:
|
||||
err_initshuffle_psi_array:
|
||||
vfree(dev->shuffled_psi_array);
|
||||
err_alloc_psi_array:
|
||||
vfree(dev->rmap);
|
||||
err_alloc_rmap:
|
||||
kfree(dev->bdev_path);
|
||||
err_alloc_real_dev_path:
|
||||
dm_put_device(ti, dev->bdev);
|
||||
err_dm_get_dev:
|
||||
err_parse:
|
||||
kfree(dev);
|
||||
err_alloc_dev:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
|
||||
/* Returns false if still busy (not all volumes have been removed). Frees the Device. */
|
||||
bool sfold_dev_destroy(sfold_Device * dev)
|
||||
{
|
||||
/* Check if we actually have to put this device */
|
||||
if (!dev) {
|
||||
return false;
|
||||
}
|
||||
if (dev->vol_cnt > 0) {
|
||||
pr_warn("Called while still holding %d volumes\n", dev->vol_cnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Flush all IVs */
|
||||
sfold_dev_flushIvs(dev);
|
||||
|
||||
/* List */
|
||||
list_del(&dev->list_node);
|
||||
|
||||
/* Sysfs */
|
||||
sfold_sysfs_remove_device(dev);
|
||||
|
||||
/* IV cache */
|
||||
kfree(dev->iv_cache);
|
||||
|
||||
/* PSI array */
|
||||
vfree(dev->shuffled_psi_array);
|
||||
|
||||
/* Reverse slice map */
|
||||
vfree(dev->rmap);
|
||||
|
||||
/* Backing device */
|
||||
dm_put_device(dev->ti, dev->bdev);
|
||||
kfree(dev->bdev_path);
|
||||
|
||||
/* Free the device itself */
|
||||
kfree(dev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Initialises and pre-shuffles the PSI array */
|
||||
static int sfold_dev_initAndShufflePsiArray(u32 *psi_array, u32 len)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
/* Init to the identity map */
|
||||
for (i = 0; i < len; i++) {
|
||||
psi_array[i] = i;
|
||||
}
|
||||
|
||||
/* Permute */
|
||||
return sfold_vec_u32shuffle(psi_array, len);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
||||
/*****************************************************
|
||||
|
|
@ -49,11 +49,10 @@ typedef struct sflc_dev_iv_cache_entry_s sflc_dev_IvCacheEntry;
|
|||
*****************************************************/
|
||||
|
||||
#include <linux/device-mapper.h>
|
||||
#include <linux/dm-io.h>
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/*****************************************************
|
||||
|
|
@ -61,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;
|
||||
|
|
@ -100,23 +99,25 @@ 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 */
|
||||
u8 * rmap;
|
||||
/* Shuffled array of PSIs, with advancement counter */
|
||||
u32 *prmslices;
|
||||
u32 prmslices_octr;
|
||||
u32 *shuffled_psi_array;
|
||||
u32 shuffled_psi_ctr;
|
||||
/* Lock for all three of these objects */
|
||||
struct mutex slices_lock;
|
||||
|
||||
|
|
@ -129,98 +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;
|
||||
|
||||
/* DM-io */
|
||||
struct dm_io_client *dmio_client;
|
||||
|
||||
/* We keep all devices in a list */
|
||||
struct list_head list_node;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* MACROS *
|
||||
*****************************************************/
|
||||
|
||||
#define sflc_dev_psiToIvBlock(dev, psi) (dev->dev_header_size + (sector_t)(psi) * SFLC_DEV_PHYS_SLICE_SIZE)
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* 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);
|
||||
|
||||
/* Synchronously read/write entire PSI (257 blocks) to/from VMA */
|
||||
int sflc_dev_rwPsi(sflc_Device *dev, void *vma, u32 psi, 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 */
|
||||
|
||||
/* Checks if PSI is free */
|
||||
bool sflc_dev_isPsiFree(sflc_Device *dev, u32 psi);
|
||||
|
||||
/* 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.
|
||||
|
|
@ -231,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_ */
|
||||
|
|
@ -25,24 +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 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 *
|
||||
|
|
@ -50,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 */
|
||||
|
|
@ -65,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;
|
||||
|
|
@ -93,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);
|
||||
|
|
@ -133,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) */
|
||||
|
|
@ -156,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) {
|
||||
|
|
@ -182,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;
|
||||
|
|
@ -210,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 */
|
||||
|
|
@ -221,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);
|
||||
}
|
||||
|
|
@ -232,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;
|
||||
|
|
@ -251,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;
|
||||
|
|
@ -271,10 +277,10 @@ static sflc_dev_IvCacheEntry * sflc_dev_newIvCacheEntry(sflc_Device * dev, u32 p
|
|||
/* Read from disk */
|
||||
|
||||
/* Position on disk */
|
||||
sector = sflc_dev_psiToIvBlock(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;
|
||||
|
|
@ -285,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;
|
||||
|
|
@ -300,11 +306,11 @@ static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry
|
|||
/* Write to disk */
|
||||
|
||||
/* Position on disk */
|
||||
sector = sflc_dev_psiToIvBlock(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;
|
||||
|
|
@ -317,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;
|
||||
}
|
||||
|
|
@ -25,14 +25,12 @@
|
|||
* 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 <linux/bio.h>
|
||||
#include <linux/dm-io.h>
|
||||
#include <linux/errno.h>
|
||||
//#include <linux/ioprio.h>
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
|
|
@ -48,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;
|
||||
|
|
@ -59,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;
|
||||
|
|
@ -83,32 +81,6 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Synchronously read/write entire PSI (257 blocks) to/from VMA
|
||||
int sflc_dev_rwPsi(sflc_Device *dev, void *vma, u32 psi, int rw)
|
||||
{
|
||||
struct dm_io_request io_req = {
|
||||
.bi_opf = ((rw == READ) ? REQ_OP_READ : REQ_OP_WRITE) | REQ_SYNC,
|
||||
|
||||
.mem.type = DM_IO_VMA,
|
||||
.mem.offset = 0,
|
||||
.mem.ptr.vma = vma,
|
||||
|
||||
.notify.fn = NULL,
|
||||
|
||||
.client = dev->dmio_client
|
||||
};
|
||||
struct dm_io_region io_reg = {
|
||||
.bdev = dev->bdev->bdev,
|
||||
.sector = sflc_dev_psiToIvBlock(dev, psi) * SFLC_DEV_SECTOR_SCALE,
|
||||
.count = SFLC_DEV_PHYS_SLICE_SIZE * SFLC_DEV_SECTOR_SCALE
|
||||
};
|
||||
|
||||
return dm_io(&io_req, 1, &io_reg, NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* PRIVATE FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
|
@ -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 *
|
||||
|
|
@ -41,18 +41,12 @@
|
|||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Checks if PSI is free */
|
||||
bool sflc_dev_isPsiFree(sflc_Device *dev, u32 psi)
|
||||
{
|
||||
return ((psi < dev->tot_slices) &&
|
||||
(dev->rmap[psi] == SFLC_DEV_RMAP_INVALID_VOL));
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Bounds check */
|
||||
if (psi >= dev->tot_slices) {
|
||||
pr_err("Requested to set ownership for invalid PSI\n");
|
||||
|
|
@ -60,7 +54,8 @@ int sflc_dev_markPsiTaken(sflc_Device * dev, u32 psi, u8 vol_idx)
|
|||
}
|
||||
|
||||
/* Check that it's free */
|
||||
if (dev->rmap[psi] != SFLC_DEV_RMAP_INVALID_VOL) {
|
||||
prev_vol_idx = dev->rmap[psi];
|
||||
if (prev_vol_idx != SFOLD_DEV_RMAP_INVALID_VOL) {
|
||||
pr_err("Requested to set ownership for already-owned PSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -74,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;
|
||||
|
||||
|
|
@ -87,15 +82,14 @@ s32 sflc_dev_getNextRandomFreePsi(sflc_Device * dev)
|
|||
/* Repeatedly advance the counter in the shuffled array
|
||||
* until you find a free one */
|
||||
do {
|
||||
if (dev->prmslices_octr >= dev->tot_slices) {
|
||||
pr_err("Double catastrophe! No free PSIs on the device, "
|
||||
"and didn't catch it before!\n");
|
||||
psi = dev->shuffled_psi_array[dev->shuffled_psi_ctr];
|
||||
dev->shuffled_psi_ctr += 1;
|
||||
|
||||
if (dev->shuffled_psi_ctr >= dev->tot_slices) {
|
||||
pr_err("Double catastrophe! No free PSIs on the device, and didn't catch it before!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
psi = dev->prmslices[dev->prmslices_octr];
|
||||
dev->prmslices_octr += 1;
|
||||
} while (dev->rmap[psi] != SFLC_DEV_RMAP_INVALID_VOL);
|
||||
} while (dev->rmap[psi] != SFOLD_DEV_RMAP_INVALID_VOL);
|
||||
|
||||
return psi;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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_ */
|
||||
87
dm-sflc/src/old/sflc_old.c
Normal file
87
dm-sflc/src/old/sflc_old.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device-mapper.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 FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Module entry point, called just once, at module-load time */
|
||||
int sfold_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sfold_rand_init();
|
||||
if (ret) {
|
||||
pr_err("Could not init rand; error %d\n", ret);
|
||||
goto err_rand_init;
|
||||
}
|
||||
|
||||
/* Init the memory pools */
|
||||
ret = sfold_pools_init();
|
||||
if (ret) {
|
||||
pr_err("Could not init memory pools; error %d\n", ret);
|
||||
goto err_pools;
|
||||
}
|
||||
|
||||
/* Init the workqueues */
|
||||
ret = sfold_queues_init();
|
||||
if (ret) {
|
||||
pr_err("Could not init workqueues; error %d\n", ret);
|
||||
goto err_queues;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
err_queues:
|
||||
sfold_pools_exit();
|
||||
err_pools:
|
||||
sfold_rand_exit();
|
||||
err_rand_init:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Module exit point, called just once, at module-unload time */
|
||||
void sfold_exit(void)
|
||||
{
|
||||
sfold_queues_exit();
|
||||
sfold_pools_exit();
|
||||
sfold_rand_exit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -20,25 +20,27 @@
|
|||
* GNU General Public License along with this program.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Methods of our DM target
|
||||
*/
|
||||
|
||||
#ifndef _SFLC_TARGET_TARGET_H_
|
||||
#define _SFLC_TARGET_TARGET_H_
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/device-mapper.h>
|
||||
|
||||
/*****************************************************
|
||||
* 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 */
|
||||
142
dm-sflc/src/old/sysfs.c
Normal file
142
dm-sflc/src/old/sysfs.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
150
dm-sflc/src/old/target.c
Normal file
150
dm-sflc/src/old/target.c
Normal file
|
|
@ -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
|
||||
* <https://www.shufflecake.net/permalinks/shufflecake-userland/AUTHORS>
|
||||
*
|
||||
* 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 <https://www.shufflecake.net>.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -31,15 +31,15 @@
|
|||
|
||||
#include <linux/string.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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,22 +39,22 @@
|
|||
*****************************************************/
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Swap v[i] and v[j] */
|
||||
u32 tmp = v[i];
|
||||
v[i] = v[j];
|
||||
v[j] = tmp;
|
||||
/* Swap v[i] and v[j] (without third 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 0;
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -29,12 +29,10 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#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 *
|
||||
|
|
@ -44,8 +42,7 @@
|
|||
* PRIVATE FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op);
|
||||
static int sflc_vol_reassignLsi(sflc_Volume *vol, u32 lsi, u32 old_psi);
|
||||
static s32 sfold_vol_mapSlice(sfold_Volume * vol, u32 lsi, int op);
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
|
|
@ -53,28 +50,28 @@ static int sflc_vol_reassignLsi(sflc_Volume *vol, u32 lsi, u32 old_psi);
|
|||
|
||||
/* 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");
|
||||
|
|
@ -91,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;
|
||||
|
|
@ -114,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;
|
||||
|
|
@ -148,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;
|
||||
|
|
@ -157,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;
|
||||
|
|
@ -167,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;
|
||||
|
|
@ -175,42 +172,22 @@ 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)));
|
||||
u32 psi = be32_to_cpu(*be_psi);
|
||||
|
||||
/* If unassigned, just move on */
|
||||
if (psi == SFLC_VOL_FMAP_INVALID_PSI) {
|
||||
vol->fmap[lsi] = psi;
|
||||
/* Next iteration */
|
||||
lsi += 1;
|
||||
continue;
|
||||
/* 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 != SFOLD_VOL_FMAP_INVALID_PSI) {
|
||||
sfold_dev_markPsiTaken(dev, psi, vol->vol_idx);
|
||||
vol->mapped_slices += 1;
|
||||
}
|
||||
|
||||
/* If already assigned to lower-order volume, sample a new one */
|
||||
if (!sflc_dev_isPsiFree(dev, psi)) {
|
||||
pr_warn("Corruption of volume %d: LSI %u was evicted from PSI %u\n",
|
||||
vol->vol_idx, lsi, psi);
|
||||
err = sflc_vol_reassignLsi(vol, lsi, psi);
|
||||
if (err) {
|
||||
pr_err("Could not reassign evicted LSI; "
|
||||
"error %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Next iteration */
|
||||
lsi += 1;
|
||||
} else {
|
||||
/* Just assign */
|
||||
vol->fmap[lsi] = psi;
|
||||
sflc_dev_markPsiTaken(dev, psi, vol->vol_idx);
|
||||
vol->mapped_slices += 1;
|
||||
|
||||
/* Next iteration */
|
||||
lsi += 1;
|
||||
}
|
||||
/* Next iteration */
|
||||
lsi += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,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;
|
||||
|
|
@ -244,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;
|
||||
|
|
@ -278,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;
|
||||
|
|
@ -293,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 */
|
||||
|
|
@ -308,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;
|
||||
|
|
@ -334,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;
|
||||
}
|
||||
|
|
@ -344,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)) {
|
||||
|
|
@ -356,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];
|
||||
}
|
||||
|
|
@ -377,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);
|
||||
|
|
@ -389,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);
|
||||
|
|
@ -397,58 +374,3 @@ static s32 sflc_vol_mapSlice(sflc_Volume * vol, u32 lsi, int op)
|
|||
|
||||
return psi;
|
||||
}
|
||||
|
||||
|
||||
static int sflc_vol_reassignLsi(sflc_Volume *vol, u32 lsi, u32 old_psi)
|
||||
{
|
||||
sflc_Device *dev = vol->dev;
|
||||
s32 new_psi;
|
||||
// void *vma;
|
||||
int err;
|
||||
|
||||
// /* Allocate array holding the raw PSI */
|
||||
// vma = vmalloc(SFLC_DEV_PHYS_SLICE_SIZE * SFLC_DEV_SECTOR_SIZE);
|
||||
// if (!vma) {
|
||||
// pr_err("Could not allocate VMA for raw PSI");
|
||||
// return -ENOMEM;
|
||||
// }
|
||||
|
||||
/* Sample new PSI */
|
||||
new_psi = sflc_dev_getNextRandomFreePsi(dev);
|
||||
if (new_psi < 0) {
|
||||
err = new_psi;
|
||||
pr_err("Could not sample new PSI for evicted LSI; "
|
||||
"error %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
// /* Read PSI contents */
|
||||
// err = sflc_dev_rwPsi(dev, vma, old_psi, READ);
|
||||
// if (err) {
|
||||
// pr_err("Could not read PSI; error %d", err);
|
||||
// goto out;
|
||||
// }
|
||||
//
|
||||
// /* Write them to new location */
|
||||
// err = sflc_dev_rwPsi(dev, vma, new_psi, WRITE);
|
||||
// if (err) {
|
||||
// pr_err("Could not write PSI; error %d", err);
|
||||
// goto out;
|
||||
// }
|
||||
|
||||
/* Assign */
|
||||
vol->fmap[lsi] = new_psi;
|
||||
sflc_dev_markPsiTaken(dev, new_psi, vol->vol_idx);
|
||||
vol->mapped_slices += 1;
|
||||
|
||||
pr_notice("Volume %d reassign LSI %u -> PSI %u",
|
||||
vol->vol_idx, lsi, new_psi);
|
||||
|
||||
/* No prob */
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
// vfree(vma);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue