# Gensplash Silent mode and LUKS encrypted root [Solved...]

## Luud

Hi all,

I've been experimenting with gensplash which was a bit more difficult as my systems are all set up to have system encryption with LUKS.

I managed to get gensplash to work in verbose mode. As I need to type in a password as part of the boot process silent mode gives me problems.

A lilttle explanation of what I have done so far and some references I used to get at that state. (A major compliment here to  everybody maintaining and contributing to the gentoo-wiki, it's become a great resource of information. I'm amazed at how fast it has grown and how much is quite up to date.)

I used the guidelines from "SECURITY Encrypting Root Filesystem with DM-Crypt with LUKS" to transfrom my initrd image for LUKS decryption of my root partition into an initramfs image. Next I added the gensplash tools and themes to the initramfs directory from which I generate the initramfs for bootup using the copy option of the splash_geninitramfs tool

```
# splash_geninitramfs -v -r 1024x768 -c initramfs mytheme
```

I had to deviate from the explanations in "SECURITY Encrypting Root Filesystem with DM-Crypt with LUKS" as with busybox the output from the sed command in devmap_mknod.sh was not assigned to the MAJOR and MINOR variables. So I copied the programs from my initrd image into my initramfs image and only use the switch_root command from busybox. I don't know why the busybox tools don't work yet.

The setup I have now works for verbose mode. However, I'm still in the dark about how to get silent mode working. Just switching to silent mode does not allow me to enter a password. I tried storing the password in a file so the request for a password was not necessary (just for debugging of course) but then I get stuck in the silent mode screen. The system boots up, but once there I cannot switch virtual terminals, the only thing I can do is trigger a reboot with <ctrl>-<alt>-<del> which nicely shuts linux down before rebooting. So it seems I just get locked out of seeing what's going on.

So the question I have are:How can I ask for a LUKS password in silent mode? Can I switch back and forth between verbose and silent mode to do this in the boot up process (while still in the initramfs image).

 Why don't I leave silent mode once booted into linux? I have the splash service as part of my boot runlevel and it works fine in verbose mode.

 Is there more information about the options and use of splash_helper?

I did look at the genkernel generated initramfs image. It has a huge amount of scripting which I'm not eager to study all. I did see a mention of decrypting a LUKS root partition in there though, so maybe there is a way to use that for my setup. Has this feature been reported to work, and if so, how can I get it to work? 

Some references I used so far (albeit not all of them completely yet): SECURITY Encrypting Root Filesystem with DM-Crypt with LUKS

 HOWTO Gensplash

 HOWTO create Gensplash themes

 Spock's website (He's the person that started the Gensplash project.)

 HOWTO Framebuffer:Bootsplash:Grubsplash

 TIP Design your own Framebuffer Splash

 Searching these forums has also not given me an answer, although it is possible I didn't find the right topic...

A related topic to my endeavour into beautifying the boot up process and the issues I face with the GRUB splashimage and menu highlighting is here.

----------

## Luud

I've been looking around a bit more and found that with the proper options and parameters to genkernel yuo can make it work with LUKS and silent splash.

It is not completely perfect yet, but getting close.

The trick is to make genkernel use luks and the proper gensplash theme. As I want to keep my kernel config I have CLEAN="no" in /etc/genkernel.conf and I use:

```
# genkernel all --luks --gensplash=livecd-2006.1
```

Next I set up the grub.conf file as

```
# For booting GNU/Linux

title GNU/Linux 2.6.19 Gentoo-r5 crypto [genkernel, silent=livecd-2006.1]

root (hd0,0)

kernel /kernel-genkernel-x86-2.6.19-gentoo-r5-crypto root=/dev/ram0 init=/linuxrc ramdisk=8192 crypt_root=/dev/hda3 splash=silent,theme:livecd-2006.1 video=vesafb:ywrap,mtrr,1024x768-16@75 console=tty1

initrd /initramfs-genkernel-x86-2.6.19-gentoo-r5-crypto
```

With this I get the silant splash screen of the livecd. It then just hangs there. So you have to press <ALT>-<F1> to see the verbose screen. There can enter the luks password and continue. The boot process will somewhat later switch to silent mode again and we can see all the nice icons disappear as in the livecd boot sequence. However, in my sequence I decrypt some additional luks volumes and when that happens the splash mode flips back and forth for each decryption to verbose modes. I my case this is not necessary as the keys are stored in the encrypted root filesystem.

So, the things to fix are: Change the scripts in the initramfs to look for the decryption key an some removable media (e.g. a floppy or usb stick).

 OR: change to verbose when the user needs to enter a key

 OR: Allow the user to enter a key in the silent mode screen

 Don't flip to verbose mode and back during the bootup process

