[Pkg-cryptsetup-devel] cryptsetup keyscript-framework / OpenPGP keyscript

David Härdeman david at hardeman.nu
Mon Jun 23 18:59:19 UTC 2008


On Mon, Jun 23, 2008 at 01:59:22PM +0200, Christoph Anton Mitterer wrote:
>Hi everybody.
>
>This is probably going to be a bit longer, so don't hold your breath ;)

It's good that you sent this to the cryptsetup list rather than as a bug 
report as it is more of a discussion than a bug report.

>First of all I'd like to introduce you into my motivation, in order to
>let you understand my scenario:
..SNIP...
>Ok so much for my motivation and the scenario.... (this was already a
>short description (too short for "real" security) X-D ).
...SNIPPETY-SNIP...
>In order to improve the key-scripts (not only mine) we need a little
>discussion about how every thing should work, at least I think we need
>one:
>(God is this eMail big...sry..)

Perhaps because you address so many different topics in the same mail? 
:)

>Generally we have the following:
>4) Keyscripts tend to depend on further applications (openssl, gnupg,
>etc.).
>5) Keyscripts can be used "within" the inird, at "normal" system startup
>or when the startup is already done and a user maps/mounts a filesystem
>"manually".
>6) The key for the keyscripts can already be available, or not:
>   - in the initrd it is probably not (at least I don't like to add the
>key into (!) the initrd image)
>   - even in the "running" system (I mean after initrd) it could come
>from an USB-stick, or even a (hopefully secured) network cable ;)
>   - also see above, where I tried to describe the different situations
>where keys could come from (and if they're encrypted or not
>7) No keyscript should ever write the key (neither the encrypted nor the
>decrypted) to any storage, as this could be a security risk.
>The keyshould only be written to stdout (in order to be piped and so
>on).
>The only exception from this is: A key may be written into the memory,
>thus it can be written "to disk" during initrd.
>8) Keyscripts need to interact with the user, e.g. tell him about
>encryption errors, ask for a passpharse (e.g. gnupg's prompt) and so on.
>
>
>
>
>Solutions/Ideas/Questions for all this:
>
>
>-> 4:
>We need a generic way for keyscripts to specify dependencies that will
>automaticall added to the initrd. This way should nicely fit with the
>current initramfs-tools framework.
>Some time ago David gave me a possible hint how to do this.
>I'd now propose the following solution, and I'd also implement it you
>give me the OK, and you would accept it for inclusion:

To elaborate on the hint I gave before...my current preference would be 
that if a keyscript is called without any parameters, it prints a list 
to stdout of all applications it depends on, one per line.

Reasons:

The way crypttab looks today, the third (key) field is mandatory. For 
situations where the key is not actually used, you still have to put 
e.g. "none" in that field. Therefore a keyscript (in normal operation) 
should always get one and only one argument (argv[1] in C).

If calling a keyscript with no parameters generates that list, we could 
easily do a separate pass at the end of the cryptsetup initramfs hook 
that does something like this:

IFS='
'
for script in $(ls -1 "${dst}/where/all/keyscripts/are/"); do
	list=$($script)
	for item in $list; do
		copy_exec "$item"
	done
done

A second change that I think might make sense to add is to set 
environment variables with additional information (like cipher, 
keylength, etc). Then keyscripts that are interested can use that 
information in a backwards compatible manner.

However, I'm not sure these changes are a good idea to do pre-Lenny as 
large changes close to a release is generally a bad idea.

On a related note I also have C code for an additional keyscript which I 
will add some time later (post Lenny perhaps) that combines the use of 
askpass and passdev to take a passphrase from the user, hash it (using 
e.g. sha256), get a file from a removable device, XOR the file and the 
hash and use the combination of the two as a key for cryptsetup. This 
would allow a two-factor key without having to add the weight of large 
software such as openssl or gnupg to the initramfs.

I also have code somewhat ready (search debian-boot for the first 
version of the patch) to add support to debian-installer for this. The 
functionality will of course not be added to debian-installer pre-Lenny 
which is one reason why there's no rush in having it in cryptsetup yet.

>-> 6:
>A few days ago, I've added a wishlist, where I've asked to include an
>option in /etc/crypttab like dep= where one could specify a dependency.
>This was denied ;)

