30 Jan 2023 [CT] [guides]

CT-012: Plausible deniability with VeraCrypt hidden volumes in Tails

This is the 12th report in the Cypherpunk Transmission series.


The VeraCrypt disk encryption tool can provide plausible deniability via hidden volumes and hidden operating systems.

This guide focuses on creating hidden volumes within file-hosted encrypted containers using VeraCrypt Console1 in Tails2.

Provided adequate security precautions3 are followed, an adversary should not be able to prove the existence of a hidden VC volume inside the file.


1. Configure Tails

1.1 Set up admininstration password

Restart your machine with the Tails USB plugged in.

At the Welcome to Tails! prompt click on + at the bottom of the screen to bring up the Additional Settings panel.

Turn the Administration Password ON and add a password. Click on Start Tails.

1.2 (Optional) Create exFat partition

This partition is useful for moving the VC encrypted volumes between Tails and other operating systems.

If you need this feature, do this before creating the persistent storage, which takes up all the free space on your device.

Navigate to Applications > Utilities > Disks.

Select the USB flash drive > click on Free Space and +.

Make sure to leave some free space for the persistent storage and click on Next > enter a Volume Name > Other > Next > select exFAT > Create and enter your admin password from step 1.1.

1.3 Create encrypted persistent storage

We can now allow Tails to use all the free space left on the USB stick to create the encrypted persistent storage partition.

Go to Applications > Favorites > Persistent Storage.

Choose a passphrase that will be used to unlock the encryption of the persistent storage (5-7 random words).

Click on Create and make sure the Persistent Folder and Additional Software switches are on/enabled. Close the window by pressing the top right x.

1.4 Establish network connection

If the network connection window didn’t pop up during the previous steps, we can manually enable Wi-Fi/ethernet by following the simple wizard in Applications > Tor Connection. Select Connect to tor automatically > and click on Connect to tor.

The output should be: Connected to tor successfully.

Note: if you want to use a bridge (CT-0095), configure it during this step.

2. Install VeraCrypt on persistent storage

2.1 Download VC Console

First check to see what the latest version of the VC Console Debian/Ubuntu package is:

torsocks curl https://launchpad.net/veracrypt/trunk/ | grep 'Latest version is'

Note: if the command fails, visit the downloads page on veracrypt.fr6.

You should get something like this: Latest version is 1.25.9.

Let’s set the release as an environment variable with:


Note: replace the number with the actual latest version.

Download the .deb package and associated PGP signature file to the persistent folder:

cd ~/Persistent/ && torsocks wget https://launchpad.net/veracrypt/trunk/$VERACRYPT_RELEASE/+download/veracrypt-console-$VERACRYPT_RELEASE-Debian-11-amd64.deb && torsocks wget https://launchpad.net/veracrypt/trunk/$VERACRYPT_RELEASE/+download/veracrypt-console-$VERACRYPT_RELEASE-Debian-11-amd64.deb.sig

2.2 Verify the download

Fetch the VC PGP public key:

torsocks wget https://www.idrix.fr/Veracrypt/Veracrypt_PGP_public_key.asc

Display the key’s fingerprint before importing it:

gpg --show-keys --with-fingerprint Veracrypt_PGP_public_key.asc

Output should be:

Key fingerpring = 5069 A233 D55A 0EEB 174A 5FC3 821A CD02 680D 16DE

Now display the fingerprint from the official website:

torsocks curl https://www.veracrypt.fr/en/Downloads.html | grep 'Fingerprint='

Only if the two fingerprints match, import the key:

gpg --import Veracrypt_PGP_public_key.asc

Output should confirm that you imported the key successfully: imported: 1.

Note: if any command fails, open the website in the tor browser and d/l the files manually.

Next we need to verify the release:

gpg --verify veracrypt-console-$VERACRYPT_RELEASE-Debian-11-amd64.deb.sig

Unless you get Good signature, stop and repeat the process from step 2.

2.3 Install VeraCrypt Console

sudo dpkg -i veracrypt-console-$VERACRYPT_RELEASE-Debian-11-amd64.deb

You can check the version with:

veracrypt --version

Note: .deb packages cannot be installed in persistent mode in Tails; copy the veracrypt binary from /usr/bin/ to your persistent folder if you want to use it later and don’t want to run dpkg after each reboot (ie. copy with cp /usr/bin/veracrypt ~/Persistent and run with ./veracrypt).

3. Create standard VeraCrypt outer volume

Note: in the command below, replace [OUTER_CONTAINER_PASSWORD] with the password for your outer volume and [VOLUME_PATH] with the path to your file container (file name and extension can be anything).

veracrypt -t -c -k '' --pim=0 --encryption=aes --hash=sha-512 --random-source=/dev/urandom --volume-type=normal --filesystem=ext4 -p [OUTER_CONTAINER_PASSWORD] --size=500M [VOLUME_PATH]

Enter the Tails admin password if/when asked.

You should see a new file created in your ~/Persistent folder named [OUTER_VOLUME_PATH]. That’s the outer encrypted volume that will contain the inner hidden volume.

4. Create hidden VeraCrypt inner volume

Note: replace [INNER_CONTAINER_PASSWORD] with the password for your inner volume and [VOLUME_PATH] with the path to your outer file container (same as the previous step).

veracrypt -t -c -k '' --pim=0 --encryption=aes --hash=sha-512 --random-source=/dev/urandom --volume-type=hidden --filesystem=ext4 -p [INNER_CONTAINER_PASSWORD] --size=100M [VOLUME_PATH]

You can modify the size of the volumes by passing a different value to the --size= flag.

5. Mounting and dismounting volumes

5.1 VC Console method

5.1.1 Mounting only the outer volume

veracrypt --mount [VOLUME_PATH] [VOLUME_MOUNT_LOCATION] --password [OUTER_CONTAINER_PASSWORD] --pim=0 -k '' --protect-hidden=no

note: replace [VOLUME_PATH] with the path to the encrypted VC file, [VOLUME_MOUNT_LOCATION] with the mount directory (ie. /media/veracrypt1), and [OUTER_CONTAINER_PASSWORD] with the password to the outer volume; if you run it with protect-hidden=yes you will be asked to provide the password to the inner container as well.

5.1.2 Mounting the hidden inner volume

veracrypt --mount [VOLUME_PATH] [VOLUME_MOUNT_LOCATION] --password [INNER_CONTAINER_PASSWORD] --pim=0 -k '' --protect-hidden=no

note: replace [INNER_CONTAINER_PASSWORD] with the password to the hidden inner volume; if you run into issues, try running veracrypt --mount with no additional parameters and follow the prompts.

5.1.3 Dismounting VC volumes

Perhaps the most convenient way is to dismount all mounted VC volumes:

veracrypt --dismount

Consult the output of veracrypt --help for the complete list of commands.

5.2 Tails VC GUI method

VeraCrypt volumes can also be unlocked using the built-in Unlock VeraCrypt Volumes Tails utility.

Access it via Applications > Utilities > Add > select encrypted VC file container and enter the password for the outer volume before clicking on Unlock.

To unlock the hidden volume, check the appropriate box and enter the hidden volume password instead.

That’s it.


You should now be able to achieve some plausible deniability by creating hidden volumes inside file-hosted VeraCrypt encrypted containers.


Let me know if you find this helpful and, depending on interest, I will do my best to post a new Cypherpunk Transmission report every (other?) Monday.

Questions, edits and suggestions are always appreciated @ /about/.


Credit goes to gnuteardrops from monero.graphics for the amazing xkcd graphic. Work and xkcd Script font licensed under CC BY-NC 3.0.