My notes on making encrypted filesystems "Just Work(tm)"

David Zeuthen david at fubar.dk
Sun Dec 12 18:47:53 PST 2004


Hi,

Here are my notes on how to make encrypted filesystems "Just Work(tm)"
using hal, the Linux kernel device mapper and GNOME (or any other
desktop that runs on Linux, whee).

I didn't really get down to coding a lot of it; I mostly looked at how I
think the architecture should look like. It would be great if someone
can pick this up. I looked a bit around at

 http://www.saout.de/misc/dm-crypt/

to find inspiration. It might be someone already did other tools to do
this in an easier way, I dunno.

So, these are the different use cases/features that I think a "Just Work
(tm)" system should support:

1) The encryption key should be passphrase protected - it must be
possible to change the passphrase without reencrypting the entire disk.

1) Support encryption of hotpluggable devices, e.g. USB keys. Used by
the office worker Abby to safely store documents she exchanges with her
coworkers. This means that Abby should be able to plug her USB key into
her colleagues laptop and the a dialog to enter the passphrase should be
offered.

2) Support encryption of root file systems; e.g. encrypt all data on a
laptop computer

3) Ability to have the passphrase protected key on another storage
device, such as a USB key; this can be used for the use case where a)
laptop; and b) USB key is required to boot the laptop. 

Can also be used in a campus/corporate setting where the sysadmin can
give the student/worker a key to one or more PC's that can be copied
onto the users personal USB key. E.g. student X may access workstation
A, B and C.

4) Fully automated, e.g. no need to use a shell to get things working.
Integration with the desktop etc.

So, basically, my position is that to support these usecases we need to
embed some metadata on the encrypted filesystem saying "this is an
encrypted filesystem, this is the cipher used, (possibly) this is the
passphrase protected encryption key and so forth". Note that, AFAICS,
this is not what people are doing today; they store such metadata on
other partitions. Which is bad as it means you cannot move partitions
around easily. However, opponents of my approach might say that it's
dangerous to give hints (such as cipher used, storing the key only
protected by a passphrase) to possible attackers - I haven't given that
much thought yet.

So, anyway, the metadata format is pretty much detailed in [1] and [2].
I've called the meta data format sesame, since I think that was a pretty
cool name. YMMV. Anyway, the metadata is just a set of well defined
key/value pairs. It supports comments.

Hence, there needs to be tools that work with this meta data and hal
also needs to understand the meta data. The thinking here is that hal
can actually identify block devices with this meta data, this is not
difficult, in fact we already have code for identifying regular file
systems such as ext3, vfat, udf and so on. Here's a screenshot of h-d-m 

 http://people.redhat.com/davidz/crypto.png

looking at the such a block device. The tools I think we need are
discussed in [3] - again, I just picked the name sesame to keep things
reasonable simple and easy to understand. And I still think it's a cool
name. Now, given these tools, how are they integrated? Here are my
thoughts on that, it's pretty straightforward:

Integration with early boot (initrd): Early boot should run sesame-is-
encrypted on devices to be mounted and if rc is 0, simply run sesame-
setup and use the device returned on stderr.

Integration with desktop environments: The hal daemon should understand
block devices with sesame signatures (through volume_id) and sets

 volume.fstype="crypto_sesame"
 volume.fsusage="crypto"

Also volume.crypto_sesame.* contains all the sesame properties, e.g. the
property volume.crypto_sesame.block_cipher="aes" if applicable. Further
volume.uuid will be set to volume.crypto_sesame.uuid.

A program in the desktop session, could be gnome-volume-manager, should
prompt the user with a dialog asking for either; 1) the passphrase; or
2) prompt the user to insert the device with the block encryption key
and then ask for the passphrase. Said program might also use gnome-
keyring to cache the passphrase.

Once the passphrase have been obtained in the desktop session, then 

 'sesame-setup --device=/dev/sda1 --passphrase=mysecret22'

