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

Christoph Anton Mitterer christoph.anton.mitterer at physik.uni-muenchen.de
Mon Jun 23 11:59:22 UTC 2008


Hi everybody.

This is probably going to be a bit longer, so don't hold your breath ;)

First of all I'd like to introduce you into my motivation, in order to
let you understand my scenario:
I'm using a fully encrypted system, at least as far as this is possible.
The only single points that cannot be encrypted are:
-bootloader
-kernel
-initrd (at least when one doesn't plan to hack the kernel)

In my opinion dm-crypt encryption isn't only a means to secure your data
if someone steals your harddisk (etc.) but also a means to provide
system integrity.
While dm-crypt doesn't sign the data on disk or add MDC's, it still
should be very difficult to attack a "fully" dm-crypt encrypted system,
while it's powered off (the different supsend modes, especially suspend
to RAM, are a different issue).
The reason is simple: In order to make a non-denial-of-service-attack
(DoS in that case would be to simply destroy parts or all of the data),
like installing a root-kit, an attacker would have to know the position
where to write the data, and how the data would "look" when encrypted
with the current key.

The only weak point (apart from the BIOS and the possibility that
someone hacks the hardware itself) is the bootloader/kernel/initrd.
Quite a lot of people that use dm-crypt encrypt everything (even the
root-partition) but not a boot-partition.
All this comes down to the same issue:
An attacker could replace your kernel/initrd/(and even the bootloader)
with a hacked version that, e.g. spies out your dm-crypt keys etc.

The only reason (as far as I can see) is: Put your
kernel/initrd/bootloader (and the dm-crypt key for your root-partition
on a "mobile storage device", e.g. an USB-stick (I found this one to be
very nice for that task:
http://www.transcendusa.com/Products/ModDetail.asp?ModNo=145&LangNo=0
because it is robust and one can safely attach it to the keyring)
Of course you MUSTN'T put this USB stick into a possibly unsecure
running (!) system (e.g. an computer of your friend or at university)
because that one could easily and quickly copy the whole stick.
Of course you'll also have to look for reasonable ways to backup your
dm-crypt keys (if you loos the USB-stick or it get's damaged).


So much for the motivation, here the way I've did it (this is only a
very short description, I have a (even too) detailed log for those who
are interested to do it really paranoid secure ^^):
1. Set up a secure Debian (secure in the sense that you checked the
signatures of your installation medium, in my case I met Andreas Barth
in order to get a trust path ;) )
2. Configure everything for dm-crypt and move the Debian into a
dm-crypt/LUKS encrypted partition
3. Set up a boot/key USB-stick
4. I'm using OpenPGP encrypted keys (gnupg is "only" an implementation
of OpenPGP - and much more (CMS))
5. The key for the root-partition is encrypted and stored on the
USB-stick
6. The key for other partitions (I should perhaps say filesystems) can
be on the (of course encrypted) harddisk, on the USB-stick or even on
another USB-stick, depending on the security needs.
If a key is on the (encrypted) harddisk it (I mean the key itself) can
be unencrypted, for example when you don't want to give the password on
every boot, like with swap or tmp.
In my case the key for all other filesystems (except root-fs) are not
OpenPGP encrypted (but of stored course on the encrypted root-fs, which
I consider to be secure enough).
7. I didn't put the (OpenPGP encrypted) key for the root-filesystem on
the harddisk - it's only on the USB stick,... and backups below my
pillow... oh I'mean,... nothing is below my pillow ;-P
This is not due to security reasons, it's only because I don't "like"
it:
- If I'd put the key for the root-fs on the root-fs it would also be
encrypted.
- If someone hacks my running system (e.g. due to weak SSL keys -
according to rumors, that happens ;-P) and get's root access, he will
have access to all my data whether I've encrypted the disk or not (there
may be exceptions from this, e.g. when using stuff like RSBAC or
SELinux).
- From time to time I WILL HAVE TO insert the USB stick (with the key)
in my running system, e.g. when installing a newer kernel/initrd on it.


Ok so much for my motivation and the scenario.... (this was already a
short description (too short for "real" security) X-D ).




So now comes what I've did until know and what I would like to do. This
is mainly filled with questions, especially for David and Jonas (and the
other?? cryptsetup maintainers). However I ask everybody to tell me his
opinions, ideas, improvements, bug's he found as well as insults and
threats against me ;)

My work mainly focuses on supporting the scenario described above,
therefore the main thing is perhaps the decrypt_openpgp keyscript.