References: Chimeric.de snippets:dm-crypt

 www.saout.de:LUKS on Gentoo

 Genkernel documentation on plasmaroo's pages

----------

## avx

 *Quote:*   

> 4. Don't flip to verbose mode and back during the bootup process

 

I can't check it right now, but IIRC you have to comment out two lines in /lib/rcscripts/addons/dm-crypt-start.sh, which read something like "splash svc_input_{begin/end} checkfs".

hth,

ph

----------

## Luud

Indeed, thanks.

That works perfectly.

----------

## Luud

I've managed to get it to work completely silent.

I had to hack around in the init scripts of the genkernel initramfs.

Here are the steps I had to take:

1. Create a removable medium to hold the LUKS key and add this key to a key slot

I used a floppy disk for it, but a usb memory stick should work just as good. To keep things easy to implement for myself I just use dd to write the key to the first 256 bytes of the floppy:

```
# dd if=/dev/urandom of=~/luks.key bs=256 count=1

# dd if=~/luks.key of=/dev/floppy/0 bs=256 count=1

# cryptsetup luksAddKey /dev/hda3 ~/luks.key
```

Using the floppy in such a way reduces the security risk as well (note reduces, it is security by obscurity which is not real security at all!). As the key is just random numbers, when you loose the floppy somewhere it will be meaningless to someone else (unless they know you and that this might just be the key to your system...). You could also fill the whole floppy with random numbers and use some part of it as the key. Of course you could also create a filesystem on the floppy and store the key in a file. This would mean mounting the floppy, using the key file and unmounting the floppy in the bootup process.

2. Turn of switching to verbose mode in cryptfs service

As ph030 mentioned above, you just have to comment out the splash lines in /lib/rcscripts/addons/dm-crypt-start.sh, which read "splash svc_input_{begin/end} checkfs". I do not think this is the proper solution though, but it works. My guess is that the checkfs service is now not reported to the silent splash system, which could break any silent splash items related to this service.

3. Get the contents of the genkernel generated initramfs so we can hack around in it

To get the contents you need to extract the cpio archive to some directory, e.g. 

```
# mkdir ~/initramfs

# cd ~/initramfs

# zcat /boot/initramfs-genkernel-x86-2.6.19-gentoo-r5 | cpio -i
```

4. Edit the init script to parse an additional kernel parameter called crypt_key

I decided to add an additional kernel parameter which contains the device from which to retrieve the key at bootup. Then we can add the following to our grub.conf kernel line:

```
crypt_key=/dev/floppy/0
```

First I made sure the /dev/floppy/0 device is available in the initramfs image (I'm not sure this is necessary, but it doesn't hurt):

```
# cd ~/initramfs/dev

# cp -a /dev/floppy .
```

Next I added the following lines to the /init file in the initramfs tree:

```
# cd ~/initramfs

# vi init
```

Just after the switch block for crypt_root (this was for me at line 179) add

```

crypt_key\=*)

    LUKS_KEY=`parse_opt "${x}"`

;;
```

This will set the LUKS_KEY variable we can check later.

5. Edit /etc/initrd.scripts to add the key handling code

In /etc/initrd.scripts are the functions that handle the unlocking of the root filesystem. The function that needs changing is openLUKS. The new function is now defined as below. I added the calls to the splash function, forcing verbose mode only if user interaction is required. Next I added the key handling code in the if block that is exe4cuted when the cryptsetup isLuks check tells us that the specified device is indeed a luks encrypted device.

```
# Open a LUKS device

# $1 LUKS device

# $2 LUKS name

openLUKS() {

   LUKS_DEVICE="$1"

   LUKS_NAME="$2"

   if [ -e /sbin/cryptsetup ]

   then

      while [ 1 ]

      do

         if [ "${LUKS_DEVICE}" = '' ]

         then

            # LUKS device could not be opened. Prompt user for device.

            splash 'verbose'

            bad_msg "The LUKS ${LUKS_NAME} block device is not detected."

            echo "   Please specify a ${LUKS_NAME} LUKS device to open, "q" to skip, or "shell" for a shell..."

            echo -n "LUKS ${LUKS_NAME}() :: "

            read LUKS_DEVICE

            continue

         elif [ "${LUKS_DEVICE}" = 'shell' ]

         then

            splash 'verbose'

            run_shell

            

            LUKS_DEVICE=''

            continue

         elif [ "${LUKS_DEVICE}" = 'q' ]

         then

            break

         else

            if cryptsetup isLuks ${LUKS_DEVICE}

            then

               good_msg "Opening LUKS device ${LUKS_DEVICE}"

               

               # See if the user has specified a device from which to retrieve the key.

               LUKS_KEYFILE=''

               if [ -n "${LUKS_KEY}" ]

               then

                  /bin/dd if=${LUKS_KEY} of=/luks.key bs=256 count=1

                  if [ "$?" -eq '0' ]

                  then

                     LUKS_KEYFILE='-d /luks.key'

                  fi

                  # Clear so we don't get stuck in infinite loop if the key on the device

                  # is invalid.

                  LUKS_KEY=''

               fi

               # If there is no file with the key, switch to verbose mode to ask user

               # for a key.

               if [ ! -n "${LUKS_KEYFILE}" ]

               then

                  splash 'verbose'

               fi

               # Try yo open the device

               echo "cryptsetup ${LUKS_KEYFILE} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}"

               cryptsetup ${LUKS_KEYFILE} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}

               if [ ! "$?" -eq '0' ]

               then

                  splash 'verbose'

                  bad_msg "Failed open LUKS device ${LUKS_DEVICE}"

               else

                  break

               fi

            else

               splash 'verbose'

               bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header"

            fi

         fi

         LUKS_DEVICE=''

      done

   else

      splash 'verbose'

      bad_msg "The initrd does not support LUKS"

   fi

   # Switch back to the original splash mode.

   splash ${SPLASH_MODE_REQ}

}
```

NOTE: I'm not a very skilled shell script writer, so the above can probably be improved a bit. Also, it can be made more general purpose so different forms of supplying the keys can be used.

6. Update the splash script in /etc/initrd.splash

Finally, we need an additional option in the splash function to switch back to silent mode. Therefore I added the following lines to /etc/initrd.splash (I just added them after the verbose case):

```
silent)

   echo "silent"

   /sbin/splash_helper 2 'repaint'

   ;;
```

7. Add required programs and devices

Make sure to add the dd and chvt hard links for busybox and to add the floppy device (if not done so already in step 4):

```
# cd ~/initramfs/bin

# ln busybox dd

# ln busybox chvt

# cd ../dev

# mkdir floppy

# cd floppy

# mknod -m 660 0 b 2 0
```

8. Generate the new initrd image

We now have an updated initramfs tree that can boot our LUKS encrypted system completely silent. Let's archive it into an image:

```
# cd ~/initramfs

# find . -print | cpio -o -Hnewc | gzip -9 > /boot/initramfs-genkernel-x86-2.6.19-gentoo-r5-silent
```

9. Setup the grub boot parameters

Add something like the following to your list of boot titles in /boot/grub/grub.conf:

```
# For booting GNU/Linux

title GNU/Linux 2.6.19 Gentoo-r5 [genkernel, silent=livecd-2006.1]

root (hd0,0)

kernel /kernel-genkernel-x86-2.6.19-gentoo-r5-crypto root=/dev/ram0 init=/linuxrc ramdisk=8192 crypt_root=/dev/hda3 crypt_key=/dev/floppy/0 quiet splash=silent,theme:livecd-2006.1 video=vesafb:ywrap,mtrr,1024x768-16@75 console=tty1

initrd /initramfs-genkernel-x86-2.6.19-gentoo-r5-silent
```

10. Disclaimer

The above works for me. If it helps you, that's just great. If you loose precious data or anything else unfortunate happens to you. Don't blame me. Use it at your own risk.  :Wink: 

----------

## Luud

Here are the steps to take if you wish to modify genkernel to create a working silent initramfs image

In /usr/share/genkernel/gen_initramfs.sh add the following code to the function append_base_layout (right after mknod tty1). Note that this is specifically targeted ad the floppy drive as key mechanism. This is not very generic as it is defined here:

```
mkdir -p floppy

cd floppy

mknod -m 660 0 b 2 0
```

Just below in the next function append_busybox add 'dd' and 'chvt' to the list of links to be made, i.e.:

```
for i in '[' ash sh mount uname echo cut dd chvt; do
```

Next, in /usr/share/genkernel/generic you need to make the same changes to linuxrc, initrd.scripts as described in the previous post. The same holds for /usr/share/splash/initrd.splash.

From now on the initramfs images generated by genkernel are LUKS silent splash ready (assuming you use the floppy as key device, otehrwise you need to make the appropriate device nodes for the device you are using in append_base_layout as described above).

Finally, I saw something that was called overlay in genkernel. That is possibly a better method to do what I just described, bus as I'm completely new to genkernel I just hacked my way into it.

----------

## Aszrael

Excellent HowTo - thanks a lot!!!

I don't use any splash-theme, but you helped me using my MMC-Card as key-device

 *Luud wrote:*   

> 
> 
> Finally, I saw something that was called overlay in genkernel.

 

Do you have some more info about this?

Aszrael

----------

