mirror of
https://codeberg.org/shufflecake/shufflecake-c.git
synced 2026-01-07 03:25:26 -05:00
Merge pull request 'Shufflecake v0.5.0' (#99) from dev into main
Reviewed-on: https://codeberg.org/shufflecake/shufflecake-c/pulls/99
This commit is contained in:
commit
6e89c99904
167 changed files with 8216 additions and 3059 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/
|
||||
|
|
|
|||
98
CHANGELOG.md
98
CHANGELOG.md
|
|
@ -11,35 +11,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Refactored
|
||||
|
||||
- Introduction of "Shufflecake Lite" scheme as default.
|
||||
- Moving old Shufflescake scheme as "Legacy" option for backward support.
|
||||
- Global constants fully shared among components through `sflc_constants.h`.
|
||||
- Global refactoring and simplification of code tree.
|
||||
|
||||
|
||||
## [0.5.0] - 2024-09-01
|
||||
|
||||
### Added
|
||||
|
||||
- Benchmark and fragmentation scripts for Shufflecake Lite.
|
||||
- Schematics for new Lite headers.
|
||||
|
||||
### Changed
|
||||
|
||||
- BREAKING CHANGE: introduction of "Shufflecake Lite" scheme as default.
|
||||
- BREAKING CHANGE: moved old Shufflescake scheme as "Legacy" option for backward support.
|
||||
- Edited README.md to show the difference between the Lite and Legacy modes, and also added a usability warning.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Volumes offered by the same device now show as all related to that device with `lsblk`.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Global refactoring and simplification of code tree.
|
||||
- Changed all occurrences of "Shufflecake Old" to "Shufflecake Legacy", including code paths and variables.
|
||||
- Reordered entries in CHANGELOG.md with sections following the order Added -> Changed -> Fixed -> Refactored -> Removed.
|
||||
|
||||
## [0.4.5] - 2024-06-03
|
||||
|
||||
### Changed
|
||||
|
||||
- Minor edits to README.md.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a compile error on some new releases of LTS kernels due to the removal of a function API.
|
||||
- Fixed segmentation fault when opening an already opened device.
|
||||
|
||||
### Changed
|
||||
|
||||
- Minor edits to README.md.
|
||||
|
||||
|
||||
## [0.4.4] - 2023-12-31
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a memory allocation error on large devices due to the use of a function not meant for allocating large amount of memory.
|
||||
|
||||
### Changed
|
||||
|
||||
- Variables `shuffled_psi_array` and `shuffled_psi_ctr` renamed to `prmslices` and `prmslices_octr` respectively, to be more consistent with reference paper.
|
||||
- Minor edits to README.md.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a memory allocation error on large devices due to the use of a function not meant for allocating large amount of memory.
|
||||
|
||||
|
||||
## [0.4.3] - 2023-11-29
|
||||
|
||||
|
|
@ -51,6 +71,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [0.4.2] - 2023-11-28
|
||||
|
||||
### Changed
|
||||
|
||||
- All schematics and references now consistently map array indices of size N from 0 to N-1 rather than from 1 to N.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed persistent slice allocation ambiguity after a volume corruption by allocating fresh slices for the corrupted volume. This is done in order to help external recovery tools (e.g. RAID).
|
||||
|
|
@ -58,10 +82,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Fixed a missed deallocation problem which caused a kernel bug on volume close after some I/O errors.
|
||||
- Fixed a buggy swap procedure which made the permutation of PSIs not completely random.
|
||||
|
||||
### Changed
|
||||
|
||||
- All schematics and references now consistently map array indices of size N from 0 to N-1 rather than from 1 to N.
|
||||
|
||||
|
||||
## [0.4.1] - 2023-07-30
|
||||
|
||||
|
|
@ -80,21 +100,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Improved documentation in `README.md` on using `init` non-interactively.
|
||||
- `doc` section which for now includes figure of Shufflecake header structure.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Implemented reference slice allocation algorithm with much faster performance.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug that made `--skip-randfill` option not work.
|
||||
- Fixed a bug that made action `close` not work.
|
||||
|
||||
### Changed
|
||||
|
||||
- BREAKING CHANGE: slightly modified header field format, removing redundant MAC field and making it adherent to documentation.
|
||||
- Action `init` now reads password from secure interface (not echoing characters, etc).
|
||||
- Updated instructions in `SECURITY.md`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug that made `--skip-randfill` option not work.
|
||||
- Fixed a bug that made action `close` not work.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Implemented reference slice allocation algorithm with much faster performance.
|
||||
|
||||
|
||||
## [0.3.1] - 2023-07-15
|
||||
|
||||
|
|
@ -111,17 +131,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [0.3.0] - 2023-07-11
|
||||
|
||||
### Refactored
|
||||
|
||||
- Unified repositories of kernel module and userland tool into a single one. Makefile, docs, etc unified accordingly.
|
||||
- Adopting SemVer as of release v0.3.0.
|
||||
- Program version now defined within `sflc_constants.h`.
|
||||
- CLI built with argp.h and following GNU behavior.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Test routines available with `make install`, for now limited to low-level crypto operations.
|
||||
|
||||
### Changed
|
||||
|
||||
- License changed from GPLv3+ to GPLv2+.
|
||||
|
|
@ -130,6 +139,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- One global salt for deriving keys for all headers in order to not slow down too much opening. This allows us to avoid a difficult choice between insecurity against brute-force attacks and unacceptably slow opening time.
|
||||
- Added a 1-block offset to accommodate for header format change.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Test routines available with `make install`, for now limited to low-level crypto operations.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Unified repositories of kernel module and userland tool into a single one. Makefile, docs, etc unified accordingly.
|
||||
- Adopting SemVer as of release v0.3.0.
|
||||
- Program version now defined within `sflc_constants.h`.
|
||||
- CLI built with argp.h and following GNU behavior.
|
||||
|
||||
|
||||
## [0.2.0] - 2023-04-17
|
||||
|
||||
|
|
@ -139,10 +159,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Support larger volumes with headers of variable size.
|
||||
- Add interactive option to skip random filling during init.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Compile correctly on Linux kernel 6.1.
|
||||
|
||||
### Changed
|
||||
|
||||
- Switch from `libsodium` to `libgcrypt`.
|
||||
|
|
@ -150,6 +166,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Change syntax of commands.
|
||||
- Switch to Scrypt KDF.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Compile correctly on Linux kernel 6.1.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed flag `--no-randfill`.
|
||||
|
|
|
|||
51
README.md
51
README.md
|
|
@ -1,23 +1,24 @@
|
|||
[](https://codeberg.org/shufflecake/shufflecake-c)
|
||||
[](https://codeberg.org/shufflecake/shufflecake-c/releases/tag/v0.4.5)
|
||||
[](https://codeberg.org/shufflecake/shufflecake-c/releases/tag/v0.5.0)
|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
[](https://eprint.iacr.org/2023/1529)
|
||||
[](https://shufflecake.net/)
|
||||
[](https://codeberg.org/shufflecake/shufflecake-c/issues)
|
||||
[](https://fosstodon.org/@shufflecake)
|
||||
[](xmpp:shufflecake@conference.draugr.de?join)
|
||||
[](https://nogithub.codeberg.page)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Shufflecake - Full C Implementation - v0.4.5
|
||||
# Shufflecake - Full C Implementation - v0.5.0
|
||||
|
||||
_Shufflecake_ is a plausible deniability (hidden storage) layer for Linux. You can consider Shufflecake a spiritual successor of tools like TrueCrypt and VeraCrypt, but vastly improved, both in terms of security and functionality. Official website: <https://www.shufflecake.net>.
|
||||
|
||||
This repository contains C source code and documentation to use and manage Shufflecake volumes.
|
||||
|
||||
__WARNING__: Shufflecake is still experimental software, please do not rely on its security or stability.
|
||||
__WARNING__: Shufflecake is a strong encryption and plausible deniability solution. The mere presence of Shufflecake on your device might put you at risk of being targeted, accused of crime or foul play, arrested, or worse. In Shufflecake there is no easy way to convince an adversary that you have given up all your passwords. Please consider carefully your threat model before using Shufflecake. In any case, this is still experimental software, please do not rely on its security or stability.
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Installation](#installation)
|
||||
|
|
@ -30,6 +31,9 @@ __WARNING__: Shufflecake is still experimental software, please do not rely on i
|
|||
- [Other Commands](#other)
|
||||
- [Changing A Password](#changepwd)
|
||||
- [Check If A Password Is Correct](#testpwd)
|
||||
- [Modes of Operation](#modes)
|
||||
- [Shufflecake Lite](#lite)
|
||||
- [Shufflecake Legacy](#legacy)
|
||||
- [Advanced Usage](#advanced)
|
||||
- [Volume Corruption Mitigation](#mitigcorr)
|
||||
- [Providing Passwords Non-Interactively](#passwordnonint)
|
||||
|
|
@ -47,17 +51,15 @@ __WARNING__: Shufflecake is still experimental software, please do not rely on i
|
|||
In the context of Shufflecake, a _device_, or _cake_, is the underlying raw block device (e.g., a disk) that is formatted to contain hidden data, while a _volume_, or _layer_, is the logical, encrypted and hidden "partition" within a device. The device can be a whole USB stick (or disk), a physical or logical partition, a file-backed loop device, etc. (you likely find it under `/dev`).
|
||||
|
||||
The three operating principles of Shufflecake are:
|
||||
- 1 device = multiple volumes;
|
||||
- 1 device = multiple (concurrently usable) volumes;
|
||||
- 1 volume = 1 password = 1 "secrecy level";
|
||||
- unlocking a volume also unlocks all those of lesser secrecy level.
|
||||
|
||||
Volumes are password-protected, and embedded in the underlying device as data _slices_ which are indistinguishable from random noise without the proper password. Headers are also indistinguishable from random when not decrypted. A Shufflecake-initialized device does not have cleartext headers, and is indistinguishable from random noise when not decrypted.
|
||||
|
||||
Up to 15 _ordered_ Shufflecake volumes can be created on a single device, with the implicit assumption that "lower-order" volumes (e.g. layer 0) are _less_ _secret_ than "higher-order" ones (e.g. layer 3). The Shufflecake header is designed in such a way that it _chains_ volumes in a backwards-linked list: volume __i__ "points to" (contains the key of) volume __i-1__. This way, providing the key of volume __i__ allows this tool to traverse the list and also automatically open volumes __0__ through __i-1__ (besides volume __i__).
|
||||
Up to 15 _ordered_ Shufflecake volumes can be created on a single device, with the implicit assumption that "lower-order" volumes (e.g. layer 0) are _less_ _secret_ than "higher-order" ones (e.g. layer 3). Shufflecake is designed in such a way that it _chains_ volumes in a backwards-linked list: volume __i__ "points to" (contains the key of) volume __i-1__. This way, providing the key of volume __i__ allows this tool to traverse the list and also automatically open volumes __0__ through __i-1__ (besides volume __i__).
|
||||
|
||||

|
||||
|
||||
Opened volumes appear as block devices of the form `sflc_x_y` in `/dev/mapper`. It is up to the user to format them with an appropriate filesystem and mounting them before use. It is recommended to always unlock the most sensitive volume for daily use ("home alone" scenario), even if that volume is not being used or even mounted. Only open a subset of volumes (with a "decoy password") if under coercion. This is due to the high possibility of corrupting hidden volumes otherwise.
|
||||
Opened volumes appear as block devices of the form `sflc_x_y` in `/dev/mapper` and they can be used concurrently. It is up to the user to format them with an appropriate filesystem and mounting them before use. It is recommended to always unlock the most sensitive volume for daily use ("home alone" scenario), even if that volume is not being used or even mounted. Only open a subset of volumes (with a "decoy password") if under coercion. This is due to the high possibility of corrupting hidden volumes otherwise.
|
||||
|
||||
For security and consistency reasons, you cannot init/open/close nested volumes within the same device one at a time; this tool only allows to perform these operations on a _chain_ of volumes in a device.
|
||||
|
||||
|
|
@ -67,7 +69,7 @@ For security and consistency reasons, you cannot init/open/close nested volumes
|
|||
|
||||
## Installation <a id="user-content-installation"></a>
|
||||
|
||||
This implementation of Shufflecake consists of two components: a module for the Linux kernel (`dm-sflc`), and a `shufflecake` userland tool. Both are necessary in order to use Shufflecake. They have been tested on Linux kernel versions 6.1 (LTS), up to 6.7. The following instructions are given for Debian/Ubuntu and similar derivatives.
|
||||
This implementation of Shufflecake consists of two components: a module for the Linux kernel (`dm-sflc`), and a `shufflecake` userland tool. Both are necessary in order to use Shufflecake. They have been tested on Linux kernel versions 6.1 (LTS), up to 6.10. The following instructions are given for Debian/Ubuntu and similar derivatives.
|
||||
|
||||
First of all, you need the kernel headers, device-mapper userspace library, and libgcrypt to compile the source. Use:
|
||||
|
||||
|
|
@ -75,10 +77,10 @@ First of all, you need the kernel headers, device-mapper userspace library, and
|
|||
sudo apt install linux-headers-$(uname -r) libdevmapper-dev libgcrypt-dev
|
||||
```
|
||||
|
||||
Important: you have to make sure to install an up-to-date version of `libgcrypt` that supports the Argon2id KDF algorithm. You need the 1.10.1 or later version, which might not be available in your local repositories (for example, Ubuntu 22.04 LTS), in which case you should find a workaround (either install manually or override your repositories by pinning an up-to-date package). You can check your current version with:
|
||||
Important: you have to make sure to install an up-to-date version of `libgcrypt` that supports the Argon2id KDF algorithm. You need the 1.10.1 or later version, which might not be available in your local repositories (for example, Ubuntu 22.04 LTS), in which case you should find a workaround (either install manually or override your repositories by pinning an up-to-date package). You can check your current version (on Debian/Ubuntu) with:
|
||||
|
||||
```
|
||||
libgcrypt-config --version
|
||||
dpkg -l libgcrypt20
|
||||
```
|
||||
Also, make sure that the Kconfig options `CONFIG_CRYPTO_DRBG_HASH` (and possibly `CONFIG_CRYPTO_DRBG_CTR`) are enabled, as they are not default options in the kernel's defconfig, although they are enabled by default on some distributions such as Debian and Ubuntu.
|
||||
|
||||
|
|
@ -193,6 +195,23 @@ sudo shufflecake testpwd <block_device>
|
|||
A password will be required. If this is the correct password for volume __M__, then this information will be returned to the user, without actually opening the volume. This can be useful if a user wants to be sure that a password unlocks a certain volume without risk of the OS logging the access to that volume and without the risk of corrupting the content of other, unlocked, hidden volumes.
|
||||
|
||||
|
||||
### Modes of Operation <a id="user-content-modes"></a>
|
||||
|
||||
Shufflecake can operate in two different modes, with different features in terms of security, performance, and data resilience.
|
||||
|
||||
#### Shufflecake Lite <a id="user-content-lite"></a>
|
||||
|
||||
As of v0.5.0, Shufflecake's default mode of operation is the "Lite" scheme. This mode introduces the AES-XTS encryption mode rather than AES-CTR, with a related change of header format. This mode has only advantages compared to the old "Legacy" scheme: it offers the _same_ level of security, but with better performance and data resilience, and it is therefore the strongly recommended way to use Shufflecake. It will be used by default whenever a Shufflecake command is invoked.
|
||||
|
||||

|
||||
|
||||
#### Shufflecake Legacy <a id="user-content-legacy"></a>
|
||||
|
||||
For backward compatibility reasons, this release of Shufflecake still offers support for the old (pre-v0.5.x) "Legacy" scheme, which can be selected with the `--legacy` option when invoking `init` or `open`, all other actions (including `close`) do not require specifying a Shufflecake mode. This scheme uses AES-CTR with explicit IVs written on disks, and it offers therefore ciphertext re-randomization, which is in turn a necessary ingredient for achieving future modes with better security. However, since these modes have not yet been implemented, currently the use of Shufflecake Legacy has only drawbacks compared to other modes: it does not offer better security, while being slower, less space-efficient, and more prone to data corruption. The use of this mode is therefore discouraged, and will be deprecated at some point in the future. However, you must use this option when trying to open volumes created with an old (pre-v0.5.x) release of Shufflecake. You are strongly encouraged to migrate Legacy volumes to the new Lite ones if you haven't done it yet.
|
||||
|
||||

|
||||
|
||||
|
||||
### Advanced Usage <a id="user-content-advanced"></a>
|
||||
|
||||
Certain features of Shufflecake are not yet implemented, but sometimes a workaround is possible. Consider all the instructions in this sections as experimental, use them at your own risk.
|
||||
|
|
@ -246,6 +265,10 @@ Both methods works with the `init` action, and we do not have current plans to c
|
|||
|
||||
Please see the file `CHANGELOG.md` for a detailed history of changes.
|
||||
|
||||
### [0.5.0] - 2024-09-01
|
||||
|
||||
- BREAKING CHANGE: major rewrite, bugfixes, introduced Shufflecake "Lite" as a default mode of operation.
|
||||
|
||||
### [0.4.5] - 2024-06-03
|
||||
|
||||
- Fixed a compile error on some versions of LTS kernels.
|
||||
|
|
@ -289,9 +312,9 @@ Bugs and other issues are tracked at <https://codeberg.org/shufflecake/shuffleca
|
|||
|
||||
Outstanding known bugs and/or limitations:
|
||||
|
||||
- There is no crash consistency implemented, so if a crash happens while some volumes are live there is the risk of data loss.
|
||||
- There is no garbage collection currently implemented, so slices remain flagged as used even if the data therein is deleted.
|
||||
- There is (currently) no protection against multi-snapshot attacks (like in TrueCrypt/VeraCrypt).
|
||||
- Only a maximum of 15 volumes per device is supported.
|
||||
- I/O performance of Shufflecake Lite is slowed down by a missing optimization of the flush method.
|
||||
- There is (currently) no protection against multi-snapshot attacks.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
389
benchmark-suite/sflc-legacy-benchmark.sh
Executable file
389
benchmark-suite/sflc-legacy-benchmark.sh
Executable file
|
|
@ -0,0 +1,389 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 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-c/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/>.
|
||||
|
||||
# Benchmarking script for Shufflecake
|
||||
|
||||
# Variables
|
||||
SCRIPTNAME=$(basename "$0")
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
LOOP_FILENAME="$SCRIPT_DIR/sflc-legacy-benchmark-loop-file.img"
|
||||
LOOP_DEVICE=""
|
||||
TIMEFORMAT='%3R'
|
||||
SFLCPATH=""
|
||||
SFLCNAME=""
|
||||
DMSFLC_INSTALLED=false
|
||||
|
||||
# Colors
|
||||
BLUE='\033[0;34m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No color
|
||||
|
||||
# Help
|
||||
print_help() {
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]${NC}"
|
||||
echo " "
|
||||
echo "This script is used to benchmark Shufflecake Legacy on this machine."
|
||||
echo "This script is part of the Shufflecake benchmark suite."
|
||||
echo "Shufflecake is a plausible deniability (hidden storage) layer for Linux."
|
||||
echo -e "Please visit ${BLUE}https://www.shufflecake.net${NC} for more info and documentation."
|
||||
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:"
|
||||
echo "1) Creates a Shufflecake (Legacy) device with two volumes."
|
||||
echo "2) Opens the second (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 must have already compiled and installed Shufflecake in order to run this."
|
||||
echo "The script will search for Shufflecake either in the default installation "
|
||||
echo "directory, or in the current directory, or in the parent directory (one level"
|
||||
echo -e "above this). If the module ${BLUE}dm-sflc${NC} is not loaded, the script "
|
||||
echo "will load it, execute, and then unload it."
|
||||
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 -e "${BLUE}WARNING: ALL CONTENT OF THE PROVIDED BLOCK DEVICE WILL BE ERASED!${NC}"
|
||||
echo " "
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Function for debugging
|
||||
bpx() {
|
||||
if [ -z "$1" ]; then
|
||||
echo "BPX: Paused. Press any key to continue..." >&2
|
||||
else
|
||||
echo "BPX: $1. Press any key to continue..." >&2
|
||||
fi
|
||||
read -n1 -s
|
||||
}
|
||||
|
||||
# Show usage
|
||||
usage() {
|
||||
echo -e "Use ${BLUE}${SCRIPTNAME} --help${NC} for usage and help."
|
||||
}
|
||||
|
||||
# Check that this is run as root
|
||||
check_sudo() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}Error: This script must be run as root.${NC}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Find the path of Shufflecake executable
|
||||
find_sflc_path() {
|
||||
local cmd="shufflecake"
|
||||
|
||||
# Check if the command exists in the current directory
|
||||
if [[ -x "./$cmd" ]]; then
|
||||
SFLCPATH=$(realpath ./)
|
||||
SFLCNAME=$(realpath ./$cmd)
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if the command exists in the parent directory
|
||||
if [[ -x "../$cmd" ]]; then
|
||||
SFLCPATH=$(realpath ../)
|
||||
SFLCNAME=$(realpath ../$cmd)
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if the command exists in the directories listed in PATH
|
||||
IFS=':' read -ra dirs <<< "$PATH"
|
||||
for dir in "${dirs[@]}"; do
|
||||
if [[ -x "$dir/$cmd" ]]; then
|
||||
SFLCPATH=$(realpath $dir)
|
||||
SFLCNAME=$(realpath $dir/$cmd)
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# If the command was not found, print an error message
|
||||
echo -e "${RED}ERROR: Command '$cmd' not found${NC}." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Find and load module dm-sflc
|
||||
load_dmsflc() {
|
||||
local mod="dm-sflc"
|
||||
|
||||
# Check if the module is already loaded
|
||||
if lsmod | grep -q "^$mod "; then
|
||||
DMSFLC_INSTALLED=true
|
||||
echo "Module '$mod' is already loaded."
|
||||
return
|
||||
fi
|
||||
|
||||
# If not, look for the module file and try to load it
|
||||
local mod_file="$mod.ko"
|
||||
|
||||
# Check if the module file exists in the current directory
|
||||
if [[ -f "./$mod_file" ]]; then
|
||||
insmod $(realpath ./$mod_file) || exit 1
|
||||
echo "Module '$mod' loaded from current directory."
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if the module file exists in the parent directory
|
||||
if [[ -f "../$mod_file" ]]; then
|
||||
insmod $(realpath ../$mod_file) || exit 1
|
||||
echo "Module '$mod' loaded from parent directory."
|
||||
return
|
||||
fi
|
||||
|
||||
# If the module file was not found, print an error message
|
||||
echo -e "${RED} ERROR: Module file '$mod_file' not found.${NC}." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Unload dm-sflc if it was loaded locally
|
||||
unload_dmsflc() {
|
||||
local mod="dm-sflc"
|
||||
# Only unload dm-sflc if it was loaded manually when the script was invoked
|
||||
if ! $DMSFLC_INSTALLED; then
|
||||
rmmod $mod || exit 1
|
||||
echo "Module '$mod' unloaded."
|
||||
else
|
||||
echo "Module '$mod' was not unloaded because it was already loaded when the script was run."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if argument is a block device
|
||||
check_block_device() {
|
||||
if [ -b "$1" ]; then
|
||||
echo "OK, block device path $1 is valid." >&2
|
||||
else
|
||||
echo -e "${RED}Error: $1 is not a valid block device, aborting.${NC}"
|
||||
unload_dmsflc
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 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"
|
||||
}
|
||||
|
||||
# Finds the sflc volume that was created last
|
||||
find_sflcvolname() {
|
||||
# List all files in /dev/mapper, select those starting with sflc_, sort them, and pick the last one.
|
||||
volname=$(ls /dev/mapper/sflc_* 2>/dev/null | sort -t '_' -k 2n,2 -k 3n,3 | tail -n 1)
|
||||
# Check if volname is empty (no sflc_ files found).
|
||||
if [ -z "$volname" ]; then
|
||||
echo -e "${RED}ERROR: No sflc_ devices found in /dev/mapper !${NC}"
|
||||
return 1
|
||||
else
|
||||
echo $volname
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function for user confirmation
|
||||
confirm() {
|
||||
while true; do
|
||||
echo -e "${BLUE}Are you sure you want to proceed? All data on disk $BLOCK_DEVICE will be erased. (y/n)${NC}"
|
||||
read -r response
|
||||
case "$response" in
|
||||
[yY]|[yY][eE][sS]) # Responded Yes
|
||||
return 0 # Return 0 for Yes (success, convention for bash scripting)
|
||||
;;
|
||||
[nN]|[nN][oO]) # Responded No
|
||||
return 1 # Return 1 for No (error, convention for bash scripting)
|
||||
;;
|
||||
*) # Responded something else
|
||||
echo "Please press only (y)es or (n)o."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Benchmarks
|
||||
benchmark() {
|
||||
|
||||
SFLCVOLUME=""
|
||||
MNTPOINT=""
|
||||
TESTNAME="sflc-lgc"
|
||||
RUNTIME="20" # running time in seconds FOR EACH TEST
|
||||
DATASIZE="500M"
|
||||
TESTFILENAME="testfile"
|
||||
echo "Starting benchmark for Shufflecake Legacy..."
|
||||
echo "Initializing block device $BLOCK_DEVICE with two Shufflecake Legacy volumes (--skip-randfill)..."
|
||||
etime=$( (time echo -e "passwd1\npasswd2" | $SFLCNAME --skip-randfill --legacy -n 2 init $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action init took $etime seconds.${NC}"
|
||||
echo "Shufflecake device initialized. Opening hidden volume (nr. 2)..."
|
||||
# open
|
||||
etime=$( (time echo -e "passwd2" | $SFLCNAME --legacy open $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action open took $etime seconds.${NC}"
|
||||
# fetch SFLCVOLUME
|
||||
SFLCVOLUME=$(find_sflcvolname)
|
||||
echo "Shufflecake Legacy volume opened as $SFLCVOLUME. Formatting with ext4..."
|
||||
# format with ext4, but mute output (too verbose)
|
||||
mkfs.ext4 $SFLCVOLUME > /dev/null
|
||||
echo "Volume $SFLCVOLUME formatted. Mounting that..."
|
||||
# assign and create MNTPOINT
|
||||
MNTPOINT=$(realpath "./sflc_mnt")
|
||||
mkdir $MNTPOINT
|
||||
# mount
|
||||
mount $SFLCVOLUME $MNTPOINT
|
||||
echo "Volume mounted at $MNTPOINT. Starting fio tests..."
|
||||
# TESTS HERE
|
||||
# test 01: random read
|
||||
echo "Test 01: random read with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..."
|
||||
OUTPUT=$(fio --name=$TESTNAME-r-rnd --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, read_iops: .read.iops, read_bw: .read.bw}')
|
||||
echo -e "${GREEN}${OUTPUT}${NC}"
|
||||
# test 02: random write
|
||||
echo "Test 02: random write with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..."
|
||||
OUTPUT=$(fio --name=$TESTNAME-w-rnd --ioengine=libaio --iodepth=32 --rw=randwrite --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}')
|
||||
echo -e "${GREEN}${OUTPUT}${NC}"
|
||||
# test 03: sequential read
|
||||
echo "Test 03: sequential read with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..."
|
||||
OUTPUT=$(fio --name=$TESTNAME-r-seq --ioengine=libaio --iodepth=32 --rw=read --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, read_iops: .read.iops, read_bw: .read.bw}')
|
||||
echo -e "${GREEN}${OUTPUT}${NC}"
|
||||
# test 04: sequential write
|
||||
echo "Test 04: sequential write with a queue of 32 4kiB blocks on a file (${RUNTIME}s)..."
|
||||
OUTPUT=$(fio --name=$TESTNAME-w-seq --ioengine=libaio --iodepth=32 --rw=write --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}')
|
||||
echo -e "${GREEN}${OUTPUT}${NC}"
|
||||
# END TESTS
|
||||
echo "Shufflecake Legacy fio tests ended. Unmounting volume."
|
||||
# unmount
|
||||
umount $MNTPOINT
|
||||
rmdir $MNTPOINT
|
||||
echo "Volume unmounted. Closing Shufflecake device..."
|
||||
# close
|
||||
etime=$( (time $SFLCNAME close $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action close took $etime seconds.${NC}"
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
# Clean up
|
||||
cleanup() {
|
||||
echo "Exiting and cleaning..."
|
||||
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."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#####################################################################
|
||||
|
||||
# MAIN SCRIPT BODY STARTS HERE
|
||||
|
||||
#####################################################################
|
||||
|
||||
# BANNER
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
echo -e "${BLUE} Benchmark Suite Script for Shufflecake Legacy${NC}"
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
|
||||
|
||||
# PRELIMINARY: PARSE HELP, SUDO, AND LOAD SHUFFLECAKE (IF IT EXISTS, OTHERWISE ERROR)
|
||||
|
||||
case "$1" in
|
||||
# help
|
||||
--help|-?)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
check_sudo
|
||||
|
||||
echo -e "${BLUE}Initializing Shufflecake...${NC}"
|
||||
echo "Searching Shufflecake executable..."
|
||||
find_sflc_path
|
||||
echo "Shufflecake executable found at $SFLCNAME ."
|
||||
echo "Searching and loading dm-sflc module..."
|
||||
load_dmsflc
|
||||
echo "Module dm-sflc found and loaded. Status DMSFLC_INSTALLED: $DMSFLC_INSTALLED ."
|
||||
echo " "
|
||||
|
||||
|
||||
# PARSER
|
||||
|
||||
case "$1" in
|
||||
"")
|
||||
# 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 "
|
||||
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
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
# argument passed
|
||||
*)
|
||||
BLOCK_DEVICE="$1"
|
||||
;;
|
||||
esac
|
||||
|
||||
check_block_device "$BLOCK_DEVICE"
|
||||
|
||||
# MAIN PROGRAM
|
||||
|
||||
if confirm; then
|
||||
benchmark
|
||||
else
|
||||
echo "Aborting..."
|
||||
fi
|
||||
|
||||
unload_dmsflc
|
||||
|
||||
cleanup
|
||||
|
||||
|
||||
|
||||
|
||||
457
benchmark-suite/sflc-legacy-fragmentation.sh
Executable file
457
benchmark-suite/sflc-legacy-fragmentation.sh
Executable file
|
|
@ -0,0 +1,457 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 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-c/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/>.
|
||||
|
||||
# Fragmentation evaluation script for Shufflecake
|
||||
|
||||
# Global variables
|
||||
SCRIPTNAME=$(basename "$0")
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
LOOP_FILENAME="$SCRIPT_DIR/sflc-legacy-frag-loop-file.img"
|
||||
LOOP_DEVICE=""
|
||||
TIMEFORMAT='%3R'
|
||||
SFLCPATH=""
|
||||
SFLCNAME=""
|
||||
DMSFLC_INSTALLED=false
|
||||
VOLSIZE=0
|
||||
NUMPOINTS=11 # number of samples, max 65536
|
||||
FSTYPE="ext4" # fragmentation performance can depend on FS type in theory, so change it here if you want to test others
|
||||
|
||||
|
||||
# Colors
|
||||
BLUE='\033[0;34m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No color
|
||||
|
||||
# Help
|
||||
print_help() {
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]${NC}"
|
||||
echo " "
|
||||
echo "This script is used to evaluate Shufflecake Legacy volume fragmentation."
|
||||
echo "This script is part of the Shufflecake benchmark suite."
|
||||
echo "Shufflecake is a plausible deniability (hidden storage) layer for Linux."
|
||||
echo -e "Please visit ${BLUE}https://www.shufflecake.net${NC} for more info and documentation."
|
||||
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:"
|
||||
echo "1) Creates a Shufflecake Legacy device with two volumes."
|
||||
echo "2) Opens the second (hidden) volume, formats it with $FSTYPE and mounts it."
|
||||
echo "3) Performs incremental random write up to filling the space."
|
||||
echo "4) After every write round, checks fragmentation status and reports it."
|
||||
echo "5) Unmounts and closes the used volume."
|
||||
echo " "
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo "You must have already compiled and installed Shufflecake in order to run this."
|
||||
echo "The script will search for Shufflecake either in the default installation "
|
||||
echo "directory, or in the current directory, or in the parent directory (one level"
|
||||
echo -e "above this). If the module ${BLUE}dm-sflc${NC} is not loaded, the script "
|
||||
echo "will load it, execute, and then unload it."
|
||||
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 -e "${BLUE}WARNING: ALL CONTENT OF THE PROVIDED BLOCK DEVICE WILL BE ERASED!${NC}"
|
||||
echo " "
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Function for debugging
|
||||
bpx() {
|
||||
if [ -z "$1" ]; then
|
||||
echo "BPX: Paused. Press any key to continue..." >&2
|
||||
else
|
||||
echo -e "BPX: $1. Press any key to continue..." >&2
|
||||
fi
|
||||
read -n1 -s
|
||||
}
|
||||
|
||||
# Show usage
|
||||
usage() {
|
||||
echo -e "Use ${BLUE}${SCRIPTNAME} --help${NC} for usage and help."
|
||||
}
|
||||
|
||||
# Check that this is run as root
|
||||
check_sudo() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}Error: This script must be run as root.${NC}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Find the path of Shufflecake executable
|
||||
find_sflc_path() {
|
||||
local cmd="shufflecake"
|
||||
|
||||
# Check if the command exists in the current directory
|
||||
if [[ -x "./$cmd" ]]; then
|
||||
SFLCPATH=$(realpath ./)
|
||||
SFLCNAME=$(realpath ./$cmd)
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if the command exists in the parent directory
|
||||
if [[ -x "../$cmd" ]]; then
|
||||
SFLCPATH=$(realpath ../)
|
||||
SFLCNAME=$(realpath ../$cmd)
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if the command exists in the directories listed in PATH
|
||||
IFS=':' read -ra dirs <<< "$PATH"
|
||||
for dir in "${dirs[@]}"; do
|
||||
if [[ -x "$dir/$cmd" ]]; then
|
||||
SFLCPATH=$(realpath $dir)
|
||||
SFLCNAME=$(realpath $dir/$cmd)
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# If the command was not found, print an error message
|
||||
echo -e "${RED}ERROR: Command '$cmd' not found${NC}." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Find and load module dm-sflc
|
||||
load_dmsflc() {
|
||||
local mod="dm-sflc"
|
||||
|
||||
# Check if the module is already loaded
|
||||
if lsmod | grep -q "^$mod "; then
|
||||
DMSFLC_INSTALLED=true
|
||||
echo "Module '$mod' is already loaded."
|
||||
return
|
||||
fi
|
||||
|
||||
# If not, look for the module file and try to load it
|
||||
local mod_file="$mod.ko"
|
||||
|
||||
# Check if the module file exists in the current directory
|
||||
if [[ -f "./$mod_file" ]]; then
|
||||
insmod $(realpath ./$mod_file) || exit 1
|
||||
echo "Module '$mod' loaded from current directory."
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if the module file exists in the parent directory
|
||||
if [[ -f "../$mod_file" ]]; then
|
||||
insmod $(realpath ../$mod_file) || exit 1
|
||||
echo "Module '$mod' loaded from parent directory."
|
||||
return
|
||||
fi
|
||||
|
||||
# If the module file was not found, print an error message
|
||||
echo -e "${RED} ERROR: Module file '$mod_file' not found.${NC}." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Unload dm-sflc if it was loaded locally
|
||||
unload_dmsflc() {
|
||||
local mod="dm-sflc"
|
||||
# Only unload dm-sflc if it was loaded manually when the script was invoked
|
||||
if ! $DMSFLC_INSTALLED; then
|
||||
rmmod $mod || exit 1
|
||||
echo "Module '$mod' unloaded."
|
||||
else
|
||||
echo "Module '$mod' was not unloaded because it was already loaded when the script was run."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if argument is a block device
|
||||
check_block_device() {
|
||||
if [ -b "$1" ]; then
|
||||
echo "OK, block device path $1 is valid." >&2
|
||||
else
|
||||
echo -e "${RED}Error: $1 is not a valid block device, aborting.${NC}"
|
||||
unload_dmsflc
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 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"
|
||||
}
|
||||
|
||||
# Finds the sflc volume that was created last
|
||||
find_sflcvolname() {
|
||||
# List all files in /dev/mapper, select those starting with sflc_, sort them, and pick the last one.
|
||||
volname=$(ls /dev/mapper/sflc_* 2>/dev/null | sort -t '_' -k 2n,2 -k 3n,3 | tail -n 1)
|
||||
# Check if volname is empty (no sflc_ files found).
|
||||
if [ -z "$volname" ]; then
|
||||
echo -e "${RED}ERROR: No sflc_ devices found in /dev/mapper !${NC}"
|
||||
return 1
|
||||
else
|
||||
echo $volname
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function for user confirmation
|
||||
confirm() {
|
||||
while true; do
|
||||
echo -e "${BLUE}Are you sure you want to proceed? All data on disk $BLOCK_DEVICE will be erased. (y/n)${NC}"
|
||||
read -r response
|
||||
case "$response" in
|
||||
[yY]|[yY][eE][sS]) # Responded Yes
|
||||
return 0 # Return 0 for Yes (success, convention for bash scripting)
|
||||
;;
|
||||
[nN]|[nN][oO]) # Responded No
|
||||
return 1 # Return 1 for No (error, convention for bash scripting)
|
||||
;;
|
||||
*) # Responded something else
|
||||
echo "Please press only (y)es or (n)o."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Benchmarks
|
||||
benchmark() {
|
||||
|
||||
SFLCVOLUME=""
|
||||
VOLNAME=""
|
||||
MNTPOINT=""
|
||||
NUMPOINTS=21 # number of graph points
|
||||
VOLSIZE=$(blockdev --getsize64 "$BLOCK_DEVICE") # first approximation, in bytes
|
||||
|
||||
echo "Starting fragmentation test for Shufflecake Legacy..."
|
||||
# init
|
||||
echo "Initializing block device $BLOCK_DEVICE with two Shufflecake Legacy volumes (--skip-randfill)..."
|
||||
etime=$( (time echo -e "passwd1\npasswd2" | $SFLCNAME --skip-randfill --legacy -n 2 init $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action init took $etime seconds.${NC}"
|
||||
echo "Shufflecake Legacy device initialized. Opening hidden volume (nr. 2)..."
|
||||
# open
|
||||
etime=$( (time echo -e "passwd2" | $SFLCNAME --legacy open $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action open took $etime seconds.${NC}"
|
||||
# fetch SFLCVOLUME
|
||||
SFLCVOLUME=$(find_sflcvolname)
|
||||
# trim path of SFLCVOLUME
|
||||
VOLNAME=${SFLCVOLUME##*/}
|
||||
echo "Shufflecake volume opened as $VOLNAME. Formatting with $FSTYPE..."
|
||||
# format with FSTYPE, but mute output (too verbose)
|
||||
mkfs.$FSTYPE $SFLCVOLUME > /dev/null
|
||||
echo "Volume $SFLCVOLUME formatted. Mounting that..."
|
||||
# assign and create MNTPOINT
|
||||
MNTPOINT=$(realpath "./sflc_mnt")
|
||||
mkdir $MNTPOINT
|
||||
# mount
|
||||
mount $SFLCVOLUME $MNTPOINT
|
||||
echo "Volume mounted at $MNTPOINT. Starting fragmentation test..."
|
||||
# TESTS HERE
|
||||
|
||||
# Fragmentation test
|
||||
# Shufflecake allocates data on disk by lazily allocating "slices", and then writing data on those slices.
|
||||
# If no suitable slice is available for writing data, a new one is allocated.
|
||||
# The number of allocated slices for a volume is tracked into /sys/devices/sflc/${VOLNAME}/mapped_slices
|
||||
# At this point the volume is already formatted as FSTYPE and mounted at MNTPOINT
|
||||
# sanity check: NUMPOINTS must be at least 1 and at most 65536, otherwise exit 1
|
||||
if [ $NUMPOINTS -lt 1 ] || [ $NUMPOINTS -gt 65536 ]; then
|
||||
echo -e "${RED}Error: NUMPOINTS must be between 1 and 65536. Aborting...${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# read number of total available slices (round down) from /sys/module/dm_sflc/bdevs/SFLCDEVICENAME/tot_slices
|
||||
MOST_RECENT_DIR=$(ls -td /sys/module/dm_sflc/bdevs/*/ | head -n 1) # include final slash /
|
||||
read -r TOTSLICES < ${MOST_RECENT_DIR}tot_slices
|
||||
|
||||
# refine down block device max size according to available slices, to make sure there is no overflow
|
||||
NEWUPPERBOUND=$((TOTSLICES * 1048576 )) # in bytes
|
||||
if ((VOLSIZE > NEWUPPERBOUND)); then
|
||||
VOLSIZE=$NEWUPPERBOUND
|
||||
fi
|
||||
|
||||
# manage case NUMPOINTS = 1
|
||||
read -r OCCSLICES < /sys/devices/sflc/${VOLNAME}/mapped_slices
|
||||
X_COORD=.0
|
||||
Y_COORD=$(echo "scale=3; $OCCSLICES/$TOTSLICES" | bc)
|
||||
|
||||
# Print occupation table for graph
|
||||
echo -e "${GREEN}Occupation table: X = percentage of data written, Y = percentage of slices used.${NC}"
|
||||
echo -e "${GREEN}---------------------------------${NC}"
|
||||
|
||||
echo -e "${GREEN}$X_COORD $Y_COORD${NC}"
|
||||
|
||||
if [ $NUMPOINTS -gt 1 ]; then
|
||||
# point 1 is always at X=0 and point NUMPOINT is always at X=1
|
||||
DATASIZE=$(( $VOLSIZE / ($NUMPOINTS-1) / 1048576 )) # data increments in MB, round down
|
||||
|
||||
# loop for i = 1 to NUMPOINTS
|
||||
for (( i=1; i<$NUMPOINTS-1; i++ )); do
|
||||
X_COORD=$(echo "scale=3; $i / ($NUMPOINTS-1) " | bc)
|
||||
# RNDDIRNAME = random name with 16 characters (loop while it does not exist already)
|
||||
while :; do
|
||||
RNDDIRNAME=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 16 | head -n 1)
|
||||
[ ! -e "${MNTPOINT}/${RNDDIRNAME}" ] && break
|
||||
done
|
||||
# create random dir
|
||||
mkdir "${MNTPOINT}/${RNDDIRNAME}"
|
||||
|
||||
# RNDFILENAME= random name with 16 characters (loop while it does not exist already)
|
||||
while :; do
|
||||
RNDFILENAME=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 16 | head -n 1)
|
||||
[ ! -e "${MNTPOINT}/${RNDDIRNAME}/${RNDFILENAME}" ] && break
|
||||
done
|
||||
|
||||
# create random file
|
||||
dd if=/dev/zero of=${MNTPOINT}/${RNDDIRNAME}/${RNDFILENAME} bs=1M count=$DATASIZE >/dev/null 2>&1
|
||||
sync
|
||||
|
||||
# compute slice occupation threshold
|
||||
read -r OCCSLICES < /sys/devices/sflc/${VOLNAME}/mapped_slices
|
||||
Y_COORD=$(echo "scale=3; $OCCSLICES / $TOTSLICES" | bc)
|
||||
# sanity check i.e. Y_COORD is between 0 and 1
|
||||
if (( $(echo "$Y_COORD < 0" | bc -l) )) || (( $(echo "$Y_COORD > 1" | bc -l) )); then
|
||||
echo "Error: Y_COORD is not between 0 and 1"
|
||||
exit 1
|
||||
fi
|
||||
# print point coords
|
||||
echo -e "${GREEN}$X_COORD $Y_COORD${NC}"
|
||||
done
|
||||
# manually print last point to avoid rounding error artifacts at the last write
|
||||
echo -e "${GREEN}1.0 1.0${NC}"
|
||||
|
||||
fi
|
||||
# end table
|
||||
echo -e "${GREEN}---------------------------------${NC}"
|
||||
|
||||
# END TESTS
|
||||
echo "Shufflecake Legacy fragmentation test ended. Unmounting volume."
|
||||
# unmount
|
||||
umount $MNTPOINT
|
||||
rmdir $MNTPOINT
|
||||
echo "Volume unmounted. Closing Shufflecake device..."
|
||||
# close
|
||||
etime=$( (time $SFLCNAME close $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action close took $etime seconds.${NC}"
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
# Clean up
|
||||
cleanup() {
|
||||
echo "Exiting and cleaning..."
|
||||
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."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#####################################################################
|
||||
|
||||
# MAIN SCRIPT BODY STARTS HERE
|
||||
|
||||
#####################################################################
|
||||
|
||||
# BANNER
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
echo -e "${BLUE} Evaluation Script for Shufflecake Legacy Volume Fragmentation${NC}"
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
|
||||
|
||||
# PRELIMINARY: PARSE HELP, SUDO, AND LOAD SHUFFLECAKE (IF IT EXISTS, OTHERWISE ERROR)
|
||||
|
||||
case "$1" in
|
||||
# help
|
||||
--help|-?)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
check_sudo
|
||||
|
||||
echo -e "${BLUE}Initializing Shufflecake...${NC}"
|
||||
echo "Searching Shufflecake executable..."
|
||||
find_sflc_path
|
||||
echo "Shufflecake executable found at $SFLCNAME ."
|
||||
echo "Searching and loading dm-sflc module..."
|
||||
load_dmsflc
|
||||
echo "Module dm-sflc found and loaded. Status DMSFLC_INSTALLED: $DMSFLC_INSTALLED ."
|
||||
echo " "
|
||||
|
||||
|
||||
# PARSER
|
||||
|
||||
case "$1" in
|
||||
"")
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
|
||||
echo "Now you will be asked to enter the path for a block device to be used for the "
|
||||
echo "evaluation (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 "
|
||||
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
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
# argument passed
|
||||
*)
|
||||
BLOCK_DEVICE="$1"
|
||||
;;
|
||||
esac
|
||||
|
||||
check_block_device "$BLOCK_DEVICE"
|
||||
|
||||
# MAIN PROGRAM
|
||||
|
||||
if confirm; then
|
||||
benchmark
|
||||
else
|
||||
echo "Aborting..."
|
||||
fi
|
||||
|
||||
unload_dmsflc
|
||||
|
||||
cleanup
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
# Variables
|
||||
SCRIPTNAME=$(basename "$0")
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
LOOP_FILENAME="$SCRIPT_DIR/sflc-benchmark-loop-file.img"
|
||||
LOOP_FILENAME="$SCRIPT_DIR/sflc-lite-benchmark-loop-file.img"
|
||||
LOOP_DEVICE=""
|
||||
TIMEFORMAT='%3R'
|
||||
SFLCPATH=""
|
||||
|
|
@ -44,15 +44,15 @@ print_help() {
|
|||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]${NC}"
|
||||
echo " "
|
||||
echo "This script is used to benchmark Shufflecake on this machine."
|
||||
echo "This script is used to benchmark Shufflecake Lite on this machine."
|
||||
echo "This script is part of the Shufflecake benchmark suite."
|
||||
echo "Shufflecake is a plausible deniability (hidden storage) layer for Linux."
|
||||
echo -e "Please visit ${BLUE}https://www.shufflecake.net${NC} for more info and documentation."
|
||||
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:"
|
||||
echo "1) Creates a Shufflecake device with two volumes."
|
||||
echo "2) Opens the second (hidden) one, formats it with ext4 and mounts it."
|
||||
echo "1) Creates a Shufflecake (Lite) device with two volumes."
|
||||
echo "2) Opens the second (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 " "
|
||||
|
|
@ -241,20 +241,21 @@ benchmark() {
|
|||
|
||||
SFLCVOLUME=""
|
||||
MNTPOINT=""
|
||||
TESTNAME="sflc"
|
||||
TESTNAME="sflc-lite"
|
||||
RUNTIME="20" # running time in seconds FOR EACH TEST
|
||||
DATASIZE="500M"
|
||||
TESTFILENAME="testfile"
|
||||
echo "Starting benchmark for Shufflecake..."
|
||||
echo "Initializing block device $BLOCK_DEVICE with two Shufflecake volumes (--skip-randfill)..."
|
||||
echo "Starting benchmark for Shufflecake Lite..."
|
||||
echo "Initializing block device $BLOCK_DEVICE with two Shufflecake Lite volumes (--skip-randfill)..."
|
||||
etime=$( (time echo -e "passwd1\npasswd2" | $SFLCNAME --skip-randfill -n 2 init $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action init took $etime seconds.${NC}"
|
||||
echo "Shufflecake device initialized. Opening hidden volume (nr. 2)..."
|
||||
# open
|
||||
etime=$( (time echo -e "passwd2" | $SFLCNAME open $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action open took $etime seconds.${NC}"
|
||||
# fetch SFLCVOLUME
|
||||
SFLCVOLUME=$(find_sflcvolname)
|
||||
echo "Shufflecake volume opened as $SFLCVOLUME. Formatting with ext4..."
|
||||
echo "Shufflecake Lite volume opened as $SFLCVOLUME. Formatting with ext4..."
|
||||
# format with ext4, but mute output (too verbose)
|
||||
mkfs.ext4 $SFLCVOLUME > /dev/null
|
||||
echo "Volume $SFLCVOLUME formatted. Mounting that..."
|
||||
|
|
@ -282,7 +283,7 @@ benchmark() {
|
|||
OUTPUT=$(fio --name=$TESTNAME-w-seq --ioengine=libaio --iodepth=32 --rw=write --bs=4k --numjobs=1 --direct=1 --size=$DATASIZE --runtime=$RUNTIME --time_based --end_fsync=1 --filename=$MNTPOINT/$TESTFILENAME --output-format=json | jq '.jobs[] | {name: .jobname, write_iops: .write.iops, write_bw: .write.bw}')
|
||||
echo -e "${GREEN}${OUTPUT}${NC}"
|
||||
# END TESTS
|
||||
echo "Shufflecake fio tests ended. Unmounting volume."
|
||||
echo "Shufflecake Lite fio tests ended. Unmounting volume."
|
||||
# unmount
|
||||
umount $MNTPOINT
|
||||
rmdir $MNTPOINT
|
||||
|
|
@ -316,7 +317,7 @@ cleanup() {
|
|||
# BANNER
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
echo -e "${BLUE} Benchmark Suite Script for Shufflecake${NC}"
|
||||
echo -e "${BLUE} Benchmark Suite Script for Shufflecake Lite${NC}"
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
# Global variables
|
||||
SCRIPTNAME=$(basename "$0")
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
LOOP_FILENAME="$SCRIPT_DIR/sflc-frag-loop-file.img"
|
||||
LOOP_FILENAME="$SCRIPT_DIR/sflc-lite-frag-loop-file.img"
|
||||
LOOP_DEVICE=""
|
||||
TIMEFORMAT='%3R'
|
||||
SFLCPATH=""
|
||||
|
|
@ -48,15 +48,15 @@ print_help() {
|
|||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}Usage: ${SCRIPTNAME} [OPTION]... [BLOCKDEVICE]${NC}"
|
||||
echo " "
|
||||
echo "This script is used to evaluate Shufflecake volume fragmentation."
|
||||
echo "This script is used to evaluate Shufflecake Lite volume fragmentation."
|
||||
echo "This script is part of the Shufflecake benchmark suite."
|
||||
echo "Shufflecake is a plausible deniability (hidden storage) layer for Linux."
|
||||
echo -e "Please visit ${BLUE}https://www.shufflecake.net${NC} for more info and documentation."
|
||||
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:"
|
||||
echo "1) Creates a Shufflecake device with two volumes."
|
||||
echo "2) Opens the second (hidden) one, formats it with $FSTYPE and mounts it."
|
||||
echo "1) Creates a Shufflecake Lite device with two volumes."
|
||||
echo "2) Opens the second (hidden) volume, formats it with $FSTYPE and mounts it."
|
||||
echo "3) Performs incremental random write up to filling the space."
|
||||
echo "4) After every write round, checks fragmentation status and reports it."
|
||||
echo "5) Unmounts and closes the used volume."
|
||||
|
|
@ -250,12 +250,12 @@ benchmark() {
|
|||
NUMPOINTS=21 # number of graph points
|
||||
VOLSIZE=$(blockdev --getsize64 "$BLOCK_DEVICE") # first approximation, in bytes
|
||||
|
||||
echo "Starting fragmentation test for Shufflecake..."
|
||||
echo "Starting fragmentation test for Shufflecake Lite..."
|
||||
# init
|
||||
echo "Initializing block device $BLOCK_DEVICE with two Shufflecake volumes (--skip-randfill)..."
|
||||
echo "Initializing block device $BLOCK_DEVICE with two Shufflecake Lite volumes (--skip-randfill)..."
|
||||
etime=$( (time echo -e "passwd1\npasswd2" | $SFLCNAME --skip-randfill -n 2 init $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action init took $etime seconds.${NC}"
|
||||
echo "Shufflecake device initialized. Opening hidden volume (nr. 2)..."
|
||||
echo "Shufflecake Lite device initialized. Opening hidden volume (nr. 2)..."
|
||||
# open
|
||||
etime=$( (time echo -e "passwd2" | $SFLCNAME open $BLOCK_DEVICE > /dev/null) 2>&1 )
|
||||
echo -e "${GREEN}Action open took $etime seconds.${NC}"
|
||||
|
|
@ -351,7 +351,7 @@ benchmark() {
|
|||
echo -e "${GREEN}---------------------------------${NC}"
|
||||
|
||||
# END TESTS
|
||||
echo "Shufflecake fragmentation test ended. Unmounting volume."
|
||||
echo "Shufflecake Lite fragmentation test ended. Unmounting volume."
|
||||
# unmount
|
||||
umount $MNTPOINT
|
||||
rmdir $MNTPOINT
|
||||
|
|
@ -385,7 +385,7 @@ cleanup() {
|
|||
# BANNER
|
||||
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 79 chars
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
echo -e "${BLUE} Evaluation Script for Shufflecake Volume Fragmentation${NC}"
|
||||
echo -e "${BLUE} Evaluation Script for Shufflecake Lite Volume Fragmentation${NC}"
|
||||
echo -e "${BLUE}===============================================================================${NC}"
|
||||
|
||||
|
||||
|
|
@ -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 += legacy/sflc_legacy.o legacy/target.o legacy/sysfs.o
|
||||
OBJ_LIST += legacy/device/device.o legacy/device/volumes.o legacy/device/rawio.o legacy/device/rmap.o legacy/device/iv.o
|
||||
OBJ_LIST += legacy/volume/volume.o legacy/volume/io.o legacy/volume/read.o legacy/volume/write.o legacy/volume/fmap.o
|
||||
OBJ_LIST += legacy/utils/string.o legacy/utils/bio.o legacy/utils/pools.o legacy/utils/workqueues.o legacy/utils/vector.o
|
||||
OBJ_LIST += legacy/crypto/rand/rand.o
|
||||
OBJ_LIST += legacy/crypto/symkey/symkey.o legacy/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 += legacy/sflc_legacy.o legacy/target.o legacy/sysfs.o
|
||||
OBJ_LIST += legacy/device/device.o legacy/device/volumes.o legacy/device/rawio.o legacy/device/rmap.o legacy/device/iv.o
|
||||
OBJ_LIST += legacy/volume/volume.o legacy/volume/io.o legacy/volume/read.o legacy/volume/write.o legacy/volume/fmap.o
|
||||
OBJ_LIST += legacy/utils/string.o legacy/utils/bio.o legacy/utils/pools.o legacy/utils/workqueues.o legacy/utils/vector.o
|
||||
OBJ_LIST += legacy/crypto/rand/rand.o
|
||||
OBJ_LIST += legacy/crypto/symkey/symkey.o legacy/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/legacy/crypto/rand/rand.c
Symbolic link
1
dm-sflc/bin/legacy/crypto/rand/rand.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/legacy/crypto/rand/rand.c
|
||||
1
dm-sflc/bin/legacy/crypto/rand/rand.h
Symbolic link
1
dm-sflc/bin/legacy/crypto/rand/rand.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/legacy/crypto/rand/rand.h
|
||||
1
dm-sflc/bin/legacy/crypto/symkey/skreq_pool.c
Symbolic link
1
dm-sflc/bin/legacy/crypto/symkey/skreq_pool.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/legacy/crypto/symkey/skreq_pool.c
|
||||
1
dm-sflc/bin/legacy/crypto/symkey/skreq_pool.h
Symbolic link
1
dm-sflc/bin/legacy/crypto/symkey/skreq_pool.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/legacy/crypto/symkey/skreq_pool.h
|
||||
1
dm-sflc/bin/legacy/crypto/symkey/symkey.c
Symbolic link
1
dm-sflc/bin/legacy/crypto/symkey/symkey.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/legacy/crypto/symkey/symkey.c
|
||||
1
dm-sflc/bin/legacy/crypto/symkey/symkey.h
Symbolic link
1
dm-sflc/bin/legacy/crypto/symkey/symkey.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../src/legacy/crypto/symkey/symkey.h
|
||||
1
dm-sflc/bin/legacy/device/device.c
Symbolic link
1
dm-sflc/bin/legacy/device/device.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/device/device.c
|
||||
1
dm-sflc/bin/legacy/device/device.h
Symbolic link
1
dm-sflc/bin/legacy/device/device.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/device/device.h
|
||||
1
dm-sflc/bin/legacy/device/iv.c
Symbolic link
1
dm-sflc/bin/legacy/device/iv.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/device/iv.c
|
||||
1
dm-sflc/bin/legacy/device/rawio.c
Symbolic link
1
dm-sflc/bin/legacy/device/rawio.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/device/rawio.c
|
||||
1
dm-sflc/bin/legacy/device/rmap.c
Symbolic link
1
dm-sflc/bin/legacy/device/rmap.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/device/rmap.c
|
||||
1
dm-sflc/bin/legacy/device/volumes.c
Symbolic link
1
dm-sflc/bin/legacy/device/volumes.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/device/volumes.c
|
||||
1
dm-sflc/bin/legacy/log/log.h
Symbolic link
1
dm-sflc/bin/legacy/log/log.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/log/log.h
|
||||
1
dm-sflc/bin/legacy/sflc_legacy.c
Symbolic link
1
dm-sflc/bin/legacy/sflc_legacy.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/legacy/sflc_legacy.c
|
||||
1
dm-sflc/bin/legacy/sflc_legacy.h
Symbolic link
1
dm-sflc/bin/legacy/sflc_legacy.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/legacy/sflc_legacy.h
|
||||
1
dm-sflc/bin/legacy/sysfs.c
Symbolic link
1
dm-sflc/bin/legacy/sysfs.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/legacy/sysfs.c
|
||||
1
dm-sflc/bin/legacy/target.c
Symbolic link
1
dm-sflc/bin/legacy/target.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/legacy/target.c
|
||||
1
dm-sflc/bin/legacy/utils/bio.c
Symbolic link
1
dm-sflc/bin/legacy/utils/bio.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/bio.c
|
||||
1
dm-sflc/bin/legacy/utils/bio.h
Symbolic link
1
dm-sflc/bin/legacy/utils/bio.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/bio.h
|
||||
1
dm-sflc/bin/legacy/utils/pools.c
Symbolic link
1
dm-sflc/bin/legacy/utils/pools.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/pools.c
|
||||
1
dm-sflc/bin/legacy/utils/pools.h
Symbolic link
1
dm-sflc/bin/legacy/utils/pools.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/pools.h
|
||||
1
dm-sflc/bin/legacy/utils/string.c
Symbolic link
1
dm-sflc/bin/legacy/utils/string.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/string.c
|
||||
1
dm-sflc/bin/legacy/utils/string.h
Symbolic link
1
dm-sflc/bin/legacy/utils/string.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/string.h
|
||||
1
dm-sflc/bin/legacy/utils/vector.c
Symbolic link
1
dm-sflc/bin/legacy/utils/vector.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/vector.c
|
||||
1
dm-sflc/bin/legacy/utils/vector.h
Symbolic link
1
dm-sflc/bin/legacy/utils/vector.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/vector.h
|
||||
1
dm-sflc/bin/legacy/utils/workqueues.c
Symbolic link
1
dm-sflc/bin/legacy/utils/workqueues.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/workqueues.c
|
||||
1
dm-sflc/bin/legacy/utils/workqueues.h
Symbolic link
1
dm-sflc/bin/legacy/utils/workqueues.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/utils/workqueues.h
|
||||
1
dm-sflc/bin/legacy/volume/fmap.c
Symbolic link
1
dm-sflc/bin/legacy/volume/fmap.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/volume/fmap.c
|
||||
1
dm-sflc/bin/legacy/volume/io.c
Symbolic link
1
dm-sflc/bin/legacy/volume/io.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/volume/io.c
|
||||
1
dm-sflc/bin/legacy/volume/read.c
Symbolic link
1
dm-sflc/bin/legacy/volume/read.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/volume/read.c
|
||||
1
dm-sflc/bin/legacy/volume/volume.c
Symbolic link
1
dm-sflc/bin/legacy/volume/volume.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/volume/volume.c
|
||||
1
dm-sflc/bin/legacy/volume/volume.h
Symbolic link
1
dm-sflc/bin/legacy/volume/volume.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/volume/volume.h
|
||||
1
dm-sflc/bin/legacy/volume/write.c
Symbolic link
1
dm-sflc/bin/legacy/volume/write.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../src/legacy/volume/write.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/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 "legacy/sflc_legacy.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->sflegc_dev = sflegc_dev_create(ti, argc, argv, &sdev->kobj);
|
||||
if (IS_ERR(sdev->sflegc_dev)) {
|
||||
err = PTR_ERR(sdev->sflegc_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:
|
||||
sflegc_dev_destroy(sdev->sflegc_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->sflegc_vol = sflegc_vol_create(ti, sdev->sflegc_dev, argc, argv, &svol->kobj);
|
||||
if (IS_ERR(svol->sflegc_vol)) {
|
||||
err = PTR_ERR(svol->sflegc_vol);
|
||||
goto bad_inner;
|
||||
}
|
||||
svol->tt = &sflegc_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:
|
||||
sflegc_vol_destroy(svol->sflegc_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);
|
||||
}
|
||||
|
|
@ -28,55 +28,55 @@
|
|||
#include <crypto/rng.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include "rand.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/crypto/rand/rand.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
#define SFLC_RAND_RNG_NAME "drbg_nopr_sha256"
|
||||
#define SFLEGC_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 sflegc_rand_tfm_lock;
|
||||
static struct crypto_rng * sflegc_rand_tfm = NULL;
|
||||
|
||||
/*****************************************************
|
||||
* PRIVATE FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
/* Flexible to accommodate for both required and non-required reseeding */
|
||||
static int sflc_rand_reseed(void);
|
||||
static int sflegc_rand_reseed(void);
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Init the submodule */
|
||||
int sflc_rand_init(void)
|
||||
int sflegc_rand_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Init the lock governing the SFLC RNG */
|
||||
mutex_init(&sflc_rand_tfm_lock);
|
||||
mutex_init(&sflegc_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);
|
||||
sflegc_rand_tfm = crypto_alloc_rng(SFLEGC_RAND_RNG_NAME, CRYPTO_ALG_TYPE_RNG, 0);
|
||||
if (IS_ERR(sflegc_rand_tfm)) {
|
||||
err = PTR_ERR(sflegc_rand_tfm);
|
||||
sflegc_rand_tfm = NULL;
|
||||
pr_err("Could not allocate RNG %s; error %d\n", SFLEGC_RAND_RNG_NAME, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* The new RNG comes not seeded, right? */
|
||||
err = sflc_rand_reseed();
|
||||
err = sflegc_rand_reseed();
|
||||
if (err) {
|
||||
pr_err("Could not seed the RNG; error %d\n", err);
|
||||
sflc_rand_exit();
|
||||
sflegc_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 sflegc_rand_getBytes(u8 * buf, unsigned count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Acquire lock */
|
||||
if (mutex_lock_interruptible(&sflc_rand_tfm_lock)) {
|
||||
if (mutex_lock_interruptible(&sflegc_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(sflegc_rand_tfm, buf, count);
|
||||
|
||||
/* End of critical region */
|
||||
mutex_unlock(&sflc_rand_tfm_lock);
|
||||
mutex_unlock(&sflegc_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 sflegc_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 = sflegc_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 sflegc_rand_exit(void)
|
||||
{
|
||||
if (sflc_rand_tfm) {
|
||||
crypto_free_rng(sflc_rand_tfm);
|
||||
sflc_rand_tfm = NULL;
|
||||
if (sflegc_rand_tfm) {
|
||||
crypto_free_rng(sflegc_rand_tfm);
|
||||
sflegc_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 sflegc_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(sflegc_rand_tfm, NULL, crypto_rng_seedsize(sflegc_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 _SFLEGC_CRYPTO_RAND_RAND_H_
|
||||
#define _SFLEGC_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 sflegc_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 sflegc_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 sflegc_rand_uniform(s32 max);
|
||||
|
||||
/* Tear down the submodule */
|
||||
void sflc_rand_exit(void);
|
||||
void sflegc_rand_exit(void);
|
||||
|
||||
|
||||
#endif /* _SFLC_CRYPTO_RAND_RAND_H_ */
|
||||
#endif /* _SFLEGC_CRYPTO_RAND_RAND_H_ */
|
||||
|
|
@ -25,8 +25,8 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "skreq_pool.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/crypto/symkey/skreq_pool.h"
|
||||
#include "legacy/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 * sflegc_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 sflegc_sk_freeRequest(void * element, void * pool_data);
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
mempool_t * sflc_sk_createReqPool(int min_nr, sflc_sk_Context * ctx)
|
||||
mempool_t * sflegc_sk_createReqPool(int min_nr, sflegc_sk_Context * ctx)
|
||||
{
|
||||
return mempool_create(min_nr, sflc_sk_allocRequest, sflc_sk_freeRequest, (void *) ctx);
|
||||
return mempool_create(min_nr, sflegc_sk_allocRequest, sflegc_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 * sflegc_sk_allocRequest(gfp_t gfp_mask, void * pool_data)
|
||||
{
|
||||
sflc_sk_Context * ctx = pool_data;
|
||||
sflegc_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 sflegc_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 _SFLEGC_CRYPTO_SYMKEY_SKREQ_POOL_H_
|
||||
#define _SFLEGC_CRYPTO_SYMKEY_SKREQ_POOL_H_
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include <linux/mempool.h>
|
||||
|
||||
#include "symkey.h"
|
||||
#include "legacy/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 * sflegc_sk_createReqPool(int min_nr, sflegc_sk_Context * ctx);
|
||||
|
||||
|
||||
#endif /* _SFLC_CRYPTO_SYMKEY_SKREQ_POOL_H_ */
|
||||
#endif /* _SFLEGC_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 "legacy/crypto/symkey/symkey.h"
|
||||
#include "legacy/crypto/symkey/skreq_pool.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
#define SFLC_SK_REQ_POOL_SIZE 1024
|
||||
#define SFLEGC_SK_REQ_POOL_SIZE 1024
|
||||
|
||||
#define SFLC_SK_ENCRYPT 0
|
||||
#define SFLC_SK_DECRYPT 1
|
||||
#define SFLEGC_SK_ENCRYPT 0
|
||||
#define SFLEGC_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 sflegc_sk_encdec(sflegc_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)
|
||||
sflegc_sk_Context * sflegc_sk_createContext(u8 * key)
|
||||
{
|
||||
sflc_sk_Context * ctx;
|
||||
sflegc_sk_Context * ctx;
|
||||
int err;
|
||||
|
||||
/* Allocate context */
|
||||
ctx = kzalloc(sizeof(sflc_sk_Context), GFP_KERNEL);
|
||||
ctx = kzalloc(sizeof(sflegc_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 sflegc_sk_Context\n", sizeof(sflegc_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(SFLEGC_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);
|
||||
sflegc_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, SFLEGC_SK_KEY_LEN);
|
||||
err = crypto_skcipher_setkey(ctx->tfm, ctx->key, SFLEGC_SK_KEY_LEN);
|
||||
if (err) {
|
||||
pr_err("Could not set key in crypto transform: error %d\n", err);
|
||||
sflc_sk_destroyContext(ctx);
|
||||
sflegc_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 = sflegc_sk_createReqPool(SFLEGC_SK_REQ_POOL_SIZE, ctx);
|
||||
if (!ctx->sk_req_pool) {
|
||||
pr_err("Could not allocate skcipher_request memory pool\n");
|
||||
sflc_sk_destroyContext(ctx);
|
||||
sflegc_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 sflegc_sk_destroyContext(sflegc_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 sflegc_sk_encrypt(sflegc_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 sflegc_sk_encdec(ctx, src, dst, len, iv, SFLEGC_SK_ENCRYPT);
|
||||
}
|
||||
|
||||
int sflc_sk_decrypt(sflc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv)
|
||||
int sflegc_sk_decrypt(sflegc_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 sflegc_sk_encdec(ctx, src, dst, len, iv, SFLEGC_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 sflegc_sk_encdec(sflegc_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 == SFLEGC_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 _SFLEGC_CRYPTO_SYMKEY_SYMKEY_H_
|
||||
#define _SFLEGC_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 SFLEGC_SK_CIPHER_NAME "ctr(aes)"
|
||||
#define SFLEGC_SK_KEY_LEN 32
|
||||
#define SFLEGC_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 sflegc_sk_context_s
|
||||
{
|
||||
/* Only one transform for now */
|
||||
struct crypto_skcipher * tfm;
|
||||
|
||||
/* 32-byte key */
|
||||
u8 key[SFLC_SK_KEY_LEN];
|
||||
u8 key[SFLEGC_SK_KEY_LEN];
|
||||
|
||||
/* Memory pool for skcipher_request's */
|
||||
mempool_t * sk_req_pool;
|
||||
|
||||
} sflc_sk_Context;
|
||||
} sflegc_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);
|
||||
sflegc_sk_Context * sflegc_sk_createContext(u8 * key);
|
||||
/* Destroy the given context */
|
||||
void sflc_sk_destroyContext(sflc_sk_Context * ctx);
|
||||
void sflegc_sk_destroyContext(sflegc_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 sflegc_sk_encrypt(sflegc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv);
|
||||
int sflegc_sk_decrypt(sflegc_sk_Context * ctx, u8 * src, u8 * dst, unsigned int len, u8 * iv);
|
||||
|
||||
|
||||
#endif /* _SFLC_CRYPTO_SYMKEY_SYMKEY_H_ */
|
||||
#endif /* _SFLEGC_CRYPTO_SYMKEY_SYMKEY_H_ */
|
||||
259
dm-sflc/src/legacy/device/device.c
Normal file
259
dm-sflc/src/legacy/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 "legacy/sflc_legacy.h"
|
||||
#include "legacy/device/device.h"
|
||||
#include "legacy/utils/vector.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC VARIABLES DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
|
||||
/* Initialises and pre-shuffles the PSI array */
|
||||
static int sflegc_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)
|
||||
*/
|
||||
sflegc_Device *sflegc_dev_create(struct dm_target *ti, int argc, char **argv, struct kobject *kobj)
|
||||
{
|
||||
sflegc_Device * dev;
|
||||
u32 tot_slices;
|
||||
u32 dev_id;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
/* Allocate device */
|
||||
dev = kzalloc(sizeof(sflegc_Device), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
pr_err("Could not allocate %lu bytes for sflegc_Device\n", sizeof(sflegc_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 < SFLEGC_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, SFLEGC_VOL_HEADER_MAPPINGS_PER_BLOCK);
|
||||
dev->vol_header_nr_iv_blocks = DIV_ROUND_UP(nr_pmbs_per_vol, SFLEGC_VOL_LOG_SLICE_SIZE);
|
||||
dev->vol_header_size = 1 + nr_pmbs_per_vol + dev->vol_header_nr_iv_blocks;
|
||||
dev->dev_header_size = 1 + (SFLEGC_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, SFLEGC_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 = sflegc_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(sflegc_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 = sflegc_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 sflegc_dev_destroy(sflegc_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 */
|
||||
sflegc_dev_flushIvs(dev);
|
||||
|
||||
/* List */
|
||||
list_del(&dev->list_node);
|
||||
|
||||
/* Sysfs */
|
||||
sflegc_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 sflegc_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 sflegc_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 _SFLEGC_DEVICE_DEVICE_H_
|
||||
#define _SFLEGC_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 sflegc_device_s sflegc_Device;
|
||||
typedef struct sflegc_dev_iv_cache_entry_s sflegc_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 "legacy/sflc_legacy.h"
|
||||
#include "legacy/volume/volume.h"
|
||||
#include "legacy/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 SFLEGC_DEV_SECTOR_SIZE 4096
|
||||
/* A SFLC sector encompasses 8 kernel sectors */
|
||||
#define SFLC_DEV_SECTOR_SCALE (SFLC_DEV_SECTOR_SIZE / SECTOR_SIZE)
|
||||
#define SFLEGC_DEV_SECTOR_SCALE (SFLEGC_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 SFLEGC_DEV_SECTOR_TO_IV_RATIO (SFLEGC_DEV_SECTOR_SIZE / SFLEGC_SK_IV_LEN)
|
||||
|
||||
/* Max number of volumes linked to a single device */
|
||||
#define SFLC_DEV_MAX_VOLUMES 15
|
||||
#define SFLEGC_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 SFLEGC_DEV_PHYS_SLICE_SIZE (SFLEGC_VOL_LOG_SLICE_SIZE + (SFLEGC_VOL_LOG_SLICE_SIZE / SFLEGC_DEV_SECTOR_TO_IV_RATIO))
|
||||
|
||||
/* Value marking a PSI as unassigned */
|
||||
#define SFLC_DEV_RMAP_INVALID_VOL 0xFFU
|
||||
#define SFLEGC_DEV_RMAP_INVALID_VOL 0xFFU
|
||||
|
||||
/* Maximum number of open devices in total across shufflecake */
|
||||
#define SFLC_DEV_MAX_DEVICES_TOT 1024
|
||||
#define SFLEGC_DEV_MAX_DEVICES_TOT 1024
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* TYPES *
|
||||
*****************************************************/
|
||||
|
||||
struct sflc_dev_iv_cache_entry_s
|
||||
struct sflegc_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 sflegc_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];
|
||||
sflegc_Volume * vol[SFLEGC_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;
|
||||
sflegc_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);
|
||||
sflegc_Device * sflegc_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 sflegc_dev_destroy(sflegc_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 sflegc_dev_addVolume(sflegc_Device * dev, sflegc_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 sflegc_dev_removeVolume(sflegc_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 sflegc_dev_rwSector(sflegc_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 sflegc_dev_markPsiTaken(sflegc_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 sflegc_dev_getNextRandomFreePsi(sflegc_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 * sflegc_dev_getIvBlockRef(sflegc_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 sflegc_dev_putIvBlockRef(sflegc_Device * dev, u32 psi);
|
||||
|
||||
/* Flush all dirty IV blocks */
|
||||
void sflc_dev_flushIvs(sflc_Device * dev);
|
||||
void sflegc_dev_flushIvs(sflegc_Device * dev);
|
||||
|
||||
|
||||
#endif /* _SFLC_DEVICE_DEVICE_H_ */
|
||||
#endif /* _SFLEGC_DEVICE_DEVICE_H_ */
|
||||
|
|
@ -25,24 +25,30 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "device.h"
|
||||
#include "utils/pools.h"
|
||||
#include "log/log.h"
|
||||
|
||||
#include "legacy/device/device.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
/* Capacity of IV cache */
|
||||
#define SFLC_DEV_IV_CACHE_CAPACITY 1024
|
||||
#define SFLEGC_DEV_IV_CACHE_CAPACITY 1024
|
||||
|
||||
/*****************************************************
|
||||
* MACROS *
|
||||
*****************************************************/
|
||||
|
||||
#define sflegc_dev_psiToIvBlockSector(dev, psi) (dev->dev_header_size + (sector_t)(psi) * SFLEGC_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 sflegc_dev_IvCacheEntry * sflegc_dev_newIvCacheEntry(sflegc_Device * dev, u32 psi);
|
||||
static int sflegc_dev_destroyIvCacheEntry(sflegc_Device * dev, sflegc_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 * sflegc_dev_getIvBlockRef(sflegc_Device * dev, u32 psi, int rw)
|
||||
{
|
||||
sflc_dev_IvCacheEntry * entry;
|
||||
sflegc_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 >= SFLEGC_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 < SFLEGC_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 = sflegc_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 sflegc_dev_putIvBlockRef(sflegc_Device * dev, u32 psi)
|
||||
{
|
||||
sflc_dev_IvCacheEntry * entry;
|
||||
sflegc_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 < SFLEGC_DEV_IV_CACHE_CAPACITY) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Otherwise, let's look for the least recent unreffed entry, and evict it */
|
||||
sflc_dev_IvCacheEntry * evicted;
|
||||
sflegc_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 = sflegc_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 sflegc_dev_flushIvs(sflegc_Device * dev)
|
||||
{
|
||||
sflc_dev_IvCacheEntry * entry, * _next;
|
||||
sflegc_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 = sflegc_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 sflegc_dev_IvCacheEntry * sflegc_dev_newIvCacheEntry(sflegc_Device * dev, u32 psi)
|
||||
{
|
||||
sflc_dev_IvCacheEntry * entry;
|
||||
sflegc_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(sflegc_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(sflegc_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 = sflegc_dev_psiToIvBlockSector(dev, psi);
|
||||
|
||||
/* Read */
|
||||
err = sflc_dev_rwSector(dev, entry->iv_page, sector, READ);
|
||||
err = sflegc_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, sflegc_pools_pagePool);
|
||||
err_alloc_page:
|
||||
kmem_cache_free(sflc_pools_ivSlab, entry);
|
||||
kmem_cache_free(sflegc_pools_ivSlab, entry);
|
||||
err_alloc_entry:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int sflc_dev_destroyIvCacheEntry(sflc_Device * dev, sflc_dev_IvCacheEntry * entry)
|
||||
static int sflegc_dev_destroyIvCacheEntry(sflegc_Device * dev, sflegc_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 = sflegc_dev_psiToIvBlockSector(dev, entry->psi);
|
||||
|
||||
/* Write (if necessary) */
|
||||
if (entry->dirtyness) {
|
||||
err = sflc_dev_rwSector(dev, entry->iv_page, sector, WRITE);
|
||||
err = sflegc_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, sflegc_pools_pagePool);
|
||||
|
||||
/* Free structure */
|
||||
kmem_cache_free(sflc_pools_ivSlab, entry);
|
||||
kmem_cache_free(sflegc_pools_ivSlab, entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -25,14 +25,12 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "device.h"
|
||||
#include "utils/pools.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/device/device.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/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 sflegc_dev_rwSector(sflegc_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, &sflegc_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 * SFLEGC_DEV_SECTOR_SCALE;
|
||||
/* Add page */
|
||||
if (!bio_add_page(bio, page, SFLC_DEV_SECTOR_SIZE, 0)) {
|
||||
if (!bio_add_page(bio, page, SFLEGC_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 "legacy/device/device.h"
|
||||
#include "legacy/crypto/rand/rand.h"
|
||||
#include "legacy/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 sflegc_dev_markPsiTaken(sflegc_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 != SFLEGC_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 sflegc_dev_getNextRandomFreePsi(sflegc_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] != SFLEGC_DEV_RMAP_INVALID_VOL);
|
||||
|
||||
return psi;
|
||||
}
|
||||
|
|
@ -29,8 +29,8 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "device.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/device/device.h"
|
||||
#include "legacy/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 sflegc_dev_addVolume(sflegc_Device * dev, sflegc_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 sflegc_dev_removeVolume(sflegc_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 _SFLEGC_LOG_LOG_H_
|
||||
#define _SFLEGC_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 /* _SFLEGC_LOG_LOG_H_ */
|
||||
87
dm-sflc/src/legacy/sflc_legacy.c
Normal file
87
dm-sflc/src/legacy/sflc_legacy.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 "legacy/sflc_legacy.h"
|
||||
#include "legacy/crypto/symkey/symkey.h"
|
||||
#include "legacy/crypto/rand/rand.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/utils/workqueues.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* MODULE FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Module entry point, called just once, at module-load time */
|
||||
int sflegc_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sflegc_rand_init();
|
||||
if (ret) {
|
||||
pr_err("Could not init rand; error %d\n", ret);
|
||||
goto err_rand_init;
|
||||
}
|
||||
|
||||
/* Init the memory pools */
|
||||
ret = sflegc_pools_init();
|
||||
if (ret) {
|
||||
pr_err("Could not init memory pools; error %d\n", ret);
|
||||
goto err_pools;
|
||||
}
|
||||
|
||||
/* Init the workqueues */
|
||||
ret = sflegc_queues_init();
|
||||
if (ret) {
|
||||
pr_err("Could not init workqueues; error %d\n", ret);
|
||||
goto err_queues;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
err_queues:
|
||||
sflegc_pools_exit();
|
||||
err_pools:
|
||||
sflegc_rand_exit();
|
||||
err_rand_init:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Module exit point, called just once, at module-unload time */
|
||||
void sflegc_exit(void)
|
||||
{
|
||||
sflegc_queues_exit();
|
||||
sflegc_pools_exit();
|
||||
sflegc_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 _SFLEGC_SFLEGC_H
|
||||
#define _SFLEGC_SFLEGC_H
|
||||
|
||||
|
||||
#endif /* _SFLC_TARGET_TARGET_H_ */
|
||||
// For the definition of sflegc_Device and its functions
|
||||
#include "legacy/device/device.h"
|
||||
// For the definition of sflegc_Volume and its functions
|
||||
#include "legacy/volume/volume.h"
|
||||
|
||||
|
||||
extern struct target_type sflegc_target_type;
|
||||
|
||||
|
||||
int sflegc_init(void);
|
||||
void sflegc_exit(void);
|
||||
|
||||
int sflegc_sysfs_add_device(sflegc_Device *dev);
|
||||
void sflegc_sysfs_remove_device(sflegc_Device *dev);
|
||||
int sflegc_sysfs_add_volume(sflegc_Volume *vol);
|
||||
void sflegc_sysfs_remove_volume(sflegc_Volume *vol);
|
||||
|
||||
|
||||
#endif /* _SFLEGC_SFLEGC_H */
|
||||
142
dm-sflc/src/legacy/sysfs.c
Normal file
142
dm-sflc/src/legacy/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 "legacy/sflc_legacy.h"
|
||||
#include "legacy/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;
|
||||
sflegc_Device * dev;
|
||||
ssize_t ret;
|
||||
|
||||
top_dev = container_of(kobj, struct sflc_device, kobj);
|
||||
dev = top_dev->sflegc_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;
|
||||
sflegc_Device * dev;
|
||||
ssize_t ret;
|
||||
|
||||
top_dev = container_of(kobj, struct sflc_device, kobj);
|
||||
dev = top_dev->sflegc_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 *sflegc_device_attrs[] = {
|
||||
&tot_slices_kattr.attr,
|
||||
&free_slices_kattr.attr,
|
||||
NULL
|
||||
};
|
||||
static const struct attribute_group sflegc_device_attr_group = {
|
||||
.attrs = sflegc_device_attrs,
|
||||
};
|
||||
|
||||
int sflegc_sysfs_add_device(sflegc_Device *dev)
|
||||
{
|
||||
return sysfs_create_group(dev->kobj_parent, &sflegc_device_attr_group);
|
||||
}
|
||||
|
||||
void sflegc_sysfs_remove_device(sflegc_Device *dev)
|
||||
{
|
||||
sysfs_remove_group(dev->kobj_parent, &sflegc_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;
|
||||
sflegc_Volume * vol;
|
||||
ssize_t ret;
|
||||
|
||||
top_vol = container_of(kobj, struct sflc_volume, kobj);
|
||||
vol = top_vol->sflegc_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 *sflegc_volume_attrs[] = {
|
||||
&mapped_slices_kattr.attr,
|
||||
NULL
|
||||
};
|
||||
static const struct attribute_group sflegc_volume_attr_group = {
|
||||
.attrs = sflegc_volume_attrs,
|
||||
};
|
||||
|
||||
int sflegc_sysfs_add_volume(sflegc_Volume *vol)
|
||||
{
|
||||
return sysfs_create_group(vol->kobj_parent, &sflegc_volume_attr_group);
|
||||
}
|
||||
|
||||
void sflegc_sysfs_remove_volume(sflegc_Volume *vol)
|
||||
{
|
||||
sysfs_remove_group(vol->kobj_parent, &sflegc_volume_attr_group);
|
||||
}
|
||||
150
dm-sflc/src/legacy/target.c
Normal file
150
dm-sflc/src/legacy/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 "legacy/device/device.h"
|
||||
#include "legacy/volume/volume.h"
|
||||
#include "legacy/utils/bio.h"
|
||||
#include "legacy/utils/string.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
// Only to import the definition of struct sflc_volume
|
||||
#include "sflc.h"
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
/*****************************************************
|
||||
* PRIVATE FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
static int sflegc_tgt_map(struct dm_target *ti, struct bio *bio);
|
||||
static void sflegc_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits);
|
||||
static int sflegc_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn,
|
||||
void *data);
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC VARIABLES DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
struct target_type sflegc_target_type = {
|
||||
.map = sflegc_tgt_map,
|
||||
.io_hints = sflegc_tgt_ioHints,
|
||||
.iterate_devices = sflegc_tgt_iterateDevices,
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
* PRIVATE FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
|
||||
/* Callback for every bio submitted to our virtual block device */
|
||||
static int sflegc_tgt_map(struct dm_target *ti, struct bio *bio)
|
||||
{
|
||||
int err;
|
||||
struct sflc_volume *top_vol = ti->private;
|
||||
sflegc_Volume *vol = top_vol->sflegc_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 = sflegc_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(!sflegc_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 > SFLEGC_DEV_SECTOR_SIZE)) {
|
||||
pr_notice("Large bio of size %u\n", bio->bi_iter.bi_size);
|
||||
dm_accept_partial_bio(bio, SFLEGC_DEV_SECTOR_SCALE);
|
||||
}
|
||||
/* Check that it contains exactly one SFLC sector */
|
||||
if (unlikely(bio->bi_iter.bi_size != SFLEGC_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 = sflegc_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 sflegc_tgt_ioHints(struct dm_target *ti, struct queue_limits *limits)
|
||||
{
|
||||
struct sflc_volume *top_vol = ti->private;
|
||||
sflegc_Volume *vol = top_vol->sflegc_vol;
|
||||
|
||||
pr_info("Called io_hints on volume \"%s\"\n", vol->vol_name);
|
||||
|
||||
limits->logical_block_size = SFLEGC_DEV_SECTOR_SIZE;
|
||||
limits->physical_block_size = SFLEGC_DEV_SECTOR_SIZE;
|
||||
|
||||
limits->io_min = SFLEGC_DEV_SECTOR_SIZE;
|
||||
limits->io_opt = SFLEGC_DEV_SECTOR_SIZE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Callback needed for God knows what, otherwise io_hints never gets called */
|
||||
static int sflegc_tgt_iterateDevices(struct dm_target *ti, iterate_devices_callout_fn fn,
|
||||
void *data)
|
||||
{
|
||||
struct sflc_volume *top_vol = ti->private;
|
||||
sflegc_Volume *vol = top_vol->sflegc_vol;
|
||||
sflegc_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 * SFLEGC_DEV_PHYS_SLICE_SIZE) * SFLEGC_DEV_SECTOR_SCALE,
|
||||
data);
|
||||
}
|
||||
|
|
@ -29,8 +29,8 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "bio.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/utils/bio.h"
|
||||
#include "legacy/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 sflegc_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 % SFLEGC_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 % SFLEGC_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 % SFLEGC_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 _SFLEGC_UTILS_BIO_H_
|
||||
#define _SFLEGC_UTILS_BIO_H_
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "device/device.h"
|
||||
#include "legacy/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 sflegc_bio_isAligned(struct bio * bio);
|
||||
|
||||
|
||||
#endif /* _SFLC_UTILS_BIO_H_ */
|
||||
#endif /* _SFLEGC_UTILS_BIO_H_ */
|
||||
|
|
@ -29,100 +29,100 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "pools.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/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 SFLEGC_POOLS_BIOSET_POOL_SIZE 1024
|
||||
#define SFLEGC_POOLS_PAGE_POOL_SIZE 1024
|
||||
#define SFLEGC_POOLS_WRITE_WORK_POOL_SIZE 1024
|
||||
#define SFLEGC_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 SFLEGC_POOLS_WRITE_WORK_SLAB_NAME "sflegc_write_work_slab"
|
||||
#define SFLEGC_POOLS_DECRYPT_WORK_SLAB_NAME "sflegc_decrypt_work_slab"
|
||||
#define SFLEGC_POOLS_IV_SLAB_NAME "sflegc_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 sflegc_pools_bioset;
|
||||
mempool_t * sflegc_pools_pagePool;
|
||||
mempool_t * sflegc_pools_writeWorkPool;
|
||||
mempool_t * sflegc_pools_decryptWorkPool;
|
||||
struct kmem_cache * sflegc_pools_ivSlab;
|
||||
|
||||
/*****************************************************
|
||||
* PRIVATE VARIABLES *
|
||||
*****************************************************/
|
||||
|
||||
static struct kmem_cache * sflc_pools_writeWorkSlab;
|
||||
static struct kmem_cache * sflc_pools_decryptWorkSlab;
|
||||
static struct kmem_cache * sflegc_pools_writeWorkSlab;
|
||||
static struct kmem_cache * sflegc_pools_decryptWorkSlab;
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
int sflc_pools_init(void)
|
||||
int sflegc_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(&sflegc_pools_bioset, SFLEGC_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) {
|
||||
sflegc_pools_pagePool = mempool_create_page_pool(SFLEGC_POOLS_PAGE_POOL_SIZE, 0);
|
||||
if (!sflegc_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);
|
||||
sflegc_pools_writeWorkSlab = kmem_cache_create(SFLEGC_POOLS_WRITE_WORK_SLAB_NAME, sizeof(sflegc_vol_WriteWork), 0, SLAB_POISON | SLAB_RED_ZONE, NULL);
|
||||
if (IS_ERR(sflegc_pools_writeWorkSlab)) {
|
||||
err = PTR_ERR(sflegc_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) {
|
||||
sflegc_pools_writeWorkPool = mempool_create_slab_pool(SFLEGC_POOLS_WRITE_WORK_POOL_SIZE, sflegc_pools_writeWorkSlab);
|
||||
if (!sflegc_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);
|
||||
sflegc_pools_decryptWorkSlab = kmem_cache_create(SFLEGC_POOLS_DECRYPT_WORK_SLAB_NAME, sizeof(sflegc_vol_DecryptWork), 0, SLAB_POISON | SLAB_RED_ZONE, NULL);
|
||||
if (IS_ERR(sflegc_pools_decryptWorkSlab)) {
|
||||
err = PTR_ERR(sflegc_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) {
|
||||
sflegc_pools_decryptWorkPool = mempool_create_slab_pool(SFLEGC_POOLS_DECRYPT_WORK_POOL_SIZE, sflegc_pools_decryptWorkSlab);
|
||||
if (!sflegc_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);
|
||||
sflegc_pools_ivSlab = kmem_cache_create(SFLEGC_POOLS_IV_SLAB_NAME, sizeof(sflegc_dev_IvCacheEntry), 0, SLAB_POISON | SLAB_RED_ZONE, NULL);
|
||||
if (IS_ERR(sflegc_pools_ivSlab)) {
|
||||
err = PTR_ERR(sflegc_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(sflegc_pools_decryptWorkPool);
|
||||
err_decrypt_work_pool:
|
||||
kmem_cache_destroy(sflc_pools_decryptWorkSlab);
|
||||
kmem_cache_destroy(sflegc_pools_decryptWorkSlab);
|
||||
err_create_decrypt_work_slab:
|
||||
mempool_destroy(sflc_pools_writeWorkPool);
|
||||
mempool_destroy(sflegc_pools_writeWorkPool);
|
||||
err_write_work_pool:
|
||||
kmem_cache_destroy(sflc_pools_writeWorkSlab);
|
||||
kmem_cache_destroy(sflegc_pools_writeWorkSlab);
|
||||
err_create_write_work_slab:
|
||||
mempool_destroy(sflc_pools_pagePool);
|
||||
mempool_destroy(sflegc_pools_pagePool);
|
||||
err_pagepool:
|
||||
bioset_exit(&sflc_pools_bioset);
|
||||
bioset_exit(&sflegc_pools_bioset);
|
||||
err_bioset:
|
||||
return err;
|
||||
}
|
||||
|
||||
void sflc_pools_exit(void)
|
||||
void sflegc_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(sflegc_pools_ivSlab);
|
||||
mempool_destroy(sflegc_pools_decryptWorkPool);
|
||||
kmem_cache_destroy(sflegc_pools_decryptWorkSlab);
|
||||
mempool_destroy(sflegc_pools_writeWorkPool);
|
||||
kmem_cache_destroy(sflegc_pools_writeWorkSlab);
|
||||
mempool_destroy(sflegc_pools_pagePool);
|
||||
bioset_exit(&sflegc_pools_bioset);
|
||||
}
|
||||
|
|
@ -25,31 +25,31 @@
|
|||
* A set of memory pools
|
||||
*/
|
||||
|
||||
#ifndef _SFLC_UTILS_POOLS_H_
|
||||
#define _SFLC_UTILS_POOLS_H_
|
||||
#ifndef _SFLEGC_UTILS_POOLS_H_
|
||||
#define _SFLEGC_UTILS_POOLS_H_
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "device/device.h"
|
||||
#include "legacy/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 sflegc_pools_bioset;
|
||||
extern mempool_t * sflegc_pools_pagePool;
|
||||
extern mempool_t * sflegc_pools_writeWorkPool;
|
||||
extern mempool_t * sflegc_pools_decryptWorkPool;
|
||||
extern struct kmem_cache * sflegc_pools_ivSlab;
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
int sflc_pools_init(void);
|
||||
void sflc_pools_exit(void);
|
||||
int sflegc_pools_init(void);
|
||||
void sflegc_pools_exit(void);
|
||||
|
||||
|
||||
#endif /* _SFLC_UTILS_POOLS_H_ */
|
||||
#endif /* _SFLEGC_UTILS_POOLS_H_ */
|
||||
|
|
@ -31,15 +31,15 @@
|
|||
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "string.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/utils/string.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
int sflc_str_hexDecode(char * hex, u8 * bin)
|
||||
int sflegc_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 sflegc_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 _SFLEGC_UTILS_STRING_H_
|
||||
#define _SFLEGC_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 sflegc_str_hexDecode(char * hex, u8 * bin);
|
||||
void sflegc_str_replaceAll(char * str, char old, char new);
|
||||
|
||||
|
||||
#endif /* _SFLC_UTILS_STRING_H_ */
|
||||
#endif /* _SFLEGC_UTILS_STRING_H_ */
|
||||
|
|
@ -29,9 +29,9 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "vector.h"
|
||||
#include "crypto/rand/rand.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/utils/vector.h"
|
||||
#include "legacy/crypto/rand/rand.h"
|
||||
#include "legacy/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 sflegc_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 = sflegc_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 _SFLEGC_UTILS_VECTOR_H_
|
||||
#define _SFLEGC_UTILS_VECTOR_H_
|
||||
|
||||
/*****************************************************
|
||||
* INCLUDE SECTION *
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
*****************************************************/
|
||||
|
||||
/* Shuffle a vector of u32's */
|
||||
int sflc_vec_u32shuffle(u32 *v, u32 len);
|
||||
int sflegc_vec_u32shuffle(u32 *v, u32 len);
|
||||
|
||||
|
||||
#endif /* _SFLC_UTILS_VECTOR_H_ */
|
||||
#endif /* _SFLEGC_UTILS_VECTOR_H_ */
|
||||
|
|
@ -28,42 +28,42 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "workqueues.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/utils/workqueues.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
/*****************************************************
|
||||
* CONSTANTS *
|
||||
*****************************************************/
|
||||
|
||||
#define SFLC_QUEUES_WRITE_WQ_NAME "sflc_write_workqueue"
|
||||
#define SFLC_QUEUES_DECRYPT_WQ_NAME "sflc_decrypt_workqueue"
|
||||
#define SFLEGC_QUEUES_WRITE_WQ_NAME "sflegc_write_workqueue"
|
||||
#define SFLEGC_QUEUES_DECRYPT_WQ_NAME "sflegc_decrypt_workqueue"
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC VARIABLES DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
struct workqueue_struct * sflc_queues_writeQueue;
|
||||
struct workqueue_struct * sflc_queues_decryptQueue;
|
||||
struct workqueue_struct * sflegc_queues_writeQueue;
|
||||
struct workqueue_struct * sflegc_queues_decryptQueue;
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
int sflc_queues_init(void)
|
||||
int sflegc_queues_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Write workqueue */
|
||||
sflc_queues_writeQueue = create_workqueue(SFLC_QUEUES_WRITE_WQ_NAME);
|
||||
if (!sflc_queues_writeQueue) {
|
||||
sflegc_queues_writeQueue = create_workqueue(SFLEGC_QUEUES_WRITE_WQ_NAME);
|
||||
if (!sflegc_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) {
|
||||
sflegc_queues_decryptQueue = create_workqueue(SFLEGC_QUEUES_DECRYPT_WQ_NAME);
|
||||
if (!sflegc_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(sflegc_queues_writeQueue);
|
||||
err_write_queue:
|
||||
return err;
|
||||
}
|
||||
|
||||
void sflc_queues_exit(void)
|
||||
void sflegc_queues_exit(void)
|
||||
{
|
||||
destroy_workqueue(sflc_queues_decryptQueue);
|
||||
destroy_workqueue(sflc_queues_writeQueue);
|
||||
destroy_workqueue(sflegc_queues_decryptQueue);
|
||||
destroy_workqueue(sflegc_queues_writeQueue);
|
||||
}
|
||||
|
|
@ -25,8 +25,8 @@
|
|||
* A set of workqueues
|
||||
*/
|
||||
|
||||
#ifndef _SFLC_UTILS_QUEUES_H_
|
||||
#define _SFLC_UTILS_QUEUES_H_
|
||||
#ifndef _SFLEGC_UTILS_QUEUES_H_
|
||||
#define _SFLEGC_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 * sflegc_queues_writeQueue;
|
||||
extern struct workqueue_struct * sflegc_queues_decryptQueue;
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
int sflc_queues_init(void);
|
||||
void sflc_queues_exit(void);
|
||||
int sflegc_queues_init(void);
|
||||
void sflegc_queues_exit(void);
|
||||
|
||||
|
||||
#endif /* _SFLC_UTILS_QUEUES_H_ */
|
||||
#endif /* _SFLEGC_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 "legacy/volume/volume.h"
|
||||
#include "legacy/crypto/rand/rand.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/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 sflegc_vol_mapSlice(sflegc_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 sflegc_vol_remapSector(sflegc_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;
|
||||
sflegc_Device *dev = vol->dev;
|
||||
|
||||
/* Start by scaling down to a Shufflecake sector */
|
||||
log_sector /= SFLC_DEV_SECTOR_SCALE;
|
||||
log_sector /= SFLEGC_DEV_SECTOR_SCALE;
|
||||
|
||||
/* Get the logical slice index it belongs to */
|
||||
lsi = log_sector / SFLC_VOL_LOG_SLICE_SIZE;
|
||||
lsi = log_sector / SFLEGC_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 % SFLEGC_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 = sflegc_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 * SFLEGC_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 *= SFLEGC_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 sflegc_vol_loadFmap(sflegc_Volume * vol)
|
||||
{
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_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(sflegc_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(sflegc_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 = sflegc_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 < SFLEGC_DEV_SECTOR_TO_IV_RATIO && lsi < dev->tot_slices; j++) {
|
||||
/* Load the data block */
|
||||
err = sflc_dev_rwSector(dev, data_page, sector, READ);
|
||||
err = sflegc_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 = sflegc_sk_decrypt(vol->skctx, data_ptr, data_ptr, SFLEGC_DEV_SECTOR_SIZE, (iv_ptr + j*SFLEGC_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 < SFLEGC_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 != SFLEGC_VOL_FMAP_INVALID_PSI) {
|
||||
sflegc_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, sflegc_pools_pagePool);
|
||||
mempool_free(data_page, sflegc_pools_pagePool);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Stores (and encrypts) the position map to the volume's header */
|
||||
int sflc_vol_storeFmap(sflc_Volume * vol)
|
||||
int sflegc_vol_storeFmap(sflegc_Volume * vol)
|
||||
{
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_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(sflegc_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(sflegc_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 = sflegc_rand_getBytes(iv_ptr, SFLEGC_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 = sflegc_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 < SFLEGC_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 < SFLEGC_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 = sflegc_sk_encrypt(vol->skctx, data_ptr, data_ptr, SFLEGC_DEV_SECTOR_SIZE, (iv_ptr + j*SFLEGC_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 = sflegc_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, sflegc_pools_pagePool);
|
||||
mempool_free(data_page, sflegc_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 sflegc_vol_mapSlice(sflegc_Volume * vol, u32 lsi, int op)
|
||||
{
|
||||
s32 psi;
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_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] != SFLEGC_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 = sflegc_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);
|
||||
sflegc_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 "legacy/volume/volume.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/utils/workqueues.h"
|
||||
#include "legacy/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 sflegc_vol_remapBioFast(sflegc_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 = sflegc_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 sflegc_vol_processBio(sflegc_Volume * vol, struct bio * bio)
|
||||
{
|
||||
sflc_vol_WriteWork * write_work;
|
||||
sflegc_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);
|
||||
sflegc_vol_doRead(vol, bio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate writeWork structure */
|
||||
write_work = mempool_alloc(sflc_pools_writeWorkPool, GFP_NOIO);
|
||||
write_work = mempool_alloc(sflegc_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, sflegc_vol_doWrite);
|
||||
|
||||
/* Enqueue */
|
||||
queue_work(sflc_queues_writeQueue, &write_work->work);
|
||||
queue_work(sflegc_queues_writeQueue, &write_work->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -32,10 +32,10 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "volume.h"
|
||||
#include "utils/pools.h"
|
||||
#include "utils/workqueues.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/volume/volume.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/utils/workqueues.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
#include <linux/bio.h>
|
||||
|
||||
|
|
@ -47,28 +47,28 @@
|
|||
* PRIVATE FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
static void sflc_vol_fillBioWithZeros(struct bio * orig_bio);
|
||||
static void sflc_vol_readEndIo(struct bio * phys_bio);
|
||||
static void sflc_vol_readEndIoBottomHalf(struct work_struct * work);
|
||||
static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice);
|
||||
static int sflc_vol_fetchIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice);
|
||||
static void sflegc_vol_fillBioWithZeros(struct bio * orig_bio);
|
||||
static void sflegc_vol_readEndIo(struct bio * phys_bio);
|
||||
static void sflegc_vol_readEndIoBottomHalf(struct work_struct * work);
|
||||
static int sflegc_vol_decryptBio(sflegc_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice);
|
||||
static int sflegc_vol_fetchIv(sflegc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice);
|
||||
|
||||
/*****************************************************
|
||||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Executed in context from sflc_tgt_map() */
|
||||
void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio)
|
||||
/* Executed in context from sflegc_tgt_map() */
|
||||
void sflegc_vol_doRead(sflegc_Volume * vol, struct bio * bio)
|
||||
{
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_Device * dev = vol->dev;
|
||||
struct bio * orig_bio = bio;
|
||||
struct bio * phys_bio;
|
||||
s64 phys_sector;
|
||||
sflc_vol_DecryptWork * dec_work;
|
||||
sflegc_vol_DecryptWork * dec_work;
|
||||
blk_status_t status;
|
||||
|
||||
/* Allocate decryptWork structure */
|
||||
dec_work = mempool_alloc(sflc_pools_decryptWorkPool, GFP_NOIO);
|
||||
dec_work = mempool_alloc(sflegc_pools_decryptWorkPool, GFP_NOIO);
|
||||
if (!dec_work) {
|
||||
pr_err("Could not allocate decryptWork structure\n");
|
||||
status = BLK_STS_IOERR;
|
||||
|
|
@ -83,7 +83,7 @@ void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio)
|
|||
we can decrypt in place. */
|
||||
|
||||
/* Shallow copy */
|
||||
phys_bio = bio_alloc_clone(dev->bdev->bdev, orig_bio, GFP_NOIO, &sflc_pools_bioset);
|
||||
phys_bio = bio_alloc_clone(dev->bdev->bdev, orig_bio, GFP_NOIO, &sflegc_pools_bioset);
|
||||
if (!phys_bio) {
|
||||
pr_err("Could not clone original bio\n");
|
||||
status = BLK_STS_IOERR;
|
||||
|
|
@ -91,11 +91,11 @@ void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio)
|
|||
}
|
||||
|
||||
/* Remap sector */
|
||||
phys_sector = sflc_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, READ, &dec_work->psi, &dec_work->off_in_slice);
|
||||
phys_sector = sflegc_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, READ, &dec_work->psi, &dec_work->off_in_slice);
|
||||
/* If -ENXIO, special case: stupid READ */
|
||||
if (phys_sector == -ENXIO) {
|
||||
pr_debug("Stupid READ. Returning all zeros\n");
|
||||
sflc_vol_fillBioWithZeros(orig_bio);
|
||||
sflegc_vol_fillBioWithZeros(orig_bio);
|
||||
status = BLK_STS_OK;
|
||||
goto err_stupid_read;
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio)
|
|||
dec_work->orig_bio = orig_bio;
|
||||
dec_work->phys_bio = phys_bio;
|
||||
/* Set fields for the endio */
|
||||
phys_bio->bi_end_io = sflc_vol_readEndIo;
|
||||
phys_bio->bi_end_io = sflegc_vol_readEndIo;
|
||||
phys_bio->bi_private = dec_work;
|
||||
|
||||
/* Only submit the physical bio */
|
||||
|
|
@ -127,7 +127,7 @@ err_stupid_read:
|
|||
bio_put(phys_bio);
|
||||
err_clone_orig_bio:
|
||||
bio_put(orig_bio);
|
||||
mempool_free(dec_work, sflc_pools_decryptWorkPool);
|
||||
mempool_free(dec_work, sflegc_pools_decryptWorkPool);
|
||||
err_alloc_dec_work:
|
||||
|
||||
orig_bio->bi_status = status;
|
||||
|
|
@ -139,42 +139,42 @@ err_alloc_dec_work:
|
|||
* PRIVATE FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
static void sflc_vol_fillBioWithZeros(struct bio * orig_bio)
|
||||
static void sflegc_vol_fillBioWithZeros(struct bio * orig_bio)
|
||||
{
|
||||
struct bio_vec bvl = bio_iovec(orig_bio);
|
||||
void * sector_ptr = kmap(bvl.bv_page) + bvl.bv_offset;
|
||||
|
||||
memset(sector_ptr, 0, SFLC_DEV_SECTOR_SIZE);
|
||||
bio_advance(orig_bio, SFLC_DEV_SECTOR_SIZE);
|
||||
memset(sector_ptr, 0, SFLEGC_DEV_SECTOR_SIZE);
|
||||
bio_advance(orig_bio, SFLEGC_DEV_SECTOR_SIZE);
|
||||
|
||||
kunmap(bvl.bv_page);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pushes all the decryption work to a workqueue bottom half */
|
||||
static void sflc_vol_readEndIo(struct bio * phys_bio)
|
||||
static void sflegc_vol_readEndIo(struct bio * phys_bio)
|
||||
{
|
||||
sflc_vol_DecryptWork * dec_work = phys_bio->bi_private;
|
||||
sflegc_vol_DecryptWork * dec_work = phys_bio->bi_private;
|
||||
|
||||
/* Init work structure */
|
||||
INIT_WORK(&dec_work->work, sflc_vol_readEndIoBottomHalf);
|
||||
INIT_WORK(&dec_work->work, sflegc_vol_readEndIoBottomHalf);
|
||||
/* Enqueue it */
|
||||
queue_work(sflc_queues_decryptQueue, &dec_work->work);
|
||||
queue_work(sflegc_queues_decryptQueue, &dec_work->work);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void sflc_vol_readEndIoBottomHalf(struct work_struct * work)
|
||||
static void sflegc_vol_readEndIoBottomHalf(struct work_struct * work)
|
||||
{
|
||||
sflc_vol_DecryptWork * dec_work = container_of(work, sflc_vol_DecryptWork, work);
|
||||
sflc_Volume * vol = dec_work->vol;
|
||||
sflegc_vol_DecryptWork * dec_work = container_of(work, sflegc_vol_DecryptWork, work);
|
||||
sflegc_Volume * vol = dec_work->vol;
|
||||
struct bio * orig_bio = dec_work->orig_bio;
|
||||
struct bio * phys_bio = dec_work->phys_bio;
|
||||
blk_status_t status = phys_bio->bi_status;
|
||||
int err;
|
||||
|
||||
/* Decrypt the physical bio and advance the original bio */
|
||||
err = sflc_vol_decryptBio(vol, orig_bio, dec_work->psi, dec_work->off_in_slice);
|
||||
err = sflegc_vol_decryptBio(vol, orig_bio, dec_work->psi, dec_work->off_in_slice);
|
||||
if (err) {
|
||||
pr_err("Could not decrypt bio; error %d\n", err);
|
||||
status = BLK_STS_IOERR;
|
||||
|
|
@ -189,19 +189,19 @@ static void sflc_vol_readEndIoBottomHalf(struct work_struct * work)
|
|||
/* Free the physical bio */
|
||||
bio_put(phys_bio);
|
||||
/* Free the work item */
|
||||
mempool_free(dec_work, sflc_pools_decryptWorkPool);
|
||||
mempool_free(dec_work, sflegc_pools_decryptWorkPool);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decrypts the content of the physical bio, and at the same time it advances the original bio */
|
||||
static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice)
|
||||
static int sflegc_vol_decryptBio(sflegc_Volume * vol, struct bio * orig_bio, u32 psi, u32 off_in_slice)
|
||||
{
|
||||
u8 iv[SFLC_SK_IV_LEN];
|
||||
u8 iv[SFLEGC_SK_IV_LEN];
|
||||
int err;
|
||||
|
||||
/* Fetch IV */
|
||||
err = sflc_vol_fetchIv(vol, iv, psi, off_in_slice);
|
||||
err = sflegc_vol_fetchIv(vol, iv, psi, off_in_slice);
|
||||
if (err) {
|
||||
pr_err("Could not fetch IV; error %d\n", err);
|
||||
return err;
|
||||
|
|
@ -210,7 +210,7 @@ static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi
|
|||
/* Decrypt sector in place */
|
||||
struct bio_vec bvl = bio_iovec(orig_bio);
|
||||
void * sector_ptr = kmap(bvl.bv_page) + bvl.bv_offset;
|
||||
err = sflc_sk_decrypt(vol->skctx, sector_ptr, sector_ptr, SFLC_DEV_SECTOR_SIZE, iv);
|
||||
err = sflegc_sk_decrypt(vol->skctx, sector_ptr, sector_ptr, SFLEGC_DEV_SECTOR_SIZE, iv);
|
||||
kunmap(bvl.bv_page);
|
||||
if (err) {
|
||||
pr_err("Error while decrypting sector: %d\n", err);
|
||||
|
|
@ -218,19 +218,19 @@ static int sflc_vol_decryptBio(sflc_Volume * vol, struct bio * orig_bio, u32 psi
|
|||
}
|
||||
|
||||
/* Advance original bio by one sector */
|
||||
bio_advance(orig_bio, SFLC_DEV_SECTOR_SIZE);
|
||||
bio_advance(orig_bio, SFLEGC_DEV_SECTOR_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sflc_vol_fetchIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice)
|
||||
static int sflegc_vol_fetchIv(sflegc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice)
|
||||
{
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_Device * dev = vol->dev;
|
||||
u8 * iv_block;
|
||||
int err;
|
||||
|
||||
/* Acquire a reference to the whole relevant IV block */
|
||||
iv_block = sflc_dev_getIvBlockRef(dev, psi, READ);
|
||||
iv_block = sflegc_dev_getIvBlockRef(dev, psi, READ);
|
||||
if (IS_ERR(iv_block)) {
|
||||
err = PTR_ERR(iv_block);
|
||||
pr_err("Could not acquire reference to IV block; error %ld\n", PTR_ERR(iv_block));
|
||||
|
|
@ -238,10 +238,10 @@ static int sflc_vol_fetchIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slic
|
|||
}
|
||||
|
||||
/* Copy the relevant portion */
|
||||
memcpy(iv, iv_block + (off_in_slice * SFLC_SK_IV_LEN), SFLC_SK_IV_LEN);
|
||||
memcpy(iv, iv_block + (off_in_slice * SFLEGC_SK_IV_LEN), SFLEGC_SK_IV_LEN);
|
||||
|
||||
/* Release reference to the IV block */
|
||||
err = sflc_dev_putIvBlockRef(dev, psi);
|
||||
err = sflegc_dev_putIvBlockRef(dev, psi);
|
||||
if (err) {
|
||||
pr_err("Could not release reference to IV block; error %d\n", err);
|
||||
goto err_put_iv_block_ref;
|
||||
|
|
@ -29,8 +29,9 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "volume.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/volume/volume.h"
|
||||
#include "legacy/utils/string.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
|
|
@ -39,35 +40,69 @@
|
|||
* PUBLIC FUNCTIONS DEFINITIONS *
|
||||
*****************************************************/
|
||||
|
||||
/* Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful */
|
||||
sflc_Volume * sflc_vol_create(struct dm_target *ti, sflc_Device *dev, int vol_idx, u8 * enckey)
|
||||
/**
|
||||
* Creates volume. 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)
|
||||
*/
|
||||
sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev,
|
||||
int argc, char **argv, struct kobject *kobj)
|
||||
{
|
||||
sflc_Volume * vol;
|
||||
sflegc_Volume * vol;
|
||||
int vol_idx;
|
||||
u8 enckey[SFLEGC_SK_KEY_LEN];
|
||||
int err;
|
||||
|
||||
pr_debug("Called to create sflc_Volume #%d on Device %s\n", vol_idx, dev->bdev_path);
|
||||
|
||||
/* Allocate volume */
|
||||
vol = kzalloc(sizeof(sflc_Volume), GFP_KERNEL);
|
||||
vol = kzalloc(sizeof(sflegc_Volume), GFP_KERNEL);
|
||||
if (!vol) {
|
||||
pr_err("Could not allocate %lu bytes for sflc_Volume\n", sizeof(sflc_Volume));
|
||||
pr_err("Could not allocate %lu bytes for sflegc_Volume\n", sizeof(sflegc_Volume));
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_vol;
|
||||
}
|
||||
|
||||
/* Parse args */
|
||||
if (argc != 6) {
|
||||
pr_err("Wrong argument count");
|
||||
err = -EINVAL;
|
||||
goto err_parse;
|
||||
}
|
||||
if (sscanf(argv[3], "%u", &vol_idx) != 1) {
|
||||
pr_err("Could not decode tot_slices\n");
|
||||
err = -EINVAL;
|
||||
goto err_parse;
|
||||
}
|
||||
/* Decode the encryption key */
|
||||
if (strlen(argv[5]) != 2 * SFLEGC_SK_KEY_LEN) {
|
||||
pr_err("Hexadecimal key (length %lu): %s\n", strlen(argv[5]), argv[5]);
|
||||
err = -EINVAL;
|
||||
goto err_parse;
|
||||
}
|
||||
err = sflegc_str_hexDecode(argv[5], enckey);
|
||||
if (err) {
|
||||
pr_err("Could not decode hexadecimal encryption key");
|
||||
err = -EINVAL;
|
||||
goto err_parse;
|
||||
}
|
||||
|
||||
/* Set volume name */
|
||||
sprintf(vol->vol_name, "sflc_%lu_%d", dev->dev_id, vol_idx);
|
||||
sprintf(vol->vol_name, "sflc_%u_%d", dev->dev_id, vol_idx);
|
||||
|
||||
/* Sysfs stuff */
|
||||
vol->kvol = sflc_sysfs_volCreateAndAdd(vol);
|
||||
if (IS_ERR(vol->kvol)) {
|
||||
err = PTR_ERR(vol->kvol);
|
||||
pr_err("Could not create sysfs entry; error %d\n", err);
|
||||
vol->kobj_parent = kobj;
|
||||
err = sflegc_sysfs_add_volume(vol);
|
||||
if (err) {
|
||||
pr_err("Could not add volume to sysfs; error %d\n", err);
|
||||
goto err_sysfs;
|
||||
}
|
||||
|
||||
/* Backing device */
|
||||
if (!sflc_dev_addVolume(dev, vol, vol_idx)) {
|
||||
if (!sflegc_dev_addVolume(dev, vol, vol_idx)) {
|
||||
pr_err("Could not add volume to device\n");
|
||||
err = -EINVAL;
|
||||
goto err_add_to_dev;
|
||||
|
|
@ -76,7 +111,7 @@ sflc_Volume * sflc_vol_create(struct dm_target *ti, sflc_Device *dev, int vol_id
|
|||
vol->vol_idx = vol_idx;
|
||||
|
||||
/* Crypto */
|
||||
vol->skctx = sflc_sk_createContext(enckey);
|
||||
vol->skctx = sflegc_sk_createContext(enckey);
|
||||
if (IS_ERR(vol->skctx)) {
|
||||
err = PTR_ERR(vol->skctx);
|
||||
pr_err("Could not create crypto context\n");
|
||||
|
|
@ -97,38 +132,52 @@ sflc_Volume * sflc_vol_create(struct dm_target *ti, sflc_Device *dev, int vol_id
|
|||
|
||||
/* Initialise fmap */
|
||||
pr_notice("Volume opening for volume %s: loading fmap from header\n", vol->vol_name);
|
||||
err = sflc_vol_loadFmap(vol);
|
||||
err = sflegc_vol_loadFmap(vol);
|
||||
if (err) {
|
||||
pr_err("Could not load position map; error %d\n", err);
|
||||
goto err_load_fmap;
|
||||
}
|
||||
pr_debug("Successfully loaded position map for volume %s\n", vol->vol_name);
|
||||
|
||||
|
||||
/* Tell DM we want one SFLC sector at a time */
|
||||
ti->max_io_len = SFLEGC_DEV_SECTOR_SCALE;
|
||||
/* Enable REQ_OP_FLUSH bios */
|
||||
ti->num_flush_bios = 1;
|
||||
/* Disable REQ_OP_WRITE_ZEROES and REQ_OP_SECURE_ERASE (can't be passed through as
|
||||
they would break deniability, and they would be too complicated to handle individually) */
|
||||
ti->num_secure_erase_bios = 0;
|
||||
ti->num_write_zeroes_bios = 0;
|
||||
/* Momentarily disable REQ_OP_DISCARD_BIOS
|
||||
TODO: will need to support them to release slice mappings */
|
||||
ti->num_discard_bios = 0;
|
||||
|
||||
return vol;
|
||||
|
||||
|
||||
err_load_fmap:
|
||||
vfree(vol->fmap);
|
||||
err_alloc_fmap:
|
||||
sflc_sk_destroyContext(vol->skctx);
|
||||
sflegc_sk_destroyContext(vol->skctx);
|
||||
err_create_skctx:
|
||||
sflc_dev_removeVolume(vol->dev, vol->vol_idx);
|
||||
sflegc_dev_removeVolume(vol->dev, vol->vol_idx);
|
||||
err_add_to_dev:
|
||||
sflc_sysfs_putVol(vol->kvol);
|
||||
sflegc_sysfs_remove_volume(vol);
|
||||
err_sysfs:
|
||||
err_parse:
|
||||
kfree(vol);
|
||||
err_alloc_vol:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* Removes the volume from the device and frees it. */
|
||||
void sflc_vol_destroy(struct dm_target * ti, sflc_Volume * vol)
|
||||
void sflegc_vol_destroy(sflegc_Volume * vol)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Store fmap */
|
||||
pr_notice("Going to store position map of volume %s\n", vol->vol_name);
|
||||
err = sflc_vol_storeFmap(vol);
|
||||
err = sflegc_vol_storeFmap(vol);
|
||||
if (err) {
|
||||
pr_err("Could not store position map; error %d\n", err);
|
||||
}
|
||||
|
|
@ -137,13 +186,13 @@ void sflc_vol_destroy(struct dm_target * ti, sflc_Volume * vol)
|
|||
vfree(vol->fmap);
|
||||
|
||||
/* Skctx */
|
||||
sflc_sk_destroyContext(vol->skctx);
|
||||
sflegc_sk_destroyContext(vol->skctx);
|
||||
|
||||
/* Remove from device */
|
||||
sflc_dev_removeVolume(vol->dev, vol->vol_idx);
|
||||
sflegc_dev_removeVolume(vol->dev, vol->vol_idx);
|
||||
|
||||
/* Destroy sysfs entries */
|
||||
sflc_sysfs_putVol(vol->kvol);
|
||||
sflegc_sysfs_remove_volume(vol);
|
||||
|
||||
/* Free volume structure */
|
||||
kfree(vol);
|
||||
|
|
@ -26,8 +26,8 @@
|
|||
* a "real" device represented by a device.
|
||||
*/
|
||||
|
||||
#ifndef _SFLC_VOLUME_VOLUME_H_
|
||||
#define _SFLC_VOLUME_VOLUME_H_
|
||||
#ifndef _SFLEGC_VOLUME_VOLUME_H_
|
||||
#define _SFLEGC_VOLUME_VOLUME_H_
|
||||
|
||||
|
||||
/*****************************************************
|
||||
|
|
@ -36,9 +36,9 @@
|
|||
|
||||
/* Necessary since device.h, volume.h, and sysfs.h all include each other */
|
||||
|
||||
typedef struct sflc_vol_write_work_s sflc_vol_WriteWork;
|
||||
typedef struct sflc_vol_decrypt_work_s sflc_vol_DecryptWork;
|
||||
typedef struct sflc_volume_s sflc_Volume;
|
||||
typedef struct sflegc_vol_write_work_s sflegc_vol_WriteWork;
|
||||
typedef struct sflegc_vol_decrypt_work_s sflegc_vol_DecryptWork;
|
||||
typedef struct sflegc_volume_s sflegc_Volume;
|
||||
|
||||
|
||||
/*****************************************************
|
||||
|
|
@ -47,9 +47,9 @@ typedef struct sflc_volume_s sflc_Volume;
|
|||
|
||||
#include <linux/blk_types.h>
|
||||
|
||||
#include "device/device.h"
|
||||
#include "crypto/symkey/symkey.h"
|
||||
#include "sysfs/sysfs.h"
|
||||
#include "legacy/sflc_legacy.h"
|
||||
#include "legacy/device/device.h"
|
||||
#include "legacy/crypto/symkey/symkey.h"
|
||||
|
||||
|
||||
/*****************************************************
|
||||
|
|
@ -57,26 +57,26 @@ typedef struct sflc_volume_s sflc_Volume;
|
|||
*****************************************************/
|
||||
|
||||
/* A single header data block contains 1024 fmap mappings */
|
||||
#define SFLC_VOL_HEADER_MAPPINGS_PER_BLOCK (SFLC_DEV_SECTOR_SIZE / sizeof(u32))
|
||||
#define SFLEGC_VOL_HEADER_MAPPINGS_PER_BLOCK (SFLEGC_DEV_SECTOR_SIZE / sizeof(u32))
|
||||
|
||||
/* We split the volume's logical addressing space into 1 MB slices */
|
||||
#define SFLC_VOL_LOG_SLICE_SIZE 256 // In 4096-byte sectors
|
||||
#define SFLEGC_VOL_LOG_SLICE_SIZE 256 // In 4096-byte sectors
|
||||
|
||||
/* Value marking an LSI as unassigned */
|
||||
#define SFLC_VOL_FMAP_INVALID_PSI 0xFFFFFFFFU
|
||||
#define SFLEGC_VOL_FMAP_INVALID_PSI 0xFFFFFFFFU
|
||||
|
||||
/* The volume name is "sflc-<devID>-<volIdx>" */
|
||||
#define SFLC_VOL_NAME_MAX_LEN 12
|
||||
#define SFLEGC_VOL_NAME_MAX_LEN 12
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* TYPES *
|
||||
*****************************************************/
|
||||
|
||||
struct sflc_vol_write_work_s
|
||||
struct sflegc_vol_write_work_s
|
||||
{
|
||||
/* Essential information */
|
||||
sflc_Volume * vol;
|
||||
sflegc_Volume * vol;
|
||||
struct bio * orig_bio;
|
||||
|
||||
/* Write requests need to allocate own page */
|
||||
|
|
@ -86,10 +86,10 @@ struct sflc_vol_write_work_s
|
|||
struct work_struct work;
|
||||
};
|
||||
|
||||
struct sflc_vol_decrypt_work_s
|
||||
struct sflegc_vol_decrypt_work_s
|
||||
{
|
||||
/* Essential information */
|
||||
sflc_Volume * vol;
|
||||
sflegc_Volume * vol;
|
||||
struct bio * orig_bio;
|
||||
struct bio * phys_bio;
|
||||
|
||||
|
|
@ -101,15 +101,15 @@ struct sflc_vol_decrypt_work_s
|
|||
struct work_struct work;
|
||||
};
|
||||
|
||||
struct sflc_volume_s
|
||||
struct sflegc_volume_s
|
||||
{
|
||||
/* Name of the volume, sflc-<devID>-<volIdx>*/
|
||||
char vol_name[SFLC_VOL_NAME_MAX_LEN + 1];
|
||||
/* Name of the volume, sflc_<devID>_<volIdx>*/
|
||||
char vol_name[SFLEGC_VOL_NAME_MAX_LEN + 1];
|
||||
|
||||
/* Backing device */
|
||||
sflc_Device * dev;
|
||||
sflegc_Device * dev;
|
||||
/* Index of this volume within the device's volume array */
|
||||
int vol_idx;
|
||||
u32 vol_idx;
|
||||
|
||||
/* Forward position map */
|
||||
struct mutex fmap_lock;
|
||||
|
|
@ -117,11 +117,11 @@ struct sflc_volume_s
|
|||
/* Stats on the fmap */
|
||||
u32 mapped_slices;
|
||||
|
||||
/* Sysfs stuff */
|
||||
sflc_sysfs_Volume * kvol;
|
||||
/* Parent sysfs directory */
|
||||
struct kobject *kobj_parent;
|
||||
|
||||
/* Crypto */
|
||||
sflc_sk_Context * skctx;
|
||||
sflegc_sk_Context * skctx;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -130,27 +130,28 @@ struct sflc_volume_s
|
|||
*****************************************************/
|
||||
|
||||
/* Creates volume and adds it to the device. Returns an ERR_PTR() if unsuccessful */
|
||||
sflc_Volume * sflc_vol_create(struct dm_target * ti, sflc_Device* dev, int vol_idx, u8 * enckey);
|
||||
sflegc_Volume * sflegc_vol_create(struct dm_target * ti, sflegc_Device* dev,
|
||||
int argc, char **argv, struct kobject *kobj);
|
||||
/* Removes the volume from the device and frees it. */
|
||||
void sflc_vol_destroy(struct dm_target * ti, sflc_Volume * vol);
|
||||
void sflegc_vol_destroy(sflegc_Volume * vol);
|
||||
|
||||
/* Remaps the underlying block device and the sector number */
|
||||
int sflc_vol_remapBioFast(sflc_Volume * vol, struct bio * bio);
|
||||
int sflegc_vol_remapBioFast(sflegc_Volume * vol, struct bio * bio);
|
||||
/* Processes the bio in the normal indirection+crypto way */
|
||||
int sflc_vol_processBio(sflc_Volume * vol, struct bio * bio);
|
||||
int sflegc_vol_processBio(sflegc_Volume * vol, struct bio * bio);
|
||||
|
||||
/* Executed in top half */
|
||||
void sflc_vol_doRead(sflc_Volume * vol, struct bio * bio);
|
||||
void sflegc_vol_doRead(sflegc_Volume * vol, struct bio * bio);
|
||||
/* Executed in bottom half */
|
||||
void sflc_vol_doWrite(struct work_struct * work);
|
||||
void sflegc_vol_doWrite(struct work_struct * work);
|
||||
|
||||
/* Maps a logical 512-byte sector to a physical 512-byte sector. Returns < 0 if error.
|
||||
* Specifically, if op == READ, and the logical slice is unmapped, -ENXIO is returned. */
|
||||
s64 sflc_vol_remapSector(sflc_Volume * vol, sector_t log_sector, int op, u32 * psi_out, u32 * off_in_slice_out);
|
||||
s64 sflegc_vol_remapSector(sflegc_Volume * vol, sector_t log_sector, int op, u32 * psi_out, u32 * off_in_slice_out);
|
||||
/* Loads (and decrypts) the position map from the volume's header */
|
||||
int sflc_vol_loadFmap(sflc_Volume * vol);
|
||||
int sflegc_vol_loadFmap(sflegc_Volume * vol);
|
||||
/* Stores (and encrypts) the position map to the volume's header */
|
||||
int sflc_vol_storeFmap(sflc_Volume * vol);
|
||||
int sflegc_vol_storeFmap(sflegc_Volume * vol);
|
||||
|
||||
|
||||
#endif /* _SFLC_VOLUME_VOLUME_H_ */
|
||||
#endif /* _SFLEGC_VOLUME_VOLUME_H_ */
|
||||
|
|
@ -32,10 +32,10 @@
|
|||
* INCLUDE SECTION *
|
||||
*****************************************************/
|
||||
|
||||
#include "volume.h"
|
||||
#include "crypto/rand/rand.h"
|
||||
#include "utils/pools.h"
|
||||
#include "log/log.h"
|
||||
#include "legacy/volume/volume.h"
|
||||
#include "legacy/crypto/rand/rand.h"
|
||||
#include "legacy/utils/pools.h"
|
||||
#include "legacy/log/log.h"
|
||||
|
||||
#include <linux/bio.h>
|
||||
|
||||
|
|
@ -47,9 +47,9 @@
|
|||
* PRIVATE FUNCTIONS PROTOTYPES *
|
||||
*****************************************************/
|
||||
|
||||
static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice);
|
||||
static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice);
|
||||
static void sflc_vol_writeEndIo(struct bio * phys_bio);
|
||||
static int sflegc_vol_encryptOrigBio(sflegc_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice);
|
||||
static int sflegc_vol_sampleAndWriteIv(sflegc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice);
|
||||
static void sflegc_vol_writeEndIo(struct bio * phys_bio);
|
||||
|
||||
/*****************************************************
|
||||
* PRIVATE VARIABLES *
|
||||
|
|
@ -60,11 +60,11 @@ static void sflc_vol_writeEndIo(struct bio * phys_bio);
|
|||
*****************************************************/
|
||||
|
||||
/* Executed in workqueue bottom half */
|
||||
void sflc_vol_doWrite(struct work_struct * work)
|
||||
void sflegc_vol_doWrite(struct work_struct * work)
|
||||
{
|
||||
sflc_vol_WriteWork * write_work = container_of(work, sflc_vol_WriteWork, work);
|
||||
sflc_Volume * vol = write_work->vol;
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_vol_WriteWork * write_work = container_of(work, sflegc_vol_WriteWork, work);
|
||||
sflegc_Volume * vol = write_work->vol;
|
||||
sflegc_Device * dev = vol->dev;
|
||||
struct bio * orig_bio = write_work->orig_bio;
|
||||
struct bio * phys_bio;
|
||||
s64 phys_sector;
|
||||
|
|
@ -80,14 +80,14 @@ void sflc_vol_doWrite(struct work_struct * work)
|
|||
non-owned bio's. So we need our own. */
|
||||
|
||||
/* Allocate an empty bio */
|
||||
phys_bio = bio_alloc_bioset(dev->bdev->bdev, bio_segments(orig_bio), orig_bio->bi_opf, GFP_NOIO, &sflc_pools_bioset);
|
||||
phys_bio = bio_alloc_bioset(dev->bdev->bdev, bio_segments(orig_bio), orig_bio->bi_opf, GFP_NOIO, &sflegc_pools_bioset);
|
||||
if (!phys_bio) {
|
||||
pr_err("Could not allocate bio\n");
|
||||
goto err_alloc_phys_bio;
|
||||
}
|
||||
|
||||
/* Remap sector */
|
||||
phys_sector = sflc_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, WRITE, &psi, &off_in_slice);
|
||||
phys_sector = sflegc_vol_remapSector(vol, orig_bio->bi_iter.bi_sector, WRITE, &psi, &off_in_slice);
|
||||
if (phys_sector < 0) {
|
||||
pr_err("Could not remap sector for physical bio; error %d\n", (int) phys_sector);
|
||||
goto err_remap_sector;
|
||||
|
|
@ -95,11 +95,11 @@ void sflc_vol_doWrite(struct work_struct * work)
|
|||
phys_bio->bi_iter.bi_sector = phys_sector;
|
||||
|
||||
/* Set fields for the endio */
|
||||
phys_bio->bi_end_io = sflc_vol_writeEndIo;
|
||||
phys_bio->bi_end_io = sflegc_vol_writeEndIo;
|
||||
phys_bio->bi_private = write_work;
|
||||
|
||||
/* Encrypt the original bio into the physical bio (newly-allocated pages) */
|
||||
int err = sflc_vol_encryptOrigBio(vol, orig_bio, phys_bio, psi, off_in_slice);
|
||||
int err = sflegc_vol_encryptOrigBio(vol, orig_bio, phys_bio, psi, off_in_slice);
|
||||
if (err) {
|
||||
pr_err("Could not encrypt original bio; error %d\n", err);
|
||||
goto err_encrypt_orig_bio;
|
||||
|
|
@ -119,7 +119,6 @@ err_alloc_phys_bio:
|
|||
|
||||
orig_bio->bi_status = BLK_STS_IOERR;
|
||||
bio_endio(orig_bio);
|
||||
mempool_free(write_work, sflc_pools_writeWorkPool);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -128,14 +127,14 @@ err_alloc_phys_bio:
|
|||
*****************************************************/
|
||||
|
||||
/* Encrypts the contents of the original bio into newly-allocated pages for the physical bio */
|
||||
static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice)
|
||||
static int sflegc_vol_encryptOrigBio(sflegc_Volume * vol, struct bio * orig_bio, struct bio * phys_bio, u32 psi, u32 off_in_slice)
|
||||
{
|
||||
sflc_vol_WriteWork * write_work = phys_bio->bi_private;
|
||||
u8 iv[SFLC_SK_IV_LEN];
|
||||
sflegc_vol_WriteWork * write_work = phys_bio->bi_private;
|
||||
u8 iv[SFLEGC_SK_IV_LEN];
|
||||
int err;
|
||||
|
||||
/* Allocate new page for the physical bio */
|
||||
write_work->page = mempool_alloc(sflc_pools_pagePool, GFP_NOIO);
|
||||
write_work->page = mempool_alloc(sflegc_pools_pagePool, GFP_NOIO);
|
||||
if (!write_work->page) {
|
||||
pr_err("Could not allocate page\n");
|
||||
err = -ENOMEM;
|
||||
|
|
@ -143,14 +142,14 @@ static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, str
|
|||
}
|
||||
|
||||
/* Add it to physical bio */
|
||||
if (!bio_add_page(phys_bio, write_work->page, SFLC_DEV_SECTOR_SIZE, 0)) {
|
||||
if (!bio_add_page(phys_bio, write_work->page, SFLEGC_DEV_SECTOR_SIZE, 0)) {
|
||||
pr_err("Catastrophe. Could not add page to copy bio. WTF?\n");
|
||||
err = -EIO;
|
||||
goto err_bio_add_page;
|
||||
}
|
||||
|
||||
/* Sample a random IV and write it in the IV block */
|
||||
err = sflc_vol_sampleAndWriteIv(vol, iv, psi, off_in_slice);
|
||||
err = sflegc_vol_sampleAndWriteIv(vol, iv, psi, off_in_slice);
|
||||
if (err) {
|
||||
pr_err("Could not sample and write IV; error %d\n", err);
|
||||
err = -EIO;
|
||||
|
|
@ -161,7 +160,7 @@ static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, str
|
|||
struct bio_vec bvl = bio_iovec(orig_bio);
|
||||
void * enc_sector_ptr = kmap(write_work->page);
|
||||
void * plain_sector_ptr = kmap(bvl.bv_page) + bvl.bv_offset;
|
||||
err = sflc_sk_encrypt(vol->skctx, plain_sector_ptr, enc_sector_ptr, SFLC_DEV_SECTOR_SIZE, iv);
|
||||
err = sflegc_sk_encrypt(vol->skctx, plain_sector_ptr, enc_sector_ptr, SFLEGC_DEV_SECTOR_SIZE, iv);
|
||||
kunmap(bvl.bv_page);
|
||||
kunmap(write_work->page);
|
||||
if (err) {
|
||||
|
|
@ -175,21 +174,21 @@ static int sflc_vol_encryptOrigBio(sflc_Volume * vol, struct bio * orig_bio, str
|
|||
err_encrypt:
|
||||
err_sample_and_write_iv:
|
||||
err_bio_add_page:
|
||||
mempool_free(write_work->page, sflc_pools_pagePool);
|
||||
mempool_free(write_work->page, sflegc_pools_pagePool);
|
||||
err_alloc_page:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Allocates the io_work's IV (will need to be freed afterwards), fills it with random
|
||||
bytes, and writes it into the IV block pointed by the io_work's PSI and off_in_slice. */
|
||||
static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice)
|
||||
static int sflegc_vol_sampleAndWriteIv(sflegc_Volume * vol, u8 * iv, u32 psi, u32 off_in_slice)
|
||||
{
|
||||
sflc_Device * dev = vol->dev;
|
||||
sflegc_Device * dev = vol->dev;
|
||||
u8 * iv_block;
|
||||
int err;
|
||||
|
||||
/* Sample IV */
|
||||
err = sflc_rand_getBytes(iv, SFLC_SK_IV_LEN);
|
||||
err = sflegc_rand_getBytes(iv, SFLEGC_SK_IV_LEN);
|
||||
if (err) {
|
||||
pr_err("Could not sample IV; error %d\n", err);
|
||||
err = -EIO;
|
||||
|
|
@ -197,7 +196,7 @@ static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 of
|
|||
}
|
||||
|
||||
/* Acquire a reference to the whole relevant IV block */
|
||||
iv_block = sflc_dev_getIvBlockRef(dev, psi, WRITE);
|
||||
iv_block = sflegc_dev_getIvBlockRef(dev, psi, WRITE);
|
||||
if (IS_ERR(iv_block)) {
|
||||
err = PTR_ERR(iv_block);
|
||||
pr_err("Could not acquire reference to IV block; error %d\n", err);
|
||||
|
|
@ -205,10 +204,10 @@ static int sflc_vol_sampleAndWriteIv(sflc_Volume * vol, u8 * iv, u32 psi, u32 of
|
|||
}
|
||||
|
||||
/* Copy it into the relevant portion of the block */
|
||||
memcpy(iv_block + (off_in_slice * SFLC_SK_IV_LEN), iv, SFLC_SK_IV_LEN);
|
||||
memcpy(iv_block + (off_in_slice * SFLEGC_SK_IV_LEN), iv, SFLEGC_SK_IV_LEN);
|
||||
|
||||
/* Release reference to the IV block */
|
||||
err = sflc_dev_putIvBlockRef(dev, psi);
|
||||
err = sflegc_dev_putIvBlockRef(dev, psi);
|
||||
if (err) {
|
||||
pr_err("Could not release reference to IV block; error %d\n", err);
|
||||
goto err_put_iv_block_ref;
|
||||
|
|
@ -223,9 +222,9 @@ err_sample_iv:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void sflc_vol_writeEndIo(struct bio * phys_bio)
|
||||
static void sflegc_vol_writeEndIo(struct bio * phys_bio)
|
||||
{
|
||||
sflc_vol_WriteWork * write_work = phys_bio->bi_private;
|
||||
sflegc_vol_WriteWork * write_work = phys_bio->bi_private;
|
||||
struct bio * orig_bio = write_work->orig_bio;
|
||||
unsigned completed_bytes;
|
||||
|
||||
|
|
@ -246,8 +245,8 @@ static void sflc_vol_writeEndIo(struct bio * phys_bio)
|
|||
if (unlikely(page_ref_count(write_work->page) != 1)) {
|
||||
pr_err("WTF: page_ref_count = %d\n", page_ref_count(write_work->page));
|
||||
}
|
||||
mempool_free(write_work->page, sflc_pools_pagePool);
|
||||
mempool_free(write_work, sflc_pools_writeWorkPool);
|
||||
mempool_free(write_work->page, sflegc_pools_pagePool);
|
||||
mempool_free(write_work, sflegc_pools_writeWorkPool);
|
||||
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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