Skip to content

Instantly share code, notes, and snippets.

@jpouellet
Created March 31, 2017 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpouellet/abe5cf438267afffc851a1a11d8be8f0 to your computer and use it in GitHub Desktop.
Save jpouellet/abe5cf438267afffc851a1a11d8be8f0 to your computer and use it in GitHub Desktop.
qubes-rpc service to write image to USB stick & return hash of contents actually written
#!/bin/bash
if [ $# -eq 0 ]; then
dev=/dev/sda
else
# Protected by arg-specific qubes-rpc policy.
dev=/dev/"$1"
fi
if ! [ -b "$dev" ]; then
echo "${0##*/}: $dev: No such block device" >&2
exit 1
fi
# Keep track of exactly how much we wrote to know where to stop reading later.
len=$(sudo tee -- "$dev" | wc -c)
echo "${0##*/}: Done writing $len bytes to $dev. Verifying..." >&2
# Read it back from actual media, only once, passing it to all checksums.
# Wait for all hashes to be done, and guarantee consistent ordering.
sudo head -c "$len" -- "$dev" | (
tee >(sha1sum --tag) >(sha256sum --tag) > >(sha512sum --tag)
) | sort
@jpouellet
Copy link
Author

jpouellet commented Mar 31, 2017

Example usage:

$ sha256sum some.img
e0055f12ebfc7d2af90a8a88234ba8c5998094f77fe139c6177ee90f7747169a  some.img
$ curl -o- file:///home/user/some.img | qrexec-client-vm sys-usb jpo.WriteUSB
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  128M  100  128M    0     0  4074k      0  0:00:32  0:00:32 --:--:-- 3189k
jpo.WriteUSB: Done writing 134217728 bytes to /dev/sda. Verifying...
SHA1 (-) = d0a9b75704a00e2d49f0497d2c1874d707a089dd
SHA256 (-) = e0055f12ebfc7d2af90a8a88234ba8c5998094f77fe139c6177ee90f7747169a
SHA512 (-) = 154791573afa213769b5e55431bc573e83e5905083ac12e4d30e4372cb34272f90cc4ff9b3561baa1761ed6ce6234c681bcfe0b81b3d2e543b3caf64281df451

Using curl -o- file:///... gives you a nice progress meter with reasonably-accurate ETA to completion.

Example policy:
dom0:/etc/qubes-rpc/policy/jpo.WriteUSB

$anyvm $anyvm deny

dom0:/etc/qubes-rpc/policy/jpo.WriteUSB+sda

trusted-vm-1 sys-usb ask
trusted-vm-2 sys-usb ask

dom0:/etc/qubes-rpc/policy/jpo.WriteUSB+sdb

trusted-vm-1 sys-usb ask
trusted-vm-2 sys-usb ask

Following service-oriented qrexec) model this would be $anyvm dom0 ask,target=sys-usb.

@jpouellet
Copy link
Author

Install this either in /usr/local/etc/qubes-rpc of sys-usb or /etc/qubes-rpc of the template used by sys-usb.

@jpouellet
Copy link
Author

The purpose of the hash is not so much for image verification (it should already be trusted before you decide to write it), but rather to detect when you have failing (or perhaps malicious?) media.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment