Introducing ZFS Crypto in Oracle Solaris 11 Express
By DarrenMoffat on Nov 15, 2010
Using ZFS encryption support can be as easy as this:
# zfs create -o encryption=on tank/darren Enter passphrase for 'tank/darren': Enter again: #
If you don't wish to use a passphrase then you can use the new keysource property to specify the wrapping key is stored in a file instead. See the zfs(1M) man page or ZFS documentation set for more details, but here are a few simple examples:
# zfs create -o encryption=on -o keysource=raw,file:///media/stick/mykey tank/darren # zfs create -o encryption=aes-256-ccm -o keysource=passphrase,prompt tank/tony
If encryption is enabled and keysource is not specified we default to keysource=passphrase,prompt. I plan to have other keysource locations available at some point in the future, for example retrieving the wrapping key from an https:// location or from a PKCS#11 accessible hardware keystore or key management system.
There are multiple different keys used in ZFS, the one the user/admin manages (or is derived from the entered passphrase) is a wrapping key, this means it is used to encrypt other keys not used for data encryption. The data encryption keys are randomly generated at the time the dataset is created (using the kernel interfaces for /dev/random), or when a user/admin explicitly requests a new data encryption key for newly written data in that ZVOL or file system (eg zfs key -K tank/darren).
Back to our simple example of 'tank/darren' lets do a little more. If we now create a filesystem below 'tank/darren' eg 'tank/darren/music' we won't be prompted for an additional passphrase/key since the encryption and keysource properties are inherited by the child dataset. Note that encryption must to set at create time and it can not be changed on existing datasets. Inheriting the keysource means that the child dataset inherits the same wrapping key but we generate new data encryption keys for that dataset.
If you create a clone of an encrypted file system then the clone is always encrypted as well, but the wrapping key for a clone need not be the same as the origin, for example:
# zfs snapshot tank/darren@1 # zfs clone tank/darren@1 tank/darren/sub # zfs clone tank/darren@1 tank/tony Enter passphrase for 'tank/tony': Enter again:
In the first clone above the 'tank/darren/sub' dataset inherits all the encryption properties and wrapping key from 'tank/darren'. In the second case there was no encrypted dataset at 'tank' to inherit the keysource property from (and thus the wrapping key) so we take the default keysource value of passphrase,prompt.
We can also change the wrapping key at any time using the 'zfs key -c <dataset>' command. Note that in the case of passphrase this does not prompt for the existing passphrase, this is intentional as the filesystem will already be mounted (and maybe shared) and the files accessible. It also gives us the ability via ZFS allow delegations to distinguish between which users can load/unload the keys (and thus have the filesystem mount) via the 'key' delegation and those users that can change the wrapping keys with the 'keychange' delegation.
At the time the wrapping key is changed you can also choose to use a different style of wrapping key, say switching from a prompted for passphrase to a key in a file.
The easiest way to create the wrapping keys is to use the existing Solaris pktool(1) command, eg:
$ pktool genkey keystore=file keytype=aes keylen=128 outkey=/media/stick/mykey
ZFS uses the Oracle Solaris Cryptographic Services APIs, as such it automatically benefits from the hardware acceleration of AES available on the SPARC T series processors and on Intel processors supporting AES instructions.