Guest User

ArchLinux: encrypt_resume initrd hook

a guest
Jan 11th, 2014
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.89 KB | None | 0 0
  1. #!/usr/bin/ash
  2.  
  3. run_hook() {
  4.     local passw resumedev resumefile swapname
  5.  
  6.     modprobe -a -q dm-crypt >/dev/null 2>&1
  7.     [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"
  8.  
  9.     # Get keyfile if specified
  10.     ckeyfile="/crypto_keyfile.bin"
  11.     if [ -n "$cryptkey" ]; then
  12.         IFS=: read ckdev ckarg1 ckarg2 <<EOF
  13. $cryptkey
  14. EOF
  15.  
  16.         if [ "$ckdev" = "rootfs" ]; then
  17.             ckeyfile=$ckarg1
  18.         elif resolved=$(resolve_device "${ckdev}" ${rootdelay}); then
  19.             case ${ckarg1} in
  20.                 *[!0-9]*)
  21.                     # Use a file on the device
  22.                     # ckarg1 is not numeric: ckarg1=filesystem, ckarg2=path
  23.                     mkdir /ckey
  24.                     mount -r -t "$ckarg1" "$resolved" /ckey
  25.                     dd if="/ckey/$ckarg2" of="$ckeyfile" >/dev/null 2>&1
  26.                     umount /ckey
  27.                     ;;
  28.                 *)
  29.                     # Read raw data from the block device
  30.                     # ckarg1 is numeric: ckarg1=offset, ckarg2=length
  31.                     dd if="$resolved" of="$ckeyfile" bs=1 skip="$ckarg1" count="$ckarg2" >/dev/null 2>&1
  32.                     ;;
  33.             esac
  34.         fi
  35.         [ ! -f ${ckeyfile} ] && echo "Keyfile could not be opened. Reverting to passphrase."
  36.     fi
  37.  
  38.     if [ -n "${cryptdevice}" ]; then
  39.         DEPRECATED_CRYPT=0
  40.         IFS=: read cryptdev cryptname cryptoptions <<EOF
  41. $cryptdevice
  42. EOF
  43.     else
  44.         DEPRECATED_CRYPT=1
  45.         cryptdev="${root}"
  46.         cryptname="root"
  47.     fi
  48.  
  49.     warn_deprecated() {
  50.         echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated"
  51.         echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead."
  52.     }
  53.  
  54.     for cryptopt in ${cryptoptions//,/ }; do
  55.         case ${cryptopt} in
  56.             allow-discards)
  57.                 cryptargs="${cryptargs} --allow-discards"
  58.                 ;;
  59.             *)
  60.                 echo "Encryption option '${cryptopt}' not known, ignoring." >&2
  61.                 ;;
  62.         esac
  63.     done
  64.  
  65.     case $resume in
  66.         swap:*|file:*)
  67.             resumedev=$(cut -d ':' -f 2 << EOF
  68. $resume
  69. EOF
  70. )
  71.             ;;
  72.         *)
  73.             resumedev=$resume
  74.             ;;
  75.     esac
  76.     resumedev=$(resolve_device "$resumedev" ${rootdelay} 2>/dev/null)
  77.  
  78.     passw=""
  79.     #decrypt swap if necessary:
  80.     swapname=enc_swap
  81.     if [ -n $resumedev ] && cryptsetup isLuks $resumedev 2>&1 ; then
  82.         [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
  83.         dopassphrase=1
  84.         # If keyfile exists, try to use that
  85.         if [ -f ${ckeyfile} ]; then
  86.             if eval cryptsetup --key-file ${ckeyfile} open --type luks ${resumedev} ${swapname} ${cryptargs} ${CSQUIET}; then
  87.                 dopassphrase=0
  88.             else
  89.                 echo "Invalid keyfile. Reverting to passphrase."
  90.             fi
  91.         fi
  92.         # Ask for a passphrase
  93.         if [ ${dopassphrase} -gt 0 ]; then
  94.             echo ""
  95.             echo "A password is required to access the ${cryptname} volume:"
  96.             read -s passw
  97.  
  98.             # loop until we get a real password.
  99.             # save the password so that we use the same for the root device.
  100.             while ! eval cryptsetup open --type luks ${resumedev} ${swapname} ${cryptargs} ${CSQUIET} << EOF
  101. $passw
  102. EOF
  103. do
  104.                 sleep 2;
  105.                 echo "A password is required to access the ${cryptname} volume:"
  106.                 read -s passw
  107.             done
  108.         fi
  109.         if [ ! -e "/dev/mapper/${swapname}" ]; then
  110.             err "Password succeeded, but ${swapname} device creation failed, aborting..."
  111.             resume=""
  112.         else
  113.             echo "Swap successfully decrypted"
  114.         fi
  115.         case $resume in
  116.             '')
  117.                 ;;
  118.             swap:*)
  119.                 resume="swap:/dev/mapper/$swapname"
  120.                 ;;
  121.             file:*)
  122.                 resume="file:/dev/mapper/$swapname:$(cut -d ':' -f 3 << EOF
  123. $resume
  124. EOF
  125. )"
  126.                 ;;
  127.             *)
  128.                 resume="/dev/mapper/$swapname"
  129.                 ;;
  130.         esac
  131.     fi
  132.  
  133.     case $resume in
  134.         '')
  135.             err "resume: no device specified for hibernation"
  136.             ;;
  137.         swap:*|file:*)
  138.             # is it even possible for files?
  139.             # tux-on-ice syntax: swap:/dev/sda2 or file:/dev/sda2:0xdeadbeef
  140.             if [ -d /sys/power/tuxonice  ]; then
  141.                 echo "$resume" >/sys/power/tuxonice/resume
  142.                 echo > /sys/power/tuxonice/do_resume
  143.             else
  144.                 err "resume: tux-on-ice syntax detected, but no support found"
  145.             fi
  146.             ;;
  147.         *)
  148.             # standard hibernation
  149.             if resumedev=$(resolve_device "$resume" "$rootdelay" 2>/dev/null ); then
  150.                 if [ -e /sys/power/resume ]; then
  151.                     printf "%d:%d" $(stat -Lc "0x%t 0x%T" "$resume") > /sys/power/resume
  152.                 else
  153.                     err "resume: no hibernation support found"
  154.                 fi
  155.             fi
  156.             ;;
  157.     esac
  158.  
  159.  
  160.     if resolved=$(resolve_device "${cryptdev}" ${rootdelay}); then
  161.         if cryptsetup isLuks ${resolved} >/dev/null 2>&1; then
  162.             [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
  163.             dopassphrase=1
  164.             # If keyfile exists, try to use that
  165.             if [ -f ${ckeyfile} ]; then
  166.                 if eval cryptsetup --key-file ${ckeyfile} open --type luks ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}; then
  167.                     dopassphrase=0
  168.                 else
  169.                     echo "Invalid keyfile. Reverting to passphrase."
  170.                 fi
  171.             fi
  172.             # Ask for a passphrase
  173.             if [ ${dopassphrase} -gt 0 ]; then
  174.                 if [ -z "$passw" ]; then
  175.                     echo ""
  176.                     echo "A password is required to access the ${cryptname} volume:"
  177.                 fi
  178.  
  179.                 # loop until we get a real password.
  180.                 # try the swap password as the first thing.
  181.                 if [ -z "$passw" ]; then
  182.                     read -s passw
  183.                 fi
  184.                 while ! eval cryptsetup open --type luks ${resolved} ${cryptname} ${cryptargs} ${CSQUIET} << EOF
  185. $passw
  186. EOF
  187. do
  188.                     sleep 2
  189.                     echo "A password is required to access the ${cryptname} volume:"
  190.                     read -s passw
  191.                 done
  192.                 unset passw
  193.             fi
  194.             if [ -e "/dev/mapper/${cryptname}" ]; then
  195.                 if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
  196.                     export root="/dev/mapper/root"
  197.                 fi
  198.             else
  199.                 err "Password succeeded, but ${cryptname} creation failed, aborting..."
  200.                 exit 1
  201.             fi
  202.         elif [ -n "${crypto}" ]; then
  203.             [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
  204.             msg "Non-LUKS encrypted device found..."
  205.             if echo "$crypto" | awk -F: '{ exit(NF == 5) }'; then
  206.                 err "Verify parameter format: crypto=hash:cipher:keysize:offset:skip"
  207.                 err "Non-LUKS decryption not attempted..."
  208.                 return 1
  209.             fi
  210.             test="cryptsetup isLuks $resolved "
  211.             exe="cryptsetup open --type plain $resolved $cryptname $cryptargs "
  212.             IFS=: read c_hash c_cipher c_keysize c_offset c_skip <<EOF
  213. $crypto
  214. EOF
  215.             args=""
  216.             [ -n "$c_hash" ]    && args="$args --hash '$c_hash'"
  217.             [ -n "$c_cipher" ]  && args="$args --cipher '$c_cipher'"
  218.             [ -n "$c_keysize" ] && args="$args --key-size '$c_keysize'"
  219.             [ -n "$c_offset" ]  && args="$args --offset '$c_offset'"
  220.             [ -n "$c_skip" ]    && args="$args --skip '$c_skip'"
  221.             exe="$exe $args"
  222.             test="$test $args $CSQUIET"
  223.             if ! eval "$test"; then
  224.                 err "Can't find anything to decrypt."
  225.                 return 1
  226.             fi
  227.             devopened=0
  228.             if [ -f "$ckeyfile" ]; then
  229.                 if ! eval "$exe --key-file $ckeyfile $CSQUIET"; then
  230.                     err "Wrong keyfile specified. Falling back to passphrase..."
  231.                     exe="$exe --verify-passphrase $CSQUIET"
  232.                     if [ -z "$passw" ]; then
  233.                         echo ""
  234.                         echo "A password is required to access the ${cryptname} volume:"
  235.                     fi
  236.                 else
  237.                     devopened=1
  238.                 fi
  239.             else
  240.                 exe="$exe --verify-passphrase $CSQUIET"
  241.                 if [ -z "$passw" ]; then
  242.                     echo ""
  243.                     echo "A password is required to access the ${cryptname} volume:"
  244.                 fi
  245.             fi
  246.             if [ $devopened -eq 0 ]; then
  247.                 if [ -z "$passw" ]; then
  248.                     read -s passw
  249.                 fi
  250.                 while ! eval "$exe << EOF
  251. $passw
  252. EOF
  253. "; do
  254.                     err "Non-LUKS device decryption failed. retry passphrase or verify format: "
  255.                     err "      crypto=hash:cipher:keysize:offset:skip"
  256.                     sleep 2
  257.                     echo "A password is required to access the ${cryptname} volume:"
  258.                     read -s passw
  259.                 done
  260.             fi
  261.             unset passw
  262.  
  263.             if [ -e "/dev/mapper/${cryptname}" ]; then
  264.                 if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
  265.                     export root="/dev/mapper/root"
  266.                 fi
  267.             else
  268.                 err "Password succeeded, but ${cryptname} creation failed, aborting..."
  269.                 return 1
  270.             fi
  271.         else
  272.             err "Failed to open encryption mapping: The device ${cryptdev} is not a LUKS volume and the crypto= paramater was not specified."
  273.         fi
  274.     fi
  275.     rm -f ${ckeyfile} 2>/dev/null
  276. }
  277.  
  278. # vim: set ft=sh ts=4 sw=4 et:
Advertisement
Add Comment
Please, Sign In to add comment