should be run by root. The desktop session program should probably ask
hald to invoke this; e.g. by invoking the Setup(string passphrase)
method on the org.freedesktop.Hal.Device.Crypto.Sesame interface for the
hal device object representing /dev/sda1.

 (NOTE:  1. hald shall only allow console user to do this
         2. requires new features in hald to callout a program specified
            in e.g. the /etc/hal/methods.d/Crypto/Sesame/Setup file)

Finally, since the hal daemon understands the clear text block
devices, /dev/dm-0 and onwards, provided by dm and hal must knows how to
add hal device objects for these. Thus, if /dev/dm-0 is really the
decrypted version of /dev/sda1 then hald must create a hal device object
representing /dev/dm-0. This device object will be a sibling to the
device object representing /dev/sda1 and will have the same storage
device as a parent. Since everything is decrypted, hald will (through
volume_id) correctly identify the filesystem (say, ext3) and fstab-sync,
pmount, gnome-volume-manager, whatever, will automount the device.

File managers, such as Nautilus, could integrate "Encrypt Disk",
"Decrypt Disk" into the context menu/properties page by simply invoking
methods on the org.fd.Hal.Device.Crypto.Sesame interface.

I've attached a patch against hal HEAD that makes volume_id understand
the meta data and makes hald understand that if you create a crypto
target named 'sesame_crypto_<sesame_uuid>' it assigns the same parent as
the real block device with that uuid and things Just Work(tm).

You can try this out by writing the other attached file,
crypthead_small2, onto the start a ext3 filesystem (e.g. dd
if=cryptheader_small2 of=/dev/whatever bs=1 count=512) and invoking the
right dmsetup command (I forgot the exact one).

Anyway, I've posted this as some people said they were interested in
working on this. Since I haven't implemented it yet, I may be way off in
that this is how it should be done. Comments?

Cheers,
David


[1] : Here follows what metadata is stored on the actual block device
that is encrypted; for this to work there must be at least 512 bytes (or 
something) somewhere well known on the block device that we can overwrite
with a guarantee that the filesystem will still work. It also requires the
encryption to be a block-based cipher as we will overwrite the portions
of the crypted block device.

This is true for ext3 as the first 1024 bytes are not used (superblock 
is at offset 0x0400).

SESAME metadata format
----------------------

# SESAME_MAGIC
# 
# ^
# +--- mandatory one line magic marker '# SESAME_MAGIC\n'
#      Both the metadata stored on the actual block device and
#      files with metadata must start with these 15 characters

###################################################################
# basic fields in metadata
###################################################################

# mandatory: Version of sesame metadata
version            = '0'                   

# mandatory: UUID for this sesame block device
uuid               = '1234-5678-9012-3456' 

# mandatory: Cipher used for encrypting blocks
block_cipher       = 'aes'

# mandatory: SHA1 digest of block encryption key
block_key_sha1     = '01234'

# optional: Data is currently in the clear; encrypt at next boot
defer              = 'encrypt'
# optional: Data is currently encrypted; make clear at next boot
defer              = 'decrypt'

###################################################################
# fields in metadata on the block device if the block cipher encryption
# key is also stored in the metadata
#
# Useful for plug and play, e.g. memory sticks
###################################################################

# mandatory: cipher user for encrypting the block encryption key
enckey_cipher      = 'aes'

# mandatory: encrypted block cipher encryption key, e.g.
# E(block_enc_key, passphr + 'SESAME0')
enckey             = '0123456789abcdef'

###################################################################
# fields in metadata on the block device if the block cipher encryption
# key is stored on another block device
# 
# Useful for root filesystem on laptop and key is on e.g. a USB memory
# key device
###################################################################

# optional: FS UUID of device
#           typically omitted if the key is on several filesystems,
#           e.g. several USB memory sticks. The UUID is references an
#           actual UUID from e.g. a ext3 or vfat filesystem depending
#           on what kind of filesystem contains the file with sesame
#           metadata
#
enckey_on_uuid     = '501f9325-842f-4b96-bce1-0a92af001a4f'

# mandatory: filename of metadata file; SHOULD contain the <uuid> property
#            in the filename so e.g. one USB memory stick can contain keys
#            for several partitions
#            
enckey_filename    = '.SESAME0-key-<uuid>'

