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

David Zeuthen david at
Thu Dec 16 09:01:41 PST 2004

On Wed, 2004-12-15 at 21:24 -0600, W. Michael Petullo wrote: 
> I have a prototype "Setup" script written in bash that should allow us
> to discuss this portion further.  Before I present the script, here is
> the cryptheader I used:

Well, ideally sesame-setup must not rely on hald running since we want
to use it in the initrd to mount /. Hence, it needs to read the metadata
off the device itself.

As such, it would be a good idea to create a libsesame library that
various things, including hald, can link against to read/write the
metadata. If you're interested in this approach I've got the start of
such a library.

Anyway, I think this is a good start anyway. Further comments below:

> ================================================================================
> # Required fields
> version               = '0'
> uuid                  = '0123-4567-89ab-cdef'
> block_key_cipher      = 'aes'
> block_key_sha1        = '920f002e08b3d4ff3882a8be98889af2d60b76a9'
> # Required if block key is here
> enc_key_cipher        = 'aes'
> enc_key               = '53616c7465645f5f1e2a1d6798d8eb7aa3b74645d3e12138e7fa974bf06fa8cbfc0d82ec71f63ec9f38c1e0d624b0627a6ba85308ed2a3e0f288777f2c10fd35683ad952dff63603293459b98089b22c98294ff1a57a5b9ff0f74961388e0c6c2755c6b9b3d4a158a62a184df2a934066bb7793c4590096409cd9762979319cda4ead189b28176c62386013a6de4ef76d42396e668dadc9d641779e0a8db81cf'
> ================================================================================

Do you use the patch that I posted? h-d-m should look somewhat like this

Btw, I have just committed the patch, with fixes (see below), to HEAD.

> And here is the script:
> ================================================================================
> #!/bin/bash
> #   FILE: sesame-setup -- Configure a dm-crypt device based on information 
> #         provided by hal.   A passphrase is read from stdin.
> # AUTHOR: W. Michael Petullo <mike at>
> #   DATE: 15 December 2004

Should check for volume.fstype==crypto_sesame and bail out if not.

> # FIXME: this should be provided by hal when this script is executed.
> UDI=/org/freedesktop/Hal/devices/block_0123-4567-89ab-cdef

Right, you will get this from the environment.


>From stdin.

> # Read the required information from hal.
> BLOCK_KEY_CIPHER=`hal-get-property --udi="$UDI" --key volume.crypto_sesame.block_key_cipher`
> BLOCK_KEY_SHA1=`hal-get-property --udi="$UDI" --key volume.crypto_sesame.block_key_sha1`
> UUID=`hal-get-property --udi="$UDI" --key volume.crypto_sesame.uuid`
> VERSION=`hal-get-property --udi="$UDI" --key volume.crypto_sesame.version`
> DEVICE=`hal-get-property --udi="$UDI" --key block.device`

I want to pass all the hal properties in the environment for method.d
invocation, so you should be able to use
$HAL_PROP_VOLUME_CRYPTO_SESAME_UUID and so forth. Of course, that won't
work before we have the methods.d stuff.

> # FIXME: this should be published by hal -- a 128 bit key (as hex).
> # for some reason hald is not providing this information.
> #
> # key was created with:
> #
> # dd if=/dev/urandom bs=1c count=128 | openssl enc -aes-256-ecb | xxd -p
> #
> # passphrase is "sesame" (see PASSPHRASE defined above)
> ENC_KEY="53616c7465645f5f1e2a1d6798d8eb7aa3b74645d3e12138e7fa974bf06fa8cbfc0d82ec71f63ec9f38c1e0d624b0627a6ba85308ed2a3e0f288777f2c10fd35683ad952dff63603293459b98089b22c98294ff1a57a5b9ff0f74961388e0c6c2755c6b9b3d4a158a62a184df2a934066bb7793c4590096409cd9762979319cda4ead189b28176c62386013a6de4ef76d42396e668dadc9d641779e0a8db81cf"

This should be volume.crypto_sesame.enc_key, what properties are on the
UDI you're looking at? (either lshal output or h-d-m screenshot link).
The reason this didn't show up was that the sesame metadata parser was
only reading 256 bytes; I've fixed that on HEAD. Now the metadata can be
up to 1024 bytes which I think should be sufficient. I used shorter keys
for my testing, I guess that's why.

> # Decrypt the key using the passphrase.
> # FIXME: uh oh, how do I pass both passphrase and data to openssl?
> KEY=`echo "$ENC_KEY" | xxd -r -p | openssl enc -d -aes-256-ecb -pass "pass:$PASSPHRASE"`
> # Check to make sure hash of key matches that provided by hal.
> if [ "$BLOCK_KEY_SHA1" != `echo $KEY | sha1sum | awk '{ print $1 }'` ]; then
> 	echo key sha1 hash does not match data provided by hal >&2
> 	exit 1
> fi

You should rather check that the cleartext key ends with SESAME0, cf. the spec

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

> # Set up the dm-crypt device.
> echo setting up $DEVICE using $BLOCK_KEY_CIPHER, default hash and 128 bit key
> echo "$KEY" | cryptsetup -s 128 -c "$BLOCK_KEY_CIPHER" create "${UDI##*/}" "$DEVICE"
> ================================================================================

Need to strip off SESAME0 from the passphrase.

Uh, oh, the name needs to be sesame_crypto_<sesame_udi>, e.g. in your
case it should be creating the device
node /dev/mapper/sesame_crypto_0123-4567-89ab-cdef. 

Right now, hald relies on that exact device node name, we can stop doing
that when there is a suitable ioctl() on the /dev/dm-0 that udev
creates. It's also pretty much a bug that dmsetup creates/destroys
device nodes, but that is another matter.

Hope this helps,

hal mailing list
hal at

More information about the Hal mailing list