1) I've attached a first version but this will still develop in the next
days, you can (and please do so :-) ) already add it to the package.
I think it should work (at lest it does here on my system) and I
consider it to be secure, but please have a close look on it, because as
we've learned from Debian's SSL: There can't be too much eyes on code.
It depends on busybox (at least some of it's tools) and of course gnupg
(1 or 2, shouldn't matter, but I'm using 1, at least with cryptsetup,
because right now it's the default in Debian)
2) Please use the current name "decrypt_openpgp" and not "decrypt_gpg".
gpg isn't a standard, it "just" implements several cryptographic
standards. So "decrypt_gpg" could even mean that the key is CMS
encrypted.
3) The "license" (if I can put one on it at all ^^) is right now GPL3 or
later. If this makes problems I will release it under (nearly ^^) any
license you like, of course. Just ask.


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..)

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:

a) adding a hook, e.g. "cryptsetup_keyscripts_dependencies" (please
provide a better name if you have one ;) )
This hook searches for the root-filesystem in /etc/crypttab an decides
whether it uses a keyscript.
If so, it invokes the keyscript with "prereqs" as the only option (the
same way as it is done with hooks and boot scripts).

b) A keyscript will have to print its dependencies to stdout when called
that way.
This will also work with non-sh-keyscripts, and it should be fairly
backwards compatible or at lease very easy to adapt to.

My decrypt_openpgp script would print "decrypt_openpgp_gnupg". I prefer
such a name in favour of just "gnupg" because of c)

c) For the dependencies of each keyscript other hooks must be added,
e.g.:
/usr/share/initramfs-tools/hooks/decrypt_openpgp_gnupg
/usr/share/initramfs-tools/hooks/decrypt_openssl_openssl

The trick is, that they'll only do anything, when called with a special
parameter e.g. "cryptsetup-keyscript-dependency".
If this one is not used, they'll simply exit with exit 0.
That way you prevent all of these dependencies to be added (by
initramfs-tools) whether they're needed or not.

These speciak hooks might get their own "prereqs" parameter, too. But it
will be the task of the hook script from a) to "resolve" these
dependencies.

A pseudo-code example would be:
#!/bin/sh
if $1 != "cryptsetup-keyscript-dependency" then exit 0 #prevent
initramfs-tools to use this hook

if $1 = "prereqs" then echo "gnome" #my pimped version of gnupg require
GNOME ;-)

copy_exec /usr/bin/gpg /bin #copy into gpg into initrd

What are your ideas?


-> 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 ;)
I agree and disagree with that:
Pro (a dep= option):
- The decrypt_* scripts should be usable in a generic way, so the
decryp_* scripts should not be responsible for mounting filesystems,
etc. because one should be able to use them with, and without mounting
any additional thing, just as it's done now: give it a pathname, print
key to stdout. Great! :-)


Cons:
The user shouldn't have to hack around to much manually (which he'll has
to if we follow the pro). A dep= option would allow him to easily
combine such scripts, e.g:
keyscript=decrypt_openpgp    deps=print_warning,
mount_my_super_secret_usbstick,shot_the_user_and_selfdestruct_if_wrong_password_entry


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

With such combination scripts we could to both, avoiding a new option to
crypttab and separate decryption scripts from
make-key-source-available-scripts .


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.
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).


I slightly prefer the solution to distinguish between combinantion
scripts, decryption scripts, and make-the-key-source-available-scripts.

What do you think?


-> 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).


-> 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.



For (5 & 8) but also for other points (like deciding whether the key may
be written to "disk":
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?



Ok,.. that should be enough for now.
I've also attached my current mount-the-usb-stick-scripts, but I'll
probably replace them (most likely as described above with those
combination scripts,...), however:
The mount-script must be in /scripts/local-top/, the umount-script
in /scripts/local-premount/
I've also attached my current (non-automatic) gnupg hook.





Best wishes,
Chris.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: decrypt_openpgp
Type: application/x-shellscript
Size: 2589 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/pkg-cryptsetup-devel/attachments/20080623/e775b7f5/attachment.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gnupg
Type: application/x-shellscript
Size: 218 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/pkg-cryptsetup-devel/attachments/20080623/e775b7f5/attachment-0001.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mount_boot_usb_stick
Type: application/x-shellscript
Size: 4878 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/pkg-cryptsetup-devel/attachments/20080623/e775b7f5/attachment-0002.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: umount_boot_usb_stick
Type: application/x-shellscript
Size: 1319 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/pkg-cryptsetup-devel/attachments/20080623/e775b7f5/attachment-0003.bin 


More information about the Pkg-cryptsetup-devel mailing list