# Hibernation with encrypted swap

## Massimo B.

Hi,

I like to learn about hibernation as suspend-to-ram is currently broken with my hardware. (It was working some month ago but now stopped working even with old kernels known to work with s2r -> Suspend-to-ram resume is crashing).

I read https://wiki.gentoo.org/wiki/Suspend_and_hibernate.

Does TuxOnIce has any advantage compared to gentoo-sources with CONFIG_HIBERNATION? I have non of the mentioned tools installed, but I have pm-suspend and pm-hibernate from app-laptop/laptop-mode-tools that are not mentioned in the wiki.

However I'm not sure how hibernation works with encrpyted swap. Currently I have a random key like this in /etc/conf.d/dmcrypt:

```
swap=swap_crypt_1

source='PARTUUID=5e974f00-05'

options='--cipher aes-xts-plain64 --key-size 512 --key-file /dev/urandom'

pre_mount='mkswap -f ${dev} -L swap_crypt_1'
```

I learned I need a fixed key for that. But which kernel args are required later to open the encrpyted swap by entering a password? My current CMDLINE for opening the btrfs-on-luks is this:

```
GRUB_CMDLINE_LINUX_DEFAULT="keymap=de splash crypt_root=UUID=e609e76c-419f-4677-a2fe-872290730f00 root=LABEL=gentoo dobtrfs"
```

I would add another resume= for suspend-to-disk, but who opens the LUKS behind the swap device?

----------

## Hu

Typically, no kernel arguments are required, because the kernel is not responsible for opening the LUKS device containing the swap area.  Your initramfs is responsible for that task, and then for resuming from the hibernation image, then falling through and starting fresh if no hibernation image was available.

I used TuxOnIce some years ago, then switched to swsusp when the TuxOnIce maintainer began issuing patches less quickly than I wanted.

----------

## Massimo B.

So you mean a well configured initramfs will open my encrypted swap automatically when pointing resume= to such an encrypted swap partition? Then why are the crypt_root and root parameters required for the encrypted root partition?

----------

## nokilli

 *Massimo B. wrote:*   

> So you mean a well configured initramfs will open my encrypted swap automatically when pointing resume= to such an encrypted swap partition? Then why are the crypt_root and root parameters required for the encrypted root partition?

 

You call resume from the initramfs but if there wasn't a suspend then your init script proceeds as usual, in which case crypt_root and root and so forth become useful once again.

----------

## Massimo B.

This is not the point. In order to check if there is a resumable image it needs to open the encrypted swap first.

----------

## nokilli

 *Massimo B. wrote:*   

> This is not the point. In order to check if there is a resumable image it needs to open the encrypted swap first.

 

Yes, but if there isn't a resumable image?  What do you want the kernel to do then?

At least that's how it is in my init.  Swap can be encrypted separately from root, so I still need to know which device to do dm_crypt stuff with and, in the case of something like lvm, which logical volume in the volume group that just got vgscanned to use as root.  I'm assuming that's what crypt_root and root point to.

----------

## Hu

 *Massimo B. wrote:*   

> So you mean a well configured initramfs will open my encrypted swap automatically when pointing resume= to such an encrypted swap partition?

 I would consider it a very poor initramfs if it opened the encrypted volume without user interaction, since that means the key is stored in the initramfs (or that it derives the data from some non-interactive source), in which case how is the key protected from unauthorized use?  A well configured initramfs will prompt you to unlock the swap device, then resume from that device after you unlock it, and if the resume fails, boot the system normally.

----------

## tholin

I used hibernate with encryption for a few years. You can't use a random generated key for swap because you loose all data on swap when you generate a new random key. You need to enter a passphrase to unlock the swap and then resume from that unlocked swap. Using resume= on the kernel command line doesn't work because the kernel will try to resume before the swap device is unlocked.

I used µswsusp (sys-power/suspend) for the userspace support needed for this. Perhaps TuxOnIce also works but I've never tried that. Read /usr/share/doc/suspend-1.0_p20150810/HOWTO.bz2 from sys-power/suspend for a good introduction.

What you need is an initramfs that unlocks the swap partition with your passphrase, do the resume with the userspace tools from that partition, if that fails do the regular boot. A minimal example might look like this:

```

#!/bin/busybox sh

PATH="/usr/sbin:/usr/bin:/sbin:/bin"

mount -t proc -o noexec,nosuid,nodev proc /proc

mount -t sysfs -o noexec,nosuid,nodev sysfs /sys

mount -t devtmpfs none /dev

SWAPDEV=`/dev/sda3`

while ! cryptsetup --allow-discards luksOpen ${SWAPDEV} swap; do

    echo "wrong passphrase, try again"

done

/sbin/resume

# if we reached this point there was no suspended image to resume

# mount the regular root fs and boot from it

ROOTDEV='/dev/sda2' # can be read from kernel commandline

mount -o ro ${ROOTDEV} /mnt/root/

for fs in /dev /sys /proc

do

    umount $fs

done

exec switch_root /mnt/root /sbin/init

```

This is only to give you an idea of what the initramfs needs to do. Don't use this. The initramfs also needs to have busybox, cryptsetup, /sbin/resume, /etc/suspend.conf and all other stuff they need to run. Perhaps genkernel can already do this for you but from looking at this bug it looks like no. https://bugs.gentoo.org/show_bug.cgi?id=156445

I'm not using hibernate anymore because it's just too broken. Almost every new kernel version got some regression. Since you can't even get suspend to ram working right I'd suggest you forget about hibernate.

----------

## nokilli

 *Hu wrote:*   

>  *Massimo B. wrote:*   So you mean a well configured initramfs will open my encrypted swap automatically when pointing resume= to such an encrypted swap partition? I would consider it a very poor initramfs if it opened the encrypted volume without user interaction, since that means the key is stored in the initramfs (or that it derives the data from some non-interactive source), in which case how is the key protected from unauthorized use?  A well configured initramfs will prompt you to unlock the swap device, then resume from that device after you unlock it, and if the resume fails, boot the system normally.

 

Or you could just write your own.  genkernel and dracut were a bit busy for my taste so I just adapted the one used by LFS.  I boot using a USB stick cause I like to maintain custody of my kernel and can choose between using a key I embed in the initramfs that sits on the USB stick or entering it in at a prompt (or both).  Whatever the key is, that's what I use to open both root and swap and whatever else.  Swap gets opened first, and we try the resume.  If it fails then we move on to opening root.

Since the kernel moved to initramfs and devtmpfs there really is no reason to not be rolling your own init scripts.  Documentation in the kernel is excellent.  No issues handing off from devtmpfs to eudev (although mine is a pretty straightforward system device-wise).  The only gotcha I experienced is that busybox bash is missing some normal bash stuff (don't do -v in expressions!).  And remember that /proc/cmdline is your friend.  Do exactly what you need/want to do and no more.

----------

## Massimo B.

 *tholin wrote:*   

> Using resume= on the kernel command line doesn't work because the kernel will try to resume before the swap device is unlocked.
> 
> I used µswsusp (sys-power/suspend) for the userspace support needed for this. Perhaps TuxOnIce also works but I've never tried that. Read /usr/share/doc/suspend-1.0_p20150810/HOWTO.bz2 from sys-power/suspend for a good introduction.

 I didn't expect that working with the kernel opening LUKS on resume=, so I tried, and you are right, it doesn't work. Previous posts were looking like it could work...

Thanks, I will look into µswsusp. Too bad if dracut couldn't create an initramfs working like that. I'm going to switch from genkernel to dracut anyway as genkernel is hitting its limits when I like to boot from some bcache storage.

----------

## Massimo B.

I migrated to dracut now, but still have issues. dracut already can open my root filesystem from LUKS. I also managed to get dracut opening my bcache by adding the dracut-modules from bcache-tools. Now I thought dracut could also open the LUKS of the swap by a key stored on the root fs. So I tried this: 

```
rd.luks.uuid=<root-uuid>  root=LABEL=root  rootflags=subvol=root  rd.luks.uuid=<swap_uuid>  rd.luks.key=/etc/key:UUID=<root-uuid>:UUID=<swap_uuid>  resume=LABEL=swap_1
```

But it does not work. Curiously dracut tries to use the keyfile for my first LUKS, which I did not configure like that.

Removing the part about the 2nd LUKS device I'm asked for the 1st password, that works, but dracut then asks also for the password of the 2nd LUKS that I did not mention in the config at all:

```
 rd.luks.uuid=<root-uuid>  root=LABEL=root  rootflags=subvol=root
```

. It should not do that as that encrypted swap is opened by dmcrypt later anyway.

----------

