1*4882a593Smuzhiyun======================================= 2*4882a593SmuzhiyunHow to use dm-crypt and swsusp together 3*4882a593Smuzhiyun======================================= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunAuthor: Andreas Steinmetz <ast@domdv.de> 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunSome prerequisites: 10*4882a593SmuzhiyunYou know how dm-crypt works. If not, visit the following web page: 11*4882a593Smuzhiyunhttp://www.saout.de/misc/dm-crypt/ 12*4882a593SmuzhiyunYou have read Documentation/power/swsusp.rst and understand it. 13*4882a593SmuzhiyunYou did read Documentation/admin-guide/initrd.rst and know how an initrd works. 14*4882a593SmuzhiyunYou know how to create or how to modify an initrd. 15*4882a593Smuzhiyun 16*4882a593SmuzhiyunNow your system is properly set up, your disk is encrypted except for 17*4882a593Smuzhiyunthe swap device(s) and the boot partition which may contain a mini 18*4882a593Smuzhiyunsystem for crypto setup and/or rescue purposes. You may even have 19*4882a593Smuzhiyunan initrd that does your current crypto setup already. 20*4882a593Smuzhiyun 21*4882a593SmuzhiyunAt this point you want to encrypt your swap, too. Still you want to 22*4882a593Smuzhiyunbe able to suspend using swsusp. This, however, means that you 23*4882a593Smuzhiyunhave to be able to either enter a passphrase or that you read 24*4882a593Smuzhiyunthe key(s) from an external device like a pcmcia flash disk 25*4882a593Smuzhiyunor an usb stick prior to resume. So you need an initrd, that sets 26*4882a593Smuzhiyunup dm-crypt and then asks swsusp to resume from the encrypted 27*4882a593Smuzhiyunswap device. 28*4882a593Smuzhiyun 29*4882a593SmuzhiyunThe most important thing is that you set up dm-crypt in such 30*4882a593Smuzhiyuna way that the swap device you suspend to/resume from has 31*4882a593Smuzhiyunalways the same major/minor within the initrd as well as 32*4882a593Smuzhiyunwithin your running system. The easiest way to achieve this is 33*4882a593Smuzhiyunto always set up this swap device first with dmsetup, so that 34*4882a593Smuzhiyunit will always look like the following:: 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunNow set up your kernel to use /dev/mapper/swap0 as the default 39*4882a593Smuzhiyunresume partition, so your kernel .config contains:: 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun CONFIG_PM_STD_PARTITION="/dev/mapper/swap0" 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunPrepare your boot loader to use the initrd you will create or 44*4882a593Smuzhiyunmodify. For lilo the simplest setup looks like the following 45*4882a593Smuzhiyunlines:: 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun image=/boot/vmlinuz 48*4882a593Smuzhiyun initrd=/boot/initrd.gz 49*4882a593Smuzhiyun label=linux 50*4882a593Smuzhiyun append="root=/dev/ram0 init=/linuxrc rw" 51*4882a593Smuzhiyun 52*4882a593SmuzhiyunFinally you need to create or modify your initrd. Lets assume 53*4882a593Smuzhiyunyou create an initrd that reads the required dm-crypt setup 54*4882a593Smuzhiyunfrom a pcmcia flash disk card. The card is formatted with an ext2 55*4882a593Smuzhiyunfs which resides on /dev/hde1 when the card is inserted. The 56*4882a593Smuzhiyuncard contains at least the encrypted swap setup in a file 57*4882a593Smuzhiyunnamed "swapkey". /etc/fstab of your initrd contains something 58*4882a593Smuzhiyunlike the following:: 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun /dev/hda1 /mnt ext3 ro 0 0 61*4882a593Smuzhiyun none /proc proc defaults,noatime,nodiratime 0 0 62*4882a593Smuzhiyun none /sys sysfs defaults,noatime,nodiratime 0 0 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun/dev/hda1 contains an unencrypted mini system that sets up all 65*4882a593Smuzhiyunof your crypto devices, again by reading the setup from the 66*4882a593Smuzhiyunpcmcia flash disk. What follows now is a /linuxrc for your 67*4882a593Smuzhiyuninitrd that allows you to resume from encrypted swap and that 68*4882a593Smuzhiyuncontinues boot with your mini system on /dev/hda1 if resume 69*4882a593Smuzhiyundoes not happen:: 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun #!/bin/sh 72*4882a593Smuzhiyun PATH=/sbin:/bin:/usr/sbin:/usr/bin 73*4882a593Smuzhiyun mount /proc 74*4882a593Smuzhiyun mount /sys 75*4882a593Smuzhiyun mapped=0 76*4882a593Smuzhiyun noresume=`grep -c noresume /proc/cmdline` 77*4882a593Smuzhiyun if [ "$*" != "" ] 78*4882a593Smuzhiyun then 79*4882a593Smuzhiyun noresume=1 80*4882a593Smuzhiyun fi 81*4882a593Smuzhiyun dmesg -n 1 82*4882a593Smuzhiyun /sbin/cardmgr -q 83*4882a593Smuzhiyun for i in 1 2 3 4 5 6 7 8 9 0 84*4882a593Smuzhiyun do 85*4882a593Smuzhiyun if [ -f /proc/ide/hde/media ] 86*4882a593Smuzhiyun then 87*4882a593Smuzhiyun usleep 500000 88*4882a593Smuzhiyun mount -t ext2 -o ro /dev/hde1 /mnt 89*4882a593Smuzhiyun if [ -f /mnt/swapkey ] 90*4882a593Smuzhiyun then 91*4882a593Smuzhiyun dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1 92*4882a593Smuzhiyun fi 93*4882a593Smuzhiyun umount /mnt 94*4882a593Smuzhiyun break 95*4882a593Smuzhiyun fi 96*4882a593Smuzhiyun usleep 500000 97*4882a593Smuzhiyun done 98*4882a593Smuzhiyun killproc /sbin/cardmgr 99*4882a593Smuzhiyun dmesg -n 6 100*4882a593Smuzhiyun if [ $mapped = 1 ] 101*4882a593Smuzhiyun then 102*4882a593Smuzhiyun if [ $noresume != 0 ] 103*4882a593Smuzhiyun then 104*4882a593Smuzhiyun mkswap /dev/mapper/swap0 > /dev/null 2>&1 105*4882a593Smuzhiyun fi 106*4882a593Smuzhiyun echo 254:0 > /sys/power/resume 107*4882a593Smuzhiyun dmsetup remove swap0 108*4882a593Smuzhiyun fi 109*4882a593Smuzhiyun umount /sys 110*4882a593Smuzhiyun mount /mnt 111*4882a593Smuzhiyun umount /proc 112*4882a593Smuzhiyun cd /mnt 113*4882a593Smuzhiyun pivot_root . mnt 114*4882a593Smuzhiyun mount /proc 115*4882a593Smuzhiyun umount -l /mnt 116*4882a593Smuzhiyun umount /proc 117*4882a593Smuzhiyun exec chroot . /sbin/init $* < dev/console > dev/console 2>&1 118*4882a593Smuzhiyun 119*4882a593SmuzhiyunPlease don't mind the weird loop above, busybox's msh doesn't know 120*4882a593Smuzhiyunthe let statement. Now, what is happening in the script? 121*4882a593SmuzhiyunFirst we have to decide if we want to try to resume, or not. 122*4882a593SmuzhiyunWe will not resume if booting with "noresume" or any parameters 123*4882a593Smuzhiyunfor init like "single" or "emergency" as boot parameters. 124*4882a593Smuzhiyun 125*4882a593SmuzhiyunThen we need to set up dmcrypt with the setup data from the 126*4882a593Smuzhiyunpcmcia flash disk. If this succeeds we need to reset the swap 127*4882a593Smuzhiyundevice if we don't want to resume. The line "echo 254:0 > /sys/power/resume" 128*4882a593Smuzhiyunthen attempts to resume from the first device mapper device. 129*4882a593SmuzhiyunNote that it is important to set the device in /sys/power/resume, 130*4882a593Smuzhiyunregardless if resuming or not, otherwise later suspend will fail. 131*4882a593SmuzhiyunIf resume starts, script execution terminates here. 132*4882a593Smuzhiyun 133*4882a593SmuzhiyunOtherwise we just remove the encrypted swap device and leave it to the 134*4882a593Smuzhiyunmini system on /dev/hda1 to set the whole crypto up (it is up to 135*4882a593Smuzhiyunyou to modify this to your taste). 136*4882a593Smuzhiyun 137*4882a593SmuzhiyunWhat then follows is the well known process to change the root 138*4882a593Smuzhiyunfile system and continue booting from there. I prefer to unmount 139*4882a593Smuzhiyunthe initrd prior to continue booting but it is up to you to modify 140*4882a593Smuzhiyunthis. 141