Plug in the sdcard

Xen (Qubes dom0) names the sdcard with device /dev/mmcblk0 (like any standard Linux kernel does). The sdcard partitions are automatically named as /dev/mmcblk0p1, /dev/mmcblk0p2

The sdcard is recognized by dom0 as soon as I plug it in.

I plug in the sdcard and then I run this in dom0 terminal:

qvm-block

The output should contain:

BACKEND:DEVID DESCRIPTION  USED BY
sys-usb:mmcblk0  ()

If Qubes OS is configured to use a USB keyboard at boot then there will be a little difference:

BACKEND:DEVID DESCRIPTION  USED BY
dom0:mmcblk0  ()

This means that Qubes OS can see and use my sdcard device.

In the spirit of Qubes OS dom0 should not be used as a workhorse so I use the vault qube to prepare the sdcard.

Attach the sdcard to the vault

As described in the documentation a qube can not use any USB device until it has been attached.

Before attaching the sdcard to the vault qube, I monitor the vault syslog:

sudo multitail /var/log/syslog

#hit enter to place the red line marker

In Qubes OS USB drive mounting is integrated into the devices widget: the tool tray icon with a yellow square located in the top right of the screen.

By clicking on it I see multiple entries: typically, sys-usb:sda, sys-usb:sda1 etc. In this case, it’s mmcblk0.

When I hover over it, it pops up a submenu showing the running VMs to which I can connect it.

I click on vault and the sdcard is attached.

Something like this pops up in the syslog of the vault:

blkfront: xvdi: barrier or flush: disabled; persistent grants: enabled; indirect descriptors: enabled;
**xvdi: xvdi1**

This means that the sdcard block is accessible to the vault as /dev/xvdi. To check if this is true:

sudo fdisk -l /dev/xvdi

Randomize sdcard content

As a security measure which hardens the sdcard against forensic attacks, I fill the entire sdcard with the random output generated by udev.

This erases all the data stored in it and grants that no malicious software or old data is present on the card.

In vault terminal:

SDCARD_DRIVE="/dev/xvdi"
sudo dd if=/dev/urandom of=${SDCARD_DRIVE} bs=1M status=progress
sudo sync

This operation can take a long time depending on the size of the sdcard (~4GB in my case) and the speed of the sdcard-reader but then the output will be something like:

3942645760 bytes (3.9 GB, 3.7 GiB) copied, 529 s, 7.5 MB/s
dd: error writing '/dev/xvdi': No space left on device

which means that the entire sdcard has been overwritten.

Sdcard structure

Once the dd process is finished I create two partitions:

  • /dev/xvdi1: a regular ext4 partition that can be used to store any data. I call it dumb partition
  • /dev/xvdi2: a regular LUKS encrypted partition containing coffin-key-files. I call it hush partition

The dumb partition is there to confuse an inattentive attacker. I fill it with irrelevant data, like landscape pictures of a holiday.

An encrypted sdcard is suspicious. An sdcard containing personal photos is less suspicious.

If the adversary plugs the sdcard in a computer the first partition will be automatically mounted and only irrelevant files will be displayed.

This is obviously not a solid security measure but sometimes even simple tricks like this on can avoid troubles.

I create the two partitions (Linux type) with cfdisk. This is a good guide for it.

sudo cfdisk /dev/xvdi

Alternatively fdisk can be use instead of cfdisk and this is a good guide for it.

My sdcard is 3.7GB and I choose to split it in 3GB (/dev/xvdi1) and 100MB (/dev/xvdi2). The latter is the hush partition

fdisk -l /dev/xvdi

The output is something like:

Disk /dev/xvdi: 3.7 GiB, 3945791488 bytes, 7706624 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt

Device       Size Type
/dev/xvdi1   3.6G Linux filesystem
/dev/xvdi2   100M Linux filesystem

Setup the dumb partition

I choose the VFAT filesystem for the dumb partition so that it can be mounted by any operating system.

sudo mkfs.vfat -F 32 -n DATA /dev/xvdi1

