grub_cmd_cryptomount.in 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #! @BUILD_SHEBANG@ -e
  2. # Run all grub cryptomount tests in a Qemu instance
  3. # Copyright (C) 2023 Free Software Foundation, Inc.
  4. #
  5. # GRUB is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # GRUB is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. if [ "x$EUID" = "x" ] ; then
  18. EUID=`id -u`
  19. fi
  20. if [ "$EUID" != 0 ] ; then
  21. echo "not root; cannot test cryptomount."
  22. exit 99
  23. fi
  24. if ! which cryptsetup >/dev/null 2>&1; then
  25. echo "cryptsetup not installed; cannot test cryptomount."
  26. exit 99
  27. fi
  28. if ! which mkfs.vfat >/dev/null 2>&1; then
  29. echo "mkfs.vfat not installed; cannot test cryptomount."
  30. exit 99
  31. fi
  32. COMMON_OPTS='${V:+--debug=$V} --cs-opts="--pbkdf-force-iterations 1000"'
  33. _testcase() {
  34. local EXPECTEDRES=$1
  35. local LOGPREFIX=$2
  36. local res=0
  37. local output
  38. shift 2
  39. # Create a subdir in TMPDIR for each testcase
  40. _TMPDIR=$TMPDIR
  41. TMPDIR=$TMPDIR/`echo -n "$(date +%s).$LOGPREFIX" | sed -e 's,[ /],_,g' -e 's,:$,,g'`
  42. mkdir -p "$TMPDIR"
  43. output=`"$@" 2>&1` || res=$?
  44. TMPDIR=$_TMPDIR
  45. if [ "$res" -eq "$EXPECTEDRES" ]; then
  46. if [ "$res" -eq 0 ]; then
  47. echo $LOGPREFIX PASS
  48. else
  49. echo $LOGPREFIX XFAIL
  50. fi
  51. else
  52. echo "Error[$res]: $output"
  53. if [ "$res" -eq 0 ]; then
  54. echo $LOGPREFIX XPASS
  55. elif [ "$res" -eq 1 ]; then
  56. echo $LOGPREFIX FAIL
  57. else
  58. # Any exit code other than 1 or 0, indicates a hard error,
  59. # not a test error
  60. echo $LOGPREFIX ERROR
  61. return 99
  62. fi
  63. return 1
  64. fi
  65. }
  66. testcase() { _testcase 0 "$@"; }
  67. testcase_fail() { _testcase 1 "$@"; }
  68. ### LUKS1 tests
  69. eval testcase "'LUKS1 test cryptsetup defaults:'" \
  70. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS
  71. eval testcase "'LUKS1 test with twofish cipher:'" \
  72. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  73. "--cs-opts='--cipher twofish-xts-plain64'"
  74. eval testcase "'LUKS1 test key file support:'" \
  75. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  76. --keyfile
  77. eval testcase "'LUKS1 test key file with offset:'" \
  78. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  79. --keyfile --cs-opts="--keyfile-offset=237"
  80. eval testcase "'LUKS1 test key file with offset and size:'" \
  81. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  82. --keyfile "--cs-opts='--keyfile-offset=237 --keyfile-size=1023'"
  83. eval testcase "'LUKS1 test detached header support:'" \
  84. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  85. --detached-header
  86. eval testcase "'LUKS1 test both detached header and key file:'" \
  87. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  88. --keyfile --detached-header
  89. ### LUKS2 tests (mirroring the LUKS1 tests above)
  90. LUKS2_COMMON_OPTS="--luks=2 --cs-opts=--pbkdf=pbkdf2"
  91. eval testcase "'LUKS2 test cryptsetup defaults:'" \
  92. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS
  93. eval testcase "'LUKS2 test with twofish cipher:'" \
  94. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  95. "--cs-opts='--cipher twofish-xts-plain64'"
  96. eval testcase "'LUKS2 test key file support:'" \
  97. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  98. --keyfile
  99. eval testcase "'LUKS2 test key file with offset:'" \
  100. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  101. --keyfile --cs-opts="--keyfile-offset=237"
  102. eval testcase "'LUKS2 test key file with offset and size:'" \
  103. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  104. --keyfile "--cs-opts='--keyfile-offset=237 --keyfile-size=1023'"
  105. eval testcase "'LUKS2 test detached header support:'" \
  106. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  107. --detached-header
  108. eval testcase "'LUKS2 test both detached header and key file:'" \
  109. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  110. --keyfile --detached-header
  111. ### LUKS1 specific tests
  112. # Tests for xts-plain and xts-plain64 modes
  113. eval testcase "'LUKS1 test cryptsetup xts-plain:'" \
  114. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  115. "--cs-opts='--cipher aes-xts-plain'"
  116. eval testcase "'LUKS1 test cryptsetup xts-plain64:'" \
  117. @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \
  118. "--cs-opts='--cipher aes-xts-plain64'"
  119. ### LUKS2 specific tests
  120. eval testcase "'LUKS2 test with 1k sector size:'" \
  121. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  122. "--cs-opts='--sector-size 1024'"
  123. eval testcase "'LUKS2 test with 2k sector size:'" \
  124. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  125. "--cs-opts='--sector-size 2048'"
  126. eval testcase "'LUKS2 test with 4k sector size:'" \
  127. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  128. "--cs-opts='--sector-size 4096'"
  129. eval testcase "'LUKS2 test with non-default key slot:'" \
  130. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  131. "--cs-opts='--key-slot 5'"
  132. eval testcase "'LUKS2 test with different metadata size:'" \
  133. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  134. "--cs-opts='--luks2-metadata-size 512k'"
  135. # TODO: Expect a failure with LUKS2 volumes with argon2 key derivation
  136. eval testcase_fail "'LUKS2 test with argon2 pbkdf:'" \
  137. @builddir@/grub-shell-luks-tester --luks=2 $COMMON_OPTS \
  138. "--cs-opts='--pbkdf-memory 32'" "--cs-opts='--pbkdf-parallel 1'"
  139. # Add good password to second slot and change first slot to unchecked password
  140. csscript=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 99
  141. cat >$csscript <<'EOF'
  142. CSOPTS="--pbkdf-force-iterations 1000 --pbkdf=pbkdf2 --force-password"
  143. cryptsetup $CSOPTS --key-file $lukskeyfile luksAddKey $luksdiskfile $lukskeyfile
  144. echo "newpass" | cryptsetup $CSOPTS --key-file $lukskeyfile --key-slot 0 luksChangeKey $luksdiskfile
  145. EOF
  146. eval testcase "'LUKS2 test with second key slot and first slot using different password:'" \
  147. @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \
  148. "--cs-script='$csscript'"
  149. exit 0