Yes, it was a horrible solution :)

...
>I'm not sure myself what I consider to be more generic and clean...
>Another idea would be to put it into the responsibility of the end-user
>to write combination-scripts that do things like:
>
>#!/bin/sh
>
>#logic to print dependencies of sub-scripts (e.g.
>"decrypt_openpgp_gnupg"
>
>mount_usb_stick 1>&2 #secure that it doesn't write to stdout
>decrypt_openpgp "$1"
>umount_usb_stick

passdev would do this..."passdev /dev/disk/something:/my/file | gpg 
--blah --foo --bar --decrypt --readfromstdin --writetostdout"

>If we'd go by the add-dep-option way we have the (possible) problem that
>we need a pre- and post-dep option.
>e.g. one would have to umount the usb-stick.

Only if you write your scripts in a non-clean manner...passdev already 
solves this for you.

>For the initrd this is not a problem, because there we could write the
>retrieved key to RAM and umount the stick immediately after writing.
>But this is not possible during non-initrd use, and we really shouldn't
>write any keys to storage (even if we'd wipe it afterwards).

Incorrect...passdev already solves this for you.

>-> 7:
>The reason for this is easy: Modern filesystems tend to cache, move
>around data and so on... even if we'd wipe (securely-delete) the key
>afterwards, it could be still copied to another physical location, where
>it remains. While this shouldn't be too sever problem (the disk is
>encrypted) we should still avoid it.
>
>Does anyone know if our written-to-stdout-and-piped-only method might
>have problems with swapping? I mean that the key is written to a
>(possibly unencrypted swap partition).

The current setup should be as secure as is currently feasible. Data is 
piped to stdout by keyscripts and read from stdin by cryptsetup. This 
means the data passes through a pipe using kernel memory which is 
(unless I'm mistaken) not swapped to disk. In addition, the initramfs 
scripts run before swap is setup, so no swapping is possible. If run 
after the initramfs stage, swap should be encrypted (debian-installer 
has code to enforce it) so even if e.g. the keyscript application and 
it's memory is swapped, that should be encrypted.

>-> 5 & 8:
>As you see in my decrypt_openpgp example I use echo bla >2& to write log
>messages to stderr instead of stdout.
>This is of course possible, but at least when during inird we have that
>nice log_ functions from /scripts/functions that nicely work with (I
>think at leas) usplash...
>
>Do this functions also work when I'm not in initrd?
>I could imagine problems, when the user "manually" maps/mounts a
>filesystem, that the log-output will be written to the console (where
>usplash "is") instead of his current xterm or so.

Portable logging is a bit of a problem right now. "askpass" helps in 
some respects since it should handle password prompts in a generic 
manner for you. Using the lsb logging functions should also work both in 
initramfs and sysv-init script situations...but it's not ideal. Beyond 
passphrase prompts you should really be able to rely on the additional 
messages that the cryptsetup scripts print as much as possible...

>For (5 & 8) but also for other points (like deciding whether the key may
>be written to "disk":

Your script should work for both initrd and non-initrd scenarios. 
Therefore it should never write to "disk". Therefore it should not need 
to know where it is running because it should always use worst-case 
assumptions. I have yet to see any sanely written scripts where disk 
writes cannot be avoided.

>Is there a way to definitely tell whether I'm in an initrd (e.g. from
>initrd-scripts or keyscripts)? Perhaps an exported environment variable
>or so?
>
>If not (and this goes mainly to David as initramfs-tools maintainer),..
>can you add one?

See above.

>Ok,.. that should be enough for now.

Likewise :)

-- 
David Härdeman



More information about the Pkg-cryptsetup-devel mailing list