This partition is now ready to be mounted and filled in with irrelevant data

Setup the hush partition

I protect the content of the hush partition with LUKS.

sd_drive="/dev/xvdi"
sd_ext4_part="/dev/xvdi1"
sd_enc_part="/dev/xvdi2"
mapper="hush"
mount_point="/home/user/.hush"

mkdir ${mount_point} &> /dev/null

sudo cryptsetup -v -q -y --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat ${sd_enc_part}

The last command creates the encrypted LUKS filesystem on ${sd_enc_part} after asking the user to input the passphrase. It outputs:

Command successful

Now I bond the LUKS filesystem with loop device and I check its status


# this asks again for the passphrase
sudo cryptsetup open --type luks ${sd_enc_part} ${mapper}

# this checks status of the hush partition
sudo cryptsetup status ${mapper}

the last command outputs:

/dev/mapper/hush is active.
type:    LUKS1
cipher:  aes-xts-plain64
keysize: 512 bits
device:  /dev/xvdi1
offset:  4096 sectors
size:    200704 sectors
mode:    read/write

I continue with:

# format loop device
sudo mkfs.ext4 -m 0 -L "hush" /dev/mapper/${mapper}

# mount loop device on root filesystem
sudo mount /dev/mapper/${mapper} ${mount_point}

# check if it's all fine
mount | grep ${mapper}

The last output looks like this:

/dev/mapper/hush on /home/user/.hush type ext4 (rw,relatime,data=ordered)
/dev/mapper/hush on /rw/home/user/.hush type ext4 (rw,relatime,data=ordered)

Finally, the hush partition is now ready to be used. I dismount and close it to go ahead with other opertions.


# umount
sudo umount ${mount_point}

# close everything
sudo cryptsetup close ${mapper}

Configure udev for the hush partition

I setup the UDEV device manager so that the hush partion is mapped to the /dev/hush when I attach the sdcard.

A consistent device naming grants that the scripts will be always working as expected.

To do so, I use the hush partition UUID and then I write a UDEV rule

sudo cryptsetup luksUUID $sd_enc_part

The output looks like this:

10a9a9b9-e1ef-3385-1121-9d12a3a35e9b

This is string unmistakably identifies the hush partition.

I write the UDEV rule this way:

UUID=$(sudo cryptsetup luksUUID ${sd_enc_part})
sudo sh -c 'echo SUBSYSTEM==\"block\", ENV{ID_FS_UUID}==\"'${UUID}'\", SYMLINK+=\"hush\" > /etc/udev/rules.d/99-sdcard.rules'
sudo service udev restart

Note: vault is a standalone qube (not an AppVM) so the changes to /etc/udev/rules.d/99-sdcard.rules will be persistent after a reboot

From this moment, when I connect the sdcard to my vault it will be mapped to /dev/hush.

Configure DOM0 script to attach sdcard

R.I.S.K.S. has some non-mandatory scripts for dom0 meant to make my life easier.

The script attach_hush_to attaches the hush partition to the qube I want, normally vault.

I copy attach_hush_to to dom0 with this command executed in a dom0 terminal:

cd
qvm-run --pass-io vault 'cat /home/user/risks-scripts/dom0/attach_hush_to' > attach_hush_to
sudo mv attach_hush_to /usr/local/sbin/
sudo chmod +x /usr/local/sbin/attach_hush_to

Still in dom0 I add this to ~/.bashrc so that attach_hush_to has its global vars configured:

echo '
#SDCard
export SDCARD_BLOCK="sys-usb:mmcblk0p2"
' >> ~/.bashrc
source ~/.bashrc

or this, if Qubes OS is configured to use a USB keyboard at boot

echo '
#SDCard
export SDCARD_BLOCK="dom0:mmcblk0p2"
' >> ~/.bashrc
source ~/.bashrc

At this point I can run from dom0:

attach_hush_to vault

and the hush partition is now seen by vault as /dev/hush.

Alternatively I can attach it manually using Qubes Device Widget. It’s technically equivalent but there are less automatic checks.