puree - encrypt devices with PUREE (the full-disk encryption format)



puree info [-v] [-p] <password_file>] [-f] <cipherdevice>

puree format [-v] [-p] <password_file>] [-f] <cipherdevice> <subspec>

puree map [-v] [-p] <password_file>] [-f] <cipherdevice> <plaindevice>

puree unmap [-v] <plaindevice>

puree destroy [-v] [-f] [-q] <device>



The puree tool suite allows you to password-protect disk devices (using dm-crypt and the PUREE header format) in such a way that the entire disk is indistinguishable from random data. Notably this occurs without requiring you to store any associated data on a separate disk (in comparison, most disk encryption formats require the user to store a separate "detached header" somewhere to accomplish this).

The full lifecycle of encrypting a disk with PUREE is as follows:

1) First format the disk with 'puree format' (keeping in mind this will destroy existing data from the disk).

2) If you'd like, you can now use the puree info command to verify that the disk is formatted correctly, and that you still have the correct password to the disk.

3) Next, map the disk to a virtual device with 'puree map'. This virtual device (which will be located under /dev/mapper/) can then be treated as if it were a new disk. Do whatever you'd like with it now, such as as format it with a filesystem, or mount it.

4) When you're done, use puree unmap to unmap the virtual device. After doing this, the disk "locked", and will not be unlocked until you call puree map again.

5) If you'd like to destroy all data on a disk, use puree destroy.




Show verbose output.

-p <password_file>

Instead of prompting for a password, read it from the specified file.


Don't ask for confirmation before writing to disk. (WARNING: Use at your own risk!)


A block device (i.e, disk, partition, or loop device).


A block device (i.e, disk, partition, or loop device) encrypted, or to be encrypted, with PUREE.


A virtual block device (i.e., device-mapper mapping), or target path to create a virtual block device.


Use subspec as the a sub-specification (i.e., the disk format and cryptosystem to use). See section SUB-SPECIFICATIONS for more details.



puree format [-p <password_file>] [-f] [-v] <cipherdevice> <subspec>

Formats the block device cipherdevice with the PUREE disk encryption format using sub-specification subspec. See section SUB-SPECIFICATIONS for more details.

puree info [-p <password_file>] [-f] [-v] <cipherdevice>

Shows detailed PUREE header information for block device cipherdevice; the device must have already been formatted with the PUREE disk encryption format.

puree map [-p <password_file>] [-f] [-v] <cipherdevice> <plaindevice>

Creates a new virtual block device, plaindevice, for which all writes (or reads) will be transparently encrypted (or decrypted) then written to (or read from) cipherdevice. The cipherdevice must have already been formatted with puree format, and a password must be provided to unlock it when it is mapped. Internally, this command leverages the dm-crypt device-mapper target using whatever parameters were used when the cipherdevice was formatted.

puree unmap [-v] <plaindevice>

Unmaps the virtual block device plaindevice, thereby making the device's plaintext data unavailable until it is mapped again.

puree destroy [-f] [-v] [-q] <device>

Destroys all data on the specified device by writing random data. WARNING: This will wipe ALL data on the disk. If -q is supplied, then only the first 1MiB of data and the last 1MiB of data on the disk will destroyed (which, for a cipherdevice previously encrypted with PUREE, will effectively wipe the entire disk).



To format, map, and mount a device, you may perform the series of commands listed below, in order.

To encrypt device /dev/sdz with AES-256-CBC-ESSIV-SHA256:

sudo puree format /dev/sdz aes256-cbc-essiv-sha256

(You will be prompted for a password. PUREE will require you to prefix your password with a "parameter character"; see "PARAMETER CHARACTERS" section below for an explanation.)

Your device should now be encrypted.

Next, you'll need to "map" your encrypted disk device (we'll assume /dev/sdz) to a virtual device :

sudo puree map /dev/sdz /dev/mapper/sdz

(You will be prompted to re-enter the password you chose earlier.)

Your virtual device should now be available at /dev/mapper/sdz. You can now treat /dev/mapper/sdz as you would a normal disk device, and its data will be transparently encrypted/decrypted.

For example, to format it with a filesystem:

sudo mkfs.ext4 /dev/mapper/sdz
sudo mount /dev/mapper/sdz /mnt

You now have an filesystem mounted to /mnt. You can treat it like a normal filesystem, and its data will be transparently encrypted/decrypted.

When you're done using the device, unmap it with:

sudo puree unmap /dev/mapper/sdz