# optional: Textual description of the device holding the key; typically
#           omitted if enckey_on_uuid is omitted (e.g. when key is on several
#           other block devices). Otherwise used as a hint to the user
enckey_description = 'davidz's 128MB Jetflash USB Stick'


[2] : When the block encryption key is not on the encrypted device it
must be stored in a file in a filesystem. However, enckey_filename and
possibly enckey_on_uuid, enckey_description can be used to prompt the
user to insert the correct device

###################################################################
# Example of file holding the key follows here
# (SHOULD be named .SESAME0-key-1234-5678-9012-3456; CAN be named anything)
###################################################################

# SESAME_MAGIC
uuid          = '1234-5678-9012-3456' # UUID for sesame block device
enckey_cipher = 'aes'                 # Cipher for encrypting block enc key
enckey        = '0123456789abcdef'    # E(block_enc_key, passphr + 'SESAME0')

[3] : Some discussion on the set of tools we will need

############################################################################
#
# For use only in a fully booted system (requires hald to be running)
#
############################################################################


# Encrypt a disk; used for setting up encryption on a disk
#
#  --passphrase can only be omitted if --key-location is given
#
#  --key-location means that key shouldn't be stored on the disk; rather
#    on device with the given mount point
#
#  --defer means don't encrypt the disk now; instead do on next boot (will
#    be done in the initrd); for use on e.g. / or /home that cannot be unmounted
#
# (note: potentially unsafe to give the passphrase on the commandline when
#        exec'ed from another program)
#
sesame-encrypt --device=/dev/sda1 
               --passphrase=mysecret22
               [--key-location=/media/my_usb_disk]
               [--defer]

# Decrypt a disk; used to remove encryption on a disk
#
#  --defer means don't decrypt the disk now; instead do on next boot (will
#    be done in the initrd); for use on e.g. / or /home that cannot be unmounted
#
# (note: potentially unsafe to give the passphrase on the commandline when
#        exec'ed from another program)
#
sesame-decrypt --device=/dev/sda1 --passphrase=mysecret22 [--defer]

############################################################################
#
# For use in the initrd (also works in a fully booted system)
#
############################################################################

# Checks whether /dev/sda1 is encrypted or scheduled to be
# encrypted/decrypted (by use of --defer). Return value is 0 only
# if this is the case
#
sesame-is-encrypted --device=/dev/sda1

# Setup a device; prompts for passphrase on stdin/stdout unless given;
# Asks for device with key on if that UUID is not mounted.
#
#  If return value is 0 the operation was successfull and the cleartext
#  device is on stderr
#
#  If --defer was used in -encrypt/-decrypt this program will also
#  encrypt/decrypt the disk once the key is obtained. For --decrypt
#  the cleartext device returned on stderr will be the same as given
#  (e.g. /dev/sda1). Will clear the defer property.
#
# (note: potentially unsafe to give the passphrase on the commandline when
#        exec'ed from another program)
#
sesame-setup --device=/dev/sda1 [--passphrase=mysecret22]

-------------- next part --------------
A non-text attachment was scrubbed...
Name: hal-crypto-first-shot.patch
Type: text/x-patch
Size: 13088 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/hal/attachments/20041212/826fcb7f/hal-crypto-first-shot.bin
-------------- next part --------------
# SESAME_MAGIC

# Required fields
version               = '0'
uuid                  = '0123-4567-89ab-cdef'
block_key_cipher      = 'aes'
block_key_sha1        = 'f3274c3404c54cad3b86d88e253d2bf93c4ccb45'

# Required if block key is here
enc_key_cipher        = 'aes'
enc_key               = '6153746c64655f5fa19a2226637b3a4c6aa6d3558b9adb1f6713dc4e4c3af2093b7542b68a4d9c05ea429c16475ca2a38a2f8b347cf8f9ddba2429e1518b2e7f'
-------------- next part --------------
_______________________________________________
hal mailing list
hal at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/hal


More information about the Hal mailing list