A way to hide your secrets and denial plausibility

June 23, 2022

Although this article may still be useful, there's an updated version out there.

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:

losetup --offset 1234567 --sizelimit 360000 -f /dev/sda
cryptsetup open /dev/loop0 bootstrap --type plain
mount /dev/mapper/bootstrap /mnt/stuff
cd /

You can automate running the above sequence using some tiny device. Up to you. Just a hint.

One of these days

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:

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:

Be creative.

And don't forget to play tux racer and watch cats. Your dummy system should look regularly used.


Here it is.

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.


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.


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 /

That's all.

Note on system updates

To propagate apt updates and upgrades down to clobbered dummy system I used this script: sync-updates.


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.