To prove to yourself that the disk is encrypted, try running `sudo hexdump -C /dev/sdz | less`, and you'll see something like this:

00000000  3ac41e42 da074126 fb9d4c6a 01a15f56  |...B..A&..Lj.._V|
00000010  c71c6c47 3a891a07 77af909a 4efb1a8f  |..lG:...w...N...|
00000020  72fc3eac 1766db1d 55d2c0cd 14a666bd  |r.>..f..U.....f.|
00000030  5592d610 bbc3ad81 46eb2bf7 cec566b6  |U.......F.+...f.|
00000040  8c44df17 8868323d d175458d 4327d107  |.D...h2=.uE.C'..|
00000050  6dbf3af8 11083156 dd3bb235 83826b62  |m.:...1V.;.5..kb|
00000060  fad3a02d 48acebc5 7b79ce68 ec9e68f1  |...-H...{y.h..h.|
00000070  4c5daf93 1a2bb71f ace7f417 ca627d05  |L]...+.......b}.|
00000080  39568ce6 5ec12f58 38c056d3 d682d728  |9V..^./X8.V....(|
00000090  446df278 d823fee0 ff2f4c04 434b5f5e  |Dm.x.#.../L.CK_^|
000000a0  bc425830 55c455cd b4439385 c59bf3fd  |.BX0U.U..C......|
000000b0  62019305 a5f38ce9 12c0c138 76f31f1b  |b..........8v...|
000000c0  8e67545a e3abf95a 2247fc0c 5c55558c  |.gTZ...Z"G....U.|
000000d0  01c62344 8fbb35df 80b313da 63269760  |..#D..5.....c&.`|
000000e0  4dfbd88d d32a1179 e4038d7c 3c4412eb  |M....*.y...|<D..|
000000f0  c856ecfe 15e5c4a5 d7f12165 628c05b8  |.V........!eb...|
00000100  6c00f7e2 dcb39dce dff67d1d e9551eaa  |l.........}..U..|
00000110  d9e24fd6 0f42b399 ed18adec 4de8912a  |..O..B......M..*|
00000120  2316e413 1712a0a7 044b96d3 154d1b2f  |#........K...M./|
00000130  67a62365 6f15d733 f4541fc7 8781bfd3  |g.#eo..3.T......|



PUREE encrypts disks using a key derived from a password via the argon2id password-key derivation function. In order to calculate a derived key from a password, however, a few parameters are required:

1. Parallelism: the maximum number of parallel CPU threads

2. Memory: the amount of RAM required

3. Iterations: multiplier on amount of time required

One goal of PUREE is that the disk must be indistinguishable from random. This means these parameters can not be stored on the disk. Instead, PUREE stores these parameters in the password. Every PUREE password must be prefixed with a special character, called the "parameter character". Current valid values are:

'b' => parallelism: 1,  memory: 75MiB,  iterations: 1
'c' => parallelism: 1,  memory: 250MiB, iterations: 1
'd' => parallelism: 4,  memory: 250MiB, iterations: 4
'e' => parallelism: 1,  memory: 1GiB,   iterations: 1
'f' => parallelism: 4,  memory: 1GiB,   iterations: 4
'g' => parallelism: 1,  memory: 4GiB,   iterations: 1
'h' => parallelism: 4,  memory: 4GiB,   iterations: 4
'i' => parallelism: 1,  memory: 16GiB,  iterations: 1
'j' => parallelism: 4,  memory: 16GiB,  iterations: 4

Or, if 'a' is chosen as the parameter character, the password will be derived simply by hashing the password (along with a salt) using the blake2b hash function.

As CPU and RAM become cheaper, more parameter characters will be added to this table.



Currently, the following subspecs are supported:

- aes256-xts-plain64

Encrypt each sector of the disk with AES-256 in XTS mode.

- aes256-cbc-essiv-sha256

Encrypt each sector of the disk with AES-256 in CBC-ESSIV mode, using SHA-256 as the hash function.

- aes128-xts-plain64

Encrypt each sector of the disk with AES-128 in XTS mode.

- aes128-cbc-essiv-sha256

Encrypt each sector of the disk with AES-128 in CBC-ESSIV mode, using SHA-256 as the hash function.



If puree was successful, it will exit with code 0.
If puree encounters an error, it will exit with code 1.
If invalid arguments are passed to puree, it will exit with code 2.



For more information, see <https://puree.cc>.



Jay Sullivan <jay@identity.pub>