A way to hide your secrets and denial plausibility
Obsolete
Although this article may still be useful, there's an updated version out there.
TLDR
The approach described below makes your computer looking an innocent toy, used only to play tux racer and watch cats on facebook. Forensics would find the data with abnormally high entropy in unused sectors, a few suspicious tweaks in your system, but none of explicit evidences of encryption. This may help to avoid rubber-hose cryptanalysis, highly possible if you used LUKS, Tomb, or simply encrypted your files.
This approach does not protect against all possible attacks, use it with care and be smart. I had been using that for about five years and now, when I no longer need it, I can disclose it. I never ran into troubles so I have no idea how's strong it in action. Now, anyone cleverer than me may criticize it and/or give more hints for others.
The approach in a nutshell:
- One or two partitions on your storage device: one for linux, another for data. The data partition is optional.
- The data partition may contain some data, however its main purpose is to keep hidden encrypted volumes in unused areas of the file system. Alternatively, these secret volumes can reside in unpartitioned space.
- A bootstrap script mounts secret volumes, clobbering /etc, /var, and other essential directories, and restarts essential services, thus turning your computer into a combat system.
- The bootstrap script is placed on some unused area of your storage device and you need to memorize a short sequence of commands and long enough passphrase for cryptsetup. Here's an example:
losetup --offset 1234567 --sizelimit 360000 -f /dev/sda cryptsetup open /dev/loop0 bootstrap --type plain mount /dev/mapper/bootstrap /mnt/stuff cd / /mnt/stuff/bootstrap
You can automate running the above sequence using some tiny device. Up to you. Just a hint.

Why losetup
That's because I have no idea how to use dm
for an arbitrary area of a storage device.
Loop devices can be created anywhere, even on a mounted partition. Of course, you should be careful and not to write anything to the file system. Or, if you know how space is allocated for particular file system, you can demonstrate to rubber-hose cryptanalysts that your data partition is not dummy and you can copy some files on it. Anyway, be prepared to lose your secret volumes and backup regularly.
losetup
approach is not reliable on Allwinner H3 based boards. I saw a lot of messages in dmesg
output about failed asynchronous operations. I don't remember the details and have no desire to repeat my research. RK33xx and Allwinner H6 based boards work very well.
Also, losetup
approach is not reliable with multiple loop devices behind dm
even on fast enough CPUs. I have no desire to dig into the problem again, I just warn.
The reliable approach is single loop device per encrypted volume.
Also, you'll have to turn TRIM off, otherwise your secret volumes will be destroyed.
Which file system to use for dummy data partition
I used ext4, despite vfat does not break free space into small regions. My choice. You can try other file systems.
Why cryptsetup --plain
LUKS exposes you.
You need to memorize long enough passphrase for plain mode. You'll need this passphrase only for tiny bootstrap volume. Your toolkit will mount all the rest.
Precautionary measures
You have to do the following basic things to avoid leaving traces:
- Disable swap.
- Use tmpfs for logs. If you're using Armbian, turn armbian-ramlog off because it writes logs back to memory card, use plain tmpfs for /var/log.
- Turn history off for root's shell.
Denial plausibility
All precautionary measures, cryptsetup
in the base system, TRIM turned off, and high entropy data in unused sectors may look highly suspicious. In case of rubber-hose cryptanalysis, possible defense is so-so. Although it's better than for explicitly encrypted data:
- I needed
cryptsetup
for my personal USB stick, - oh, here it is and the password is 12345! Don't tell my secrets to anyone, please. - Excessively tested storage device with random patterns. Yeah, look how smart I am!
- I've read that article and gave described approach a try. Total shit, I don't need it. Forgot to revert all tweaks and turn TRIM on, thanks for reminding. Bootstrap area? Oh, here it is, in the first 1MB right before the first partition! Offset 512000, sizelimit 512000, password 12345! (you point them to a dummy bootstrap, right?)
Be creative.
And don't forget to play tux racer and watch cats. Your dummy system should look regularly used.
Toolkit
Initially I tried to keep everything in a single file with no third-party dependencies, but with increased number of computers I moved common stuff to utils.py. Bootstrap routines are different for desktops and servers, I'll show you an example for server, as the simplest one. For desktop you'll have to mount a tmpfs to /home, create more users, and you'll need to restart display manager along with syslog and journald. I had multiple users for different tasks with their own VPN connections, with per-user routing.
Installation
I'm a Debian user, so all my notes are for Debian, but I suppose it's easy to adapt this approach for any linux distro or *BSD.
Before installing your favorite linux distro, fill your storage device with random data. Then, collect sector hashes for finding untouched areas after installation. I used blake2s with 8-bytes digest size. Here is the script: secha.py. Arguments:
python3 secha.py <action> <device> <output-filename> [<sector-size>]
sector-size
is optional, default value is 512.
Example:
python3 secha.py compute /dev/sda /mnt/usb-stick/sda-sector-hashes 4096
Create partitions. Two, at least. Carefully think your partitioning scheme through. You might need some gaps for bootstrap area if their offsets are easily memorable for you. However, I don't recommend using gaps. Remember, you'll have to explain any deviation from the 'quick install'.
Install your linux. Format your data partition and copy some legal files there. Some documentation, your family photos, etc.
Now find untouched areas on your storage devices using the same script:
python3 secha.py find-intact <device> <hashes-filename> [[[<start-lba> <end-lba>] <sector_size>] <min-length>]
hashes-filename
is output-filename
from previous run.
start-lba
and end-lba
are optional and let you narrow down your search.
min-length
is the minimum length of untouched area, in sectors. 1 by default.
Now, choose an area for bootstrap volume. You have to memorize where it starts and how big it is. For example, 360K would be more than enough for the size and it's easy to memorize such a number if you remember old good times when floppy disks were big.
losetup --offset 1234567 --sizelimit 360000 -f /dev/sda cryptsetup open /dev/loop0 bootstrap --type plain mkfs -t ext2 /dev/mapper/bootstrap
Mount created volume and copy utils.py and bootstrap script. You should review and customize it for your needs.
Prepare configuration file, like this. For simple cases with one big area, say, when you use vfat of unpartitioned space, you can generate such a config with makeconf.py from a simplified definition config_def.yaml.
Basically, you can create all secret volumes manually, same as bootstrap volume. However, setup.py can do this for you.
And when all necessary volumes are created and initialized, you're ready to bootstrap your combat system:
cd / /mnt/stuff/bootstrap
That's all.
Note on system updates
To propagate apt updates and upgrades down to clobbered dummy system I used this script: sync-updates.
Conclusion
If you found this approach useful, I won't refuse your satoshis bc1qwksstkxqu8a7e484k70fpa5euxv55f87fps53m. Basically, I don't need your money but I do need to thank my angel.