Encrypted cross-platform read/write volumes with tcplay

17 Aug 2016

tcplay is a reimplementation of truecrypt disk & disk-image encryption using dm-crypt. Originally for DragonflyBSD, it’s been ported and is in most Linux distro repositories. It’s compatible with VeraCrypt on Mac and Windows. The following describes how to create & use encrypted read/write volumes on a Linux host which can be used on Mac & Windows machines.

A note about filesystems

When creating an encrypted disk image you must choose an internal filesystem which is supported on each of the operating systems you need to work with. For instance, a tcplay-encrypted image containing an ext4 filesystem will not be usable (easily) on Windows. The main choices for all-platform compatibility are UDF and exFAT. Of the two exFAT has the fewest caveats (as of 2017 it “just works” for read/write support on Mac/Windows/Linux). If you only need to write on the host and read for restore operations on other platforms, then you could choose UDF or even potentially NTFS.

Creating a new container image

The process generally is: find an unused loopback device, allocate a new empty file of the size you need for this archive, attach the file to the loopback device, invoke tcplay.

losetup -f # find 1st unused loopback device e.g. /dev/loop3
fallocate -l 20G host-docs-backup.tc
losetup /dev/loop3 host-docs-backup.tc
tcplay --create -d /dev/loop3 --cipher AES-256-XTS --pbkdf-prf=whirlpool

That last line causes tcplay to create a container volume encrypted with AES-256 and the whirlpool hash function (a generally-recommended combination). Explore the docs if you want additional security in the shape of cascading encryption or hidden volumes. I just use it for portable encrypted volumes, so I stick to plain AES.

It will prompt for a password (there are options for keyfiles as well) then fill the file with random data. This can take a while if the container file is large.

You next need to map the volume and create a filesystem:

tcplay --map=wibble -d /dev/loop3
mkfs.exfat -n "HOST-BACKUP" /dev/mapper/wibble

Note that the tcplay --map option is the dm map name, it needs to be a simple unique string with no spaces or special characters. The -n option for mkfs.exfat provides a friendly volume name: you’ll see this when it’s a mounted volume on Windows/Mac for instance.

Then you can mount the device and use it like any other filesystem:

mount /dev/mapper/wibble /mnt
rsync -rvh /home/henry/Documents/Foo/ /mnt/

When you’re done, you can unmount the volume and release the loopback device like so:

umount /mnt
dmsetup remove wibble
losetup -d /dev/loop3

Mounting an existing container with tcplay

The process here is: attach container file to loopback device, map and decrypt the container with tcplay, mount the volume.

losetup -f  # let's assume this returns /dev/loop3 again
losetup /dev/loop3 /path/to/container.tc
tcplay --map=wibble --device=/dev/loop3
mount -o nodev,nosuid /dev/mapper/wibble /mnt

You can now read/write from/to the volume as usual. Note: if your container is using a filesystem with POSIX owner/permission support like xfs, ext4 etc. then you’ll need to tweak your mount command with some uid and gid options.

Tearing down the mounted container is the same process as above:

umount /mnt
dmsetup remove wibble
losetup -d /dev/loop3

Other notes