mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-11 02:40:01 +01:00
Compare commits
125 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4e9252270 | ||
|
|
21c4d1507a | ||
|
|
3e763e1cd2 | ||
|
|
060c807bc8 | ||
|
|
0f82f90e14 | ||
|
|
66b6808cb8 | ||
|
|
99b3a69e52 | ||
|
|
1a940a49cb | ||
|
|
645c8b6026 | ||
|
|
00fc4beac1 | ||
|
|
b220bef821 | ||
|
|
d1cfdc7fd7 | ||
|
|
ccfbd302bd | ||
|
|
0dda2b0e33 | ||
|
|
4e70b9ce16 | ||
|
|
7d8a62b7d5 | ||
|
|
b383e11372 | ||
|
|
a6e9399f7b | ||
|
|
e4fd2fafed | ||
|
|
e31b20d8d8 | ||
|
|
838c91fef3 | ||
|
|
be8c39749f | ||
|
|
cec5f8a8bf | ||
|
|
f6dde0f39e | ||
|
|
2f265f81e7 | ||
|
|
9da865e685 | ||
|
|
8d4e794d39 | ||
|
|
018486cea0 | ||
|
|
96a3dc0a66 | ||
|
|
efeada291a | ||
|
|
fb6935385c | ||
|
|
599748bc9f | ||
|
|
d0d507e325 | ||
|
|
7d8f64fe21 | ||
|
|
a52dbc43d3 | ||
|
|
7df458b74e | ||
|
|
bcd7527938 | ||
|
|
e7141383e3 | ||
|
|
cd968551d6 | ||
|
|
6a3e585141 | ||
|
|
6f48bdf9e5 | ||
|
|
517b5da67a | ||
|
|
98460af44f | ||
|
|
7213d5a76b | ||
|
|
bb29c5b322 | ||
|
|
58ad7bae48 | ||
|
|
82a3480b12 | ||
|
|
c00811a846 | ||
|
|
27eaf46c8a | ||
|
|
202aeece3c | ||
|
|
825fc895dc | ||
|
|
a74aecedf1 | ||
|
|
fa1f63bcd0 | ||
|
|
c2bce3e93e | ||
|
|
a46733e701 | ||
|
|
8f350f9b9f | ||
|
|
484692aacd | ||
|
|
7f0df99511 | ||
|
|
bebd2fe7e7 | ||
|
|
36e8839675 | ||
|
|
61305a50c1 | ||
|
|
1d7749a40f | ||
|
|
f01d044618 | ||
|
|
31532adf86 | ||
|
|
879e06db39 | ||
|
|
4beb0f702a | ||
|
|
a771460dbd | ||
|
|
f849f83d84 | ||
|
|
1d084a41ad | ||
|
|
c4198986f1 | ||
|
|
7514786b20 | ||
|
|
9df042c0b8 | ||
|
|
37e0150f70 | ||
|
|
294e4cbcb7 | ||
|
|
952716afe1 | ||
|
|
24aba9a514 | ||
|
|
905993751c | ||
|
|
0b10d877b0 | ||
|
|
874fa5810d | ||
|
|
5be31bbce6 | ||
|
|
a6e3a31690 | ||
|
|
506f3f7b57 | ||
|
|
cd1c36ef94 | ||
|
|
ee689d88b4 | ||
|
|
b93b676336 | ||
|
|
1c6d66fccc | ||
|
|
114356ad2e | ||
|
|
7ab419701c | ||
|
|
d41b1a7560 | ||
|
|
622943529e | ||
|
|
9d7cc152f9 | ||
|
|
3f73d448f3 | ||
|
|
a1b606803f | ||
|
|
b2c7b40568 | ||
|
|
0cbe09d43a | ||
|
|
f1d5b94762 | ||
|
|
6fc2e7c774 | ||
|
|
3b39c1d1ef | ||
|
|
5a3e4abf71 | ||
|
|
48e9362186 | ||
|
|
03a74b74e5 | ||
|
|
248f99cad3 | ||
|
|
d2f0773eb8 | ||
|
|
dd36d56d47 | ||
|
|
0270fc66a1 | ||
|
|
69a844c654 | ||
|
|
5b5a64361f | ||
|
|
26f6d1cb10 | ||
|
|
f87eb1668a | ||
|
|
3114abfd55 | ||
|
|
5a94cff91e | ||
|
|
d704e87ee4 | ||
|
|
c8ce996872 | ||
|
|
0e7b068061 | ||
|
|
71dd149ca2 | ||
|
|
b30ba41d6a | ||
|
|
a0bf790892 | ||
|
|
caefc4eb8e | ||
|
|
31364c17d6 | ||
|
|
5e56966e72 | ||
|
|
1f951ed7ec | ||
|
|
ecd82f1fc9 | ||
|
|
7aaf1eeb1b | ||
|
|
e53fe70668 | ||
|
|
9e2e0a4a2d |
@@ -44,13 +44,6 @@ function check_nonroot
|
||||
|
||||
$MAKE || return
|
||||
|
||||
sudo modprobe dm-crypt
|
||||
sudo modprobe dm-verity
|
||||
sudo modprobe dm-integrity
|
||||
uname -a
|
||||
sudo dmsetup version
|
||||
sudo dmsetup targets
|
||||
|
||||
make check
|
||||
}
|
||||
|
||||
@@ -69,13 +62,6 @@ function check_root
|
||||
|
||||
$MAKE || return
|
||||
|
||||
sudo modprobe dm-crypt
|
||||
sudo modprobe dm-verity
|
||||
sudo modprobe dm-integrity
|
||||
uname -a
|
||||
sudo dmsetup version
|
||||
sudo dmsetup targets
|
||||
|
||||
# FIXME: we should use -E option here
|
||||
sudo make check
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- wip-luks2
|
||||
- v2_0_x
|
||||
|
||||
before_install:
|
||||
- uname -a
|
||||
|
||||
22
README.md
22
README.md
@@ -18,8 +18,7 @@ LUKS Design
|
||||
-----------
|
||||
**LUKS** is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not
|
||||
only facilitate compatibility among distributions, but also provides secure management of multiple user passwords.
|
||||
In contrast to existing solution, LUKS stores all setup necessary setup information in the partition header,
|
||||
enabling the user to transport or migrate his data seamlessly.
|
||||
LUKS stores all necessary setup information in the partition header, enabling to transport or migrate data seamlessly.
|
||||
|
||||
Last version of the LUKS format specification is
|
||||
[available here](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
|
||||
@@ -42,13 +41,22 @@ Download
|
||||
--------
|
||||
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest cryptsetup version is 2.0.3**
|
||||
* [cryptsetup-2.0.3.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.xz)
|
||||
* Signature [cryptsetup-2.0.3.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.sign)
|
||||
**The latest cryptsetup version is 2.0.6**
|
||||
* [cryptsetup-2.0.6.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz)
|
||||
* Signature [cryptsetup-2.0.6.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.0.3 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.3-ReleaseNotes).
|
||||
* [Cryptsetup 2.0.6 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.0.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.5-ReleaseNotes).
|
||||
* [Version 2.0.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.4-ReleaseNotes).
|
||||
* [Version 2.0.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.3-ReleaseNotes).
|
||||
* [Version 2.0.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.2-ReleaseNotes).
|
||||
@@ -82,7 +90,7 @@ Source and API docs
|
||||
For development version code, please refer to [source](https://gitlab.com/cryptsetup/cryptsetup/tree/master) page,
|
||||
mirror on [kernel.org](https://git.kernel.org/cgit/utils/cryptsetup/cryptsetup.git/) or [GitHub](https://github.com/mbroz/cryptsetup).
|
||||
|
||||
For libcryptsetup documentation see [libcryptsetup API](https://gitlab.com/cryptsetup/cryptsetup/wikis/API/index.html) page.
|
||||
For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeople.org/libcryptsetup_API/) page.
|
||||
|
||||
The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
|
||||
|
||||
|
||||
175
configure.ac
175
configure.ac
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.0.4])
|
||||
AC_INIT([cryptsetup],[2.0.6])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
@@ -63,7 +63,9 @@ AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
|
||||
AC_ARG_ENABLE(keyring, AS_HELP_STRING([--disable-keyring],[disable kernel keyring support and builtin kernel keyring token]),[], [enable_keyring=yes])
|
||||
AC_ARG_ENABLE([keyring],
|
||||
AS_HELP_STRING([--disable-keyring], [disable kernel keyring support and builtin kernel keyring token]),
|
||||
[], [enable_keyring=yes])
|
||||
if test "x$enable_keyring" = "xyes"; then
|
||||
AC_CHECK_HEADERS(linux/keyctl.h,,[AC_MSG_ERROR([You need Linux kernel headers with kernel keyring service compiled.])])
|
||||
|
||||
@@ -84,7 +86,7 @@ if test "x$enable_keyring" = "xyes"; then
|
||||
|
||||
AC_DEFINE(KERNEL_KEYRING, 1, [Enable kernel keyring service support])
|
||||
fi
|
||||
AM_CONDITIONAL(KERNEL_KEYRING, test x$enable_keyring = xyes)
|
||||
AM_CONDITIONAL(KERNEL_KEYRING, test "x$enable_keyring" = "xyes")
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
@@ -92,9 +94,9 @@ AC_SUBST(UUID_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
AC_SEARCH_LIBS([clock_gettime],[rt posix4])
|
||||
AC_CHECK_FUNCS([posix_memalign clock_gettime posix_fallocate])
|
||||
AC_CHECK_FUNCS([posix_memalign clock_gettime posix_fallocate explicit_bzero])
|
||||
|
||||
if test "x$enable_largefile" = "xno" ; then
|
||||
if test "x$enable_largefile" = "xno"; then
|
||||
AC_MSG_ERROR([Building with --disable-largefile is not supported, it can cause data corruption.])
|
||||
fi
|
||||
|
||||
@@ -120,12 +122,10 @@ AC_SUBST(POPT_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl FIPS extensions (only for RHEL)
|
||||
AC_ARG_ENABLE([fips], AS_HELP_STRING([--enable-fips],[enable FIPS mode restrictions]),
|
||||
[with_fips=$enableval],
|
||||
[with_fips=no])
|
||||
|
||||
if test "x$with_fips" = "xyes"; then
|
||||
dnl FIPS extensions
|
||||
AC_ARG_ENABLE([fips],
|
||||
AS_HELP_STRING([--enable-fips], [enable FIPS mode restrictions]))
|
||||
if test "x$enable_fips" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_FIPS, 1, [Enable FIPS mode restrictions])
|
||||
|
||||
if test "x$enable_static" = "xyes" -o "x$enable_static_cryptsetup" = "xyes" ; then
|
||||
@@ -134,7 +134,7 @@ if test "x$with_fips" = "xyes"; then
|
||||
fi
|
||||
|
||||
AC_DEFUN([NO_FIPS], [
|
||||
if test "x$with_fips" = "xyes"; then
|
||||
if test "x$enable_fips" = "xyes"; then
|
||||
AC_MSG_ERROR([This option is not compatible with FIPS.])
|
||||
fi
|
||||
])
|
||||
@@ -142,12 +142,9 @@ AC_DEFUN([NO_FIPS], [
|
||||
dnl ==========================================================================
|
||||
dnl pwquality library (cryptsetup CLI only)
|
||||
AC_ARG_ENABLE([pwquality],
|
||||
AS_HELP_STRING([--enable-pwquality],
|
||||
[enable password quality checking using pwquality library]),
|
||||
[with_pwquality=$enableval],
|
||||
[with_pwquality=no])
|
||||
AS_HELP_STRING([--enable-pwquality], [enable password quality checking using pwquality library]))
|
||||
|
||||
if test "x$with_pwquality" = "xyes"; then
|
||||
if test "x$enable_pwquality" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_PWQUALITY, 1, [Enable password quality checking using pwquality library])
|
||||
PKG_CHECK_MODULES([PWQUALITY], [pwquality >= 1.0.0],,
|
||||
AC_MSG_ERROR([You need pwquality library.]))
|
||||
@@ -159,13 +156,11 @@ fi
|
||||
dnl ==========================================================================
|
||||
dnl passwdqc library (cryptsetup CLI only)
|
||||
AC_ARG_ENABLE([passwdqc],
|
||||
AS_HELP_STRING([--enable-passwdqc@<:@=CONFIG_PATH@:>@],
|
||||
[enable password quality checking using passwdqc library (optionally with CONFIG_PATH)]),
|
||||
[enable_passwdqc=$enableval],
|
||||
[enable_passwdqc=no])
|
||||
AS_HELP_STRING([--enable-passwdqc@<:@=CONFIG_PATH@:>@],
|
||||
[enable password quality checking using passwdqc library (optionally with CONFIG_PATH)]))
|
||||
|
||||
case "$enable_passwdqc" in
|
||||
yes|no) use_passwdqc_config="" ;;
|
||||
""|yes|no) use_passwdqc_config="" ;;
|
||||
/*) use_passwdqc_config="$enable_passwdqc"; enable_passwdqc=yes ;;
|
||||
*) AC_MSG_ERROR([Unrecognized --enable-passwdqc parameter.]) ;;
|
||||
esac
|
||||
@@ -177,7 +172,7 @@ if test "x$enable_passwdqc" = "xyes"; then
|
||||
PASSWDQC_LIBS="-lpasswdqc"
|
||||
fi
|
||||
|
||||
if test "x$with_pwquality$enable_passwdqc" = "xyesyes"; then
|
||||
if test "x$enable_pwquality$enable_passwdqc" = "xyesyes"; then
|
||||
AC_MSG_ERROR([--enable-pwquality and --enable-passwdqc are mutually incompatible.])
|
||||
fi
|
||||
|
||||
@@ -185,13 +180,14 @@ dnl ==========================================================================
|
||||
dnl Crypto backend functions
|
||||
|
||||
AC_DEFUN([CONFIGURE_GCRYPT], [
|
||||
if test "x$with_fips" = "xyes"; then
|
||||
if test "x$enable_fips" = "xyes"; then
|
||||
GCRYPT_REQ_VERSION=1.4.5
|
||||
else
|
||||
GCRYPT_REQ_VERSION=1.1.42
|
||||
fi
|
||||
dnl Check if we can use gcrypt PBKDF2 (1.6.0 supports empty password)
|
||||
AC_ARG_ENABLE([gcrypt-pbkdf2], AS_HELP_STRING([--enable-gcrypt-pbkdf2],[force enable internal gcrypt PBKDF2]),
|
||||
AC_ARG_ENABLE([gcrypt-pbkdf2],
|
||||
AS_HELP_STRING([--enable-gcrypt-pbkdf2], [force enable internal gcrypt PBKDF2]),
|
||||
if test "x$enableval" = "xyes"; then
|
||||
[use_internal_pbkdf2=0]
|
||||
else
|
||||
@@ -208,7 +204,7 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
|
||||
NO_FIPS([])
|
||||
fi
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
if test "x$enable_static_cryptsetup" = "xyes"; then
|
||||
saved_LIBS=$LIBS
|
||||
LIBS="$saved_LIBS $LIBGCRYPT_LIBS -static"
|
||||
AC_CHECK_LIB(gcrypt, gcry_check_version,,
|
||||
@@ -232,7 +228,7 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
|
||||
CRYPTO_LIBS=$OPENSSL_LIBS
|
||||
use_internal_pbkdf2=0
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
if test "x$enable_static_cryptsetup" = "xyes"; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
PKG_CHECK_MODULES([OPENSSL_STATIC], [openssl])
|
||||
@@ -242,7 +238,7 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_NSS], [
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
if test "x$enable_static_cryptsetup" = "xyes"; then
|
||||
AC_MSG_ERROR([Static build of cryptsetup is not supported with NSS.])
|
||||
fi
|
||||
|
||||
@@ -291,43 +287,42 @@ dnl ==========================================================================
|
||||
saved_LIBS=$LIBS
|
||||
|
||||
AC_ARG_ENABLE([static-cryptsetup],
|
||||
AS_HELP_STRING([--enable-static-cryptsetup],
|
||||
[enable build of static version of tools]))
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
if test x$enable_static = xno; then
|
||||
AS_HELP_STRING([--enable-static-cryptsetup], [enable build of static version of tools]))
|
||||
if test "x$enable_static_cryptsetup" = "xyes"; then
|
||||
if test "x$enable_static" = "xno"; then
|
||||
AC_MSG_WARN([Requested static cryptsetup build, enabling static library.])
|
||||
enable_static=yes
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(STATIC_TOOLS, test x$enable_static_cryptsetup = xyes)
|
||||
AM_CONDITIONAL(STATIC_TOOLS, test "x$enable_static_cryptsetup" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE(cryptsetup,
|
||||
AS_HELP_STRING([--disable-cryptsetup],
|
||||
[disable cryptsetup support]),[], [enable_cryptsetup=yes])
|
||||
AM_CONDITIONAL(CRYPTSETUP, test x$enable_cryptsetup = xyes)
|
||||
AC_ARG_ENABLE([cryptsetup],
|
||||
AS_HELP_STRING([--disable-cryptsetup], [disable cryptsetup support]),
|
||||
[], [enable_cryptsetup=yes])
|
||||
AM_CONDITIONAL(CRYPTSETUP, test "x$enable_cryptsetup" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE(veritysetup,
|
||||
AS_HELP_STRING([--disable-veritysetup],
|
||||
[disable veritysetup support]),[], [enable_veritysetup=yes])
|
||||
AM_CONDITIONAL(VERITYSETUP, test x$enable_veritysetup = xyes)
|
||||
AC_ARG_ENABLE([veritysetup],
|
||||
AS_HELP_STRING([--disable-veritysetup], [disable veritysetup support]),
|
||||
[], [enable_veritysetup=yes])
|
||||
AM_CONDITIONAL(VERITYSETUP, test "x$enable_veritysetup" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE([cryptsetup-reencrypt],
|
||||
AS_HELP_STRING([--disable-cryptsetup-reencrypt],
|
||||
[disable cryptsetup-reencrypt tool]),[], [enable_cryptsetup_reencrypt=yes])
|
||||
AM_CONDITIONAL(REENCRYPT, test x$enable_cryptsetup_reencrypt = xyes)
|
||||
AS_HELP_STRING([--disable-cryptsetup-reencrypt], [disable cryptsetup-reencrypt tool]),
|
||||
[], [enable_cryptsetup_reencrypt=yes])
|
||||
AM_CONDITIONAL(REENCRYPT, test "x$enable_cryptsetup_reencrypt" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE(integritysetup,
|
||||
AS_HELP_STRING([--disable-integritysetup],
|
||||
[disable integritysetup support]),[], [enable_integritysetup=yes])
|
||||
AM_CONDITIONAL(INTEGRITYSETUP, test x$enable_integritysetup = xyes)
|
||||
AC_ARG_ENABLE([integritysetup],
|
||||
AS_HELP_STRING([--disable-integritysetup], [disable integritysetup support]),
|
||||
[], [enable_integritysetup=yes])
|
||||
AM_CONDITIONAL(INTEGRITYSETUP, test "x$enable_integritysetup" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE(selinux,
|
||||
AS_HELP_STRING([--disable-selinux],
|
||||
[disable selinux support [default=auto]]),[], [])
|
||||
AC_ARG_ENABLE([selinux],
|
||||
AS_HELP_STRING([--disable-selinux], [disable selinux support [default=auto]]),
|
||||
[], [enable_selinux=yes])
|
||||
|
||||
AC_ARG_ENABLE([udev],
|
||||
AS_HELP_STRING([--disable-udev],
|
||||
[disable udev support]),[], enable_udev=yes)
|
||||
AS_HELP_STRING([--disable-udev], [disable udev support]),
|
||||
[], [enable_udev=yes])
|
||||
|
||||
dnl Try to use pkg-config for devmapper, but fallback to old detection
|
||||
PKG_CHECK_MODULES([DEVMAPPER], [devmapper >= 1.02.03],, [
|
||||
@@ -361,16 +356,14 @@ PKG_CHECK_MODULES([JSON_C], [json-c])
|
||||
dnl Crypto backend configuration.
|
||||
AC_ARG_WITH([crypto_backend],
|
||||
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [gcrypt]]),
|
||||
[], with_crypto_backend=gcrypt
|
||||
)
|
||||
[], [with_crypto_backend=gcrypt])
|
||||
|
||||
dnl Kernel crypto API backend needed for benchmark and tcrypt
|
||||
AC_ARG_ENABLE([kernel_crypto], AS_HELP_STRING([--disable-kernel_crypto],
|
||||
[disable kernel userspace crypto (no benchmark and tcrypt)]),
|
||||
[with_kernel_crypto=$enableval],
|
||||
[with_kernel_crypto=yes])
|
||||
AC_ARG_ENABLE([kernel_crypto],
|
||||
AS_HELP_STRING([--disable-kernel_crypto], [disable kernel userspace crypto (no benchmark and tcrypt)]),
|
||||
[], [enable_kernel_crypto=yes])
|
||||
|
||||
if test "x$with_kernel_crypto" = "xyes"; then
|
||||
if test "x$enable_kernel_crypto" = "xyes"; then
|
||||
AC_CHECK_HEADERS(linux/if_alg.h,,
|
||||
[AC_MSG_ERROR([You need Linux kernel headers with userspace crypto interface. (Or use --disable-kernel_crypto.)])])
|
||||
AC_DEFINE(ENABLE_AF_ALG, 1, [Enable using of kernel userspace crypto])
|
||||
@@ -384,23 +377,24 @@ case $with_crypto_backend in
|
||||
nettle) CONFIGURE_NETTLE([]) ;;
|
||||
*) AC_MSG_ERROR([Unknown crypto backend.]) ;;
|
||||
esac
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test $with_crypto_backend = gcrypt)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test $with_crypto_backend = openssl)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test $with_crypto_backend = nss)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test $with_crypto_backend = kernel)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test $with_crypto_backend = nettle)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test "$with_crypto_backend" = "gcrypt")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test "$with_crypto_backend" = "openssl")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test "$with_crypto_backend" = "nss")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test "$with_crypto_backend" = "kernel")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test "$with_crypto_backend" = "nettle")
|
||||
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_PBKDF2, test $use_internal_pbkdf2 = 1)
|
||||
AC_DEFINE_UNQUOTED(USE_INTERNAL_PBKDF2, [$use_internal_pbkdf2], [Use internal PBKDF2])
|
||||
|
||||
dnl Argon2 implementation
|
||||
AC_ARG_ENABLE(internal-argon2, AS_HELP_STRING([--disable-internal-argon2],
|
||||
[disable internal implementation of Argon2 PBKDF]),[], [enable_internal_argon2=yes])
|
||||
AC_ARG_ENABLE([internal-argon2],
|
||||
AS_HELP_STRING([--disable-internal-argon2], [disable internal implementation of Argon2 PBKDF]),
|
||||
[], [enable_internal_argon2=yes])
|
||||
|
||||
AC_ARG_ENABLE([libargon2], AS_HELP_STRING([--enable-libargon2],
|
||||
[enable external libargon2 (PHC) library (disables internal bundled version) ]),[], [enable_libargon2=no])
|
||||
AC_ARG_ENABLE([libargon2],
|
||||
AS_HELP_STRING([--enable-libargon2], [enable external libargon2 (PHC) library (disables internal bundled version)]))
|
||||
|
||||
if test x$enable_libargon2 = xyes ; then
|
||||
if test "x$enable_libargon2" = "xyes" ; then
|
||||
AC_CHECK_HEADERS(argon2.h,,
|
||||
[AC_MSG_ERROR([You need libargon2 development library installed.])])
|
||||
AC_CHECK_DECL(Argon2_id,,[AC_MSG_ERROR([You need more recent Argon2 library with support for Argon2id.])], [#include <argon2.h>])
|
||||
@@ -409,10 +403,10 @@ if test x$enable_libargon2 = xyes ; then
|
||||
else
|
||||
AC_MSG_WARN([Argon2 bundled (slow) reference implementation will be used, please consider to use system library with --enable-libargon2.])
|
||||
|
||||
AC_ARG_ENABLE(internal-sse-argon2, AS_HELP_STRING([--enable-internal-sse-argon2],
|
||||
[enable internal SSE implementation of Argon2 PBKDF]),[], [enable_internal_sse_argon2=no])
|
||||
AC_ARG_ENABLE([internal-sse-argon2],
|
||||
AS_HELP_STRING([--enable-internal-sse-argon2], [enable internal SSE implementation of Argon2 PBKDF]))
|
||||
|
||||
if test x$enable_internal_sse_argon2 = xyes ; then
|
||||
if test "x$enable_internal_sse_argon2" = "xyes"; then
|
||||
AC_MSG_CHECKING(if Argon2 SSE optimization can be used)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <emmintrin.h>
|
||||
@@ -424,17 +418,18 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$enable_internal_argon2 = xyes ; then
|
||||
if test "x$enable_internal_argon2" = "xyes"; then
|
||||
AC_DEFINE(USE_INTERNAL_ARGON2, 1, [Use internal Argon2])
|
||||
fi
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_ARGON2, test x$enable_internal_argon2 = xyes)
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_SSE_ARGON2, test x$enable_internal_sse_argon2 = xyes)
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_ARGON2, test "x$enable_internal_argon2" = "xyes")
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_SSE_ARGON2, test "x$enable_internal_sse_argon2" = "xyes")
|
||||
|
||||
dnl Link with blkid to check for other device types
|
||||
AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid],
|
||||
[disable use of blkid for device signature detection and wiping.]), [], [enable_blkid=yes])
|
||||
AC_ARG_ENABLE([blkid],
|
||||
AS_HELP_STRING([--disable-blkid], [disable use of blkid for device signature detection and wiping]),
|
||||
[], [enable_blkid=yes])
|
||||
|
||||
if test x$enable_blkid = xyes ; then
|
||||
if test "x$enable_blkid" = "xyes"; then
|
||||
PKG_CHECK_MODULES([BLKID], [blkid],[AC_DEFINE([HAVE_BLKID], 1, [Define to 1 to use blkid for detection of disk signatures.])],[LIBBLKID_LIBS="-lblkid"])
|
||||
|
||||
AC_CHECK_HEADERS(blkid/blkid.h,,[AC_MSG_ERROR([You need blkid development library installed.])])
|
||||
@@ -458,12 +453,12 @@ if test x$enable_blkid = xyes ; then
|
||||
[AC_MSG_ERROR([Can not compile with blkid support, disable it by --disable-blkid.])],
|
||||
[#include <blkid/blkid.h>])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_BLKID, test x$enable_blkid = xyes)
|
||||
AM_CONDITIONAL(HAVE_BLKID_WIPE, test x$enable_blkid_wipe = xyes)
|
||||
AM_CONDITIONAL(HAVE_BLKID_STEP_BACK, test x$enable_blkid_step_back = xyes)
|
||||
AM_CONDITIONAL(HAVE_BLKID, test "x$enable_blkid" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_BLKID_WIPE, test "x$enable_blkid_wipe" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_BLKID_STEP_BACK, test "x$enable_blkid_step_back" = "xyes")
|
||||
|
||||
dnl Magic for cryptsetup.static build.
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
if test "x$enable_static_cryptsetup" = "xyes"; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
|
||||
@@ -475,7 +470,7 @@ if test x$enable_static_cryptsetup = xyes; then
|
||||
LIBS="$saved_LIBS -static"
|
||||
PKG_CHECK_MODULES([DEVMAPPER_STATIC], [devmapper >= 1.02.27],,[
|
||||
DEVMAPPER_STATIC_LIBS=$DEVMAPPER_LIBS
|
||||
if test "x$enable_selinux" != xno; then
|
||||
if test "x$enable_selinux" = "xyes"; then
|
||||
AC_CHECK_LIB(sepol, sepol_bool_set)
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled)
|
||||
DEVMAPPER_STATIC_LIBS="$DEVMAPPER_STATIC_LIBS $LIBS"
|
||||
@@ -553,15 +548,14 @@ AC_DEFUN([CS_ABSPATH], [
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl Python bindings
|
||||
AC_ARG_ENABLE([python], AS_HELP_STRING([--enable-python],[enable Python bindings]),
|
||||
[with_python=$enableval],
|
||||
[with_python=no])
|
||||
AC_ARG_ENABLE([python],
|
||||
AS_HELP_STRING([--enable-python], [enable Python bindings]))
|
||||
|
||||
AC_ARG_WITH([python_version],
|
||||
AS_HELP_STRING([--with-python_version=VERSION], [required Python version [2.6]]),
|
||||
[PYTHON_VERSION=$withval], [PYTHON_VERSION=2.6])
|
||||
|
||||
if test "x$with_python" = "xyes"; then
|
||||
if test "x$enable_python" = "xyes"; then
|
||||
AM_PATH_PYTHON([$PYTHON_VERSION])
|
||||
|
||||
AC_PATH_PROGS([PYTHON_CONFIG], [python${PYTHON_VERSION}-config python-config], [no])
|
||||
@@ -579,7 +573,7 @@ if test "x$with_python" = "xyes"; then
|
||||
AC_MSG_RESULT($PYTHON_LIBS)
|
||||
AC_SUBST(PYTHON_LIBS)
|
||||
fi
|
||||
AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$with_python" = "xyes"])
|
||||
AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$enable_python" = "xyes"])
|
||||
|
||||
dnl ==========================================================================
|
||||
CS_STR_WITH([plain-hash], [password hashing function for plain mode], [ripemd160])
|
||||
@@ -633,8 +627,7 @@ AC_SUBST(DEFAULT_LUKS2_LOCK_DIR_PERMS)
|
||||
dnl Override default LUKS format version (for cryptsetup or cryptsetup-reencrypt format actions only).
|
||||
AC_ARG_WITH([default_luks_format],
|
||||
AS_HELP_STRING([--with-default-luks-format=FORMAT], [default LUKS format version (LUKS1/LUKS2) [LUKS1]]),
|
||||
[], with_default_luks_format=LUKS1
|
||||
)
|
||||
[], [with_default_luks_format=LUKS1])
|
||||
|
||||
case $with_default_luks_format in
|
||||
LUKS1) default_luks=CRYPT_LUKS1 ;;
|
||||
|
||||
Binary file not shown.
102
docs/v2.0.5-ReleaseNotes
Normal file
102
docs/v2.0.5-ReleaseNotes
Normal file
@@ -0,0 +1,102 @@
|
||||
Cryptsetup 2.0.5 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with new features.
|
||||
|
||||
Cryptsetup 2.x version introduces a new on-disk LUKS2 format.
|
||||
|
||||
The legacy LUKS (referenced as LUKS1) will be fully supported
|
||||
forever as well as a traditional and fully backward compatible format.
|
||||
|
||||
Please note that authenticated disk encryption, non-cryptographic
|
||||
data integrity protection (dm-integrity), use of Argon2 Password-Based
|
||||
Key Derivation Function and the LUKS2 on-disk format itself are new
|
||||
features and can contain some bugs.
|
||||
|
||||
Please do not use LUKS2 without properly configured backup or in
|
||||
production systems that need to be compatible with older systems.
|
||||
|
||||
Changes since version 2.0.4
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Wipe full header areas (including unused) during LUKS format.
|
||||
|
||||
Since this version, the whole area up to the data offset is zeroed,
|
||||
and subsequently, all keyslots areas are wiped with random data.
|
||||
This ensures that no remaining old data remains in the LUKS header
|
||||
areas, but it could slow down format operation on some devices.
|
||||
Previously only first 4k (or 32k for LUKS2) and the used keyslot
|
||||
was overwritten in the format operation.
|
||||
|
||||
* Several fixes to error messages that were unintentionally replaced
|
||||
in previous versions with a silent exit code.
|
||||
More descriptive error messages were added, including error
|
||||
messages if
|
||||
- a device is unusable (not a block device, no access, etc.),
|
||||
- a LUKS device is not detected,
|
||||
- LUKS header load code detects unsupported version,
|
||||
- a keyslot decryption fails (also happens in the cipher check),
|
||||
- converting an inactive keyslot.
|
||||
|
||||
* Device activation fails if data area overlaps with LUKS header.
|
||||
|
||||
* Code now uses explicit_bzero to wipe memory if available
|
||||
(instead of own implementation).
|
||||
|
||||
* Additional VeraCrypt modes are now supported, including Camellia
|
||||
and Kuznyechik symmetric ciphers (and cipher chains) and Streebog
|
||||
hash function. These were introduced in a recent VeraCrypt upstream.
|
||||
|
||||
Note that Kuznyechik requires out-of-tree kernel module and
|
||||
Streebog hash function is available only with the gcrypt cryptographic
|
||||
backend for now.
|
||||
|
||||
* Fixes static build for integritysetup if the pwquality library is used.
|
||||
|
||||
* Allows passphrase change for unbound keyslots.
|
||||
|
||||
* Fixes removed keyslot number in verbose message for luksKillSlot,
|
||||
luksRemoveKey and erase command.
|
||||
|
||||
* Adds blkid scan when attempting to open a plain device and warn the user
|
||||
about existing device signatures in a ciphertext device.
|
||||
|
||||
* Remove LUKS header signature if luksFormat fails to add the first keyslot.
|
||||
|
||||
* Remove O_SYNC from device open and use fsync() to speed up
|
||||
wipe operation considerably.
|
||||
|
||||
* Create --master-key-file in luksDump and fail if the file already exists.
|
||||
|
||||
* Fixes a bug when LUKS2 authenticated encryption with a detached header
|
||||
wiped the header device instead of dm-integrity data device area (causing
|
||||
unnecessary LUKS2 header auto recovery).
|
||||
|
||||
Unfinished things & TODO for next releases
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Authenticated encryption should use new algorithms from CAESAR competition
|
||||
https://competitions.cr.yp.to/caesar-submissions.html.
|
||||
AEGIS and MORUS are already available in kernel 4.18.
|
||||
|
||||
For more info about LUKS2 authenticated encryption, please see our paper
|
||||
https://arxiv.org/abs/1807.00309
|
||||
|
||||
Please note that authenticated encryption is still an experimental feature
|
||||
and can have performance problems for hish-speed devices and device
|
||||
with larger IO blocks (like RAID).
|
||||
|
||||
* Authenticated encryption do not set encryption for a dm-integrity journal.
|
||||
|
||||
While it does not influence data confidentiality or integrity protection,
|
||||
an attacker can get some more information from data journal or cause that
|
||||
system will corrupt sectors after journal replay. (That corruption will be
|
||||
detected though.)
|
||||
|
||||
* There are examples of user-defined tokens inside misc/luks2_keyslot_example
|
||||
directory (like a simple external program that uses libssh to unlock LUKS2
|
||||
using remote keyfile).
|
||||
|
||||
* The python binding (pycryptsetup) contains only basic functionality for LUKS1
|
||||
(it is not updated for new features) and will be REMOVED in version 2.1
|
||||
in favor of python bindings to the libblockdev library.
|
||||
See https://github.com/storaged-project/libblockdev/releases that
|
||||
already supports LUKS2 and VeraCrypt devices handling through libcryptsetup.
|
||||
97
docs/v2.0.6-ReleaseNotes
Normal file
97
docs/v2.0.6-ReleaseNotes
Normal file
@@ -0,0 +1,97 @@
|
||||
Cryptsetup 2.0.6 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
All users of cryptsetup 2.0.x should upgrade to this version.
|
||||
|
||||
Cryptsetup 2.x version introduces a new on-disk LUKS2 format.
|
||||
|
||||
The legacy LUKS (referenced as LUKS1) will be fully supported
|
||||
forever as well as a traditional and fully backward compatible format.
|
||||
|
||||
Please note that authenticated disk encryption, non-cryptographic
|
||||
data integrity protection (dm-integrity), use of Argon2 Password-Based
|
||||
Key Derivation Function and the LUKS2 on-disk format itself are new
|
||||
features and can contain some bugs.
|
||||
|
||||
Please do not use LUKS2 without properly configured backup or in
|
||||
production systems that need to be compatible with older systems.
|
||||
|
||||
Changes since version 2.0.5
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix support of larger metadata areas in LUKS2 header.
|
||||
|
||||
This release properly supports all specified metadata areas, as documented
|
||||
in LUKS2 format description (see docs/on-disk-format-luks2.pdf in archive).
|
||||
|
||||
Currently, only default metadata area size is used (in format or convert).
|
||||
Later cryptsetup versions will allow increasing this metadata area size.
|
||||
|
||||
* If AEAD (authenticated encryption) is used, cryptsetup now tries to check
|
||||
if the requested AEAD algorithm with specified key size is available
|
||||
in kernel crypto API.
|
||||
This change avoids formatting a device that cannot be later activated.
|
||||
|
||||
For this function, the kernel must be compiled with the
|
||||
CONFIG_CRYPTO_USER_API_AEAD option enabled.
|
||||
Note that kernel user crypto API options (CONFIG_CRYPTO_USER_API and
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER) are already mandatory for LUKS2.
|
||||
|
||||
* Fix setting of integrity no-journal flag.
|
||||
Now you can store this flag to metadata using --persistent option.
|
||||
|
||||
* Fix cryptsetup-reencrypt to not keep temporary reencryption headers
|
||||
if interrupted during initial password prompt.
|
||||
|
||||
* Adds early check to plain and LUKS2 formats to disallow device format
|
||||
if device size is not aligned to requested sector size.
|
||||
Previously it was possible, and the device was rejected to activate by
|
||||
kernel later.
|
||||
|
||||
* Fix checking of hash algorithms availability for PBKDF early.
|
||||
Previously LUKS2 format allowed non-existent hash algorithm with
|
||||
invalid keyslot preventing the device from activation.
|
||||
|
||||
* Allow Adiantum cipher construction (a non-authenticated length-preserving
|
||||
fast encryption scheme), so it can be used both for data encryption and
|
||||
keyslot encryption in LUKS1/2 devices.
|
||||
|
||||
For benchmark, use:
|
||||
# cryptsetup benchmark -c xchacha12,aes-adiantum
|
||||
# cryptsetup benchmark -c xchacha20,aes-adiantum
|
||||
|
||||
For LUKS format:
|
||||
# cryptsetup luksFormat -c xchacha20,aes-adiantum-plain64 -s 256 <device>
|
||||
|
||||
The support for Adiantum will be merged in Linux kernel 4.21.
|
||||
For more info see the paper https://eprint.iacr.org/2018/720.
|
||||
|
||||
Unfinished things & TODO for next releases
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Authenticated encryption should use new algorithms from CAESAR competition
|
||||
https://competitions.cr.yp.to/caesar-submissions.html.
|
||||
AEGIS and MORUS are already available in kernel 4.18.
|
||||
|
||||
For more info about LUKS2 authenticated encryption, please see our paper
|
||||
https://arxiv.org/abs/1807.00309
|
||||
|
||||
Please note that authenticated encryption is still an experimental feature
|
||||
and can have performance problems for high-speed devices and device
|
||||
with larger IO blocks (like RAID).
|
||||
|
||||
* Authenticated encryption do not set encryption for a dm-integrity journal.
|
||||
|
||||
While it does not influence data confidentiality or integrity protection,
|
||||
an attacker can get some more information from data journal or cause that
|
||||
system will corrupt sectors after journal replay. (That corruption will be
|
||||
detected though.)
|
||||
|
||||
* There are examples of user-defined tokens inside misc/luks2_keyslot_example
|
||||
directory (like a simple external program that uses libssh to unlock LUKS2
|
||||
using remote keyfile).
|
||||
|
||||
* The python binding (pycryptsetup) contains only basic functionality for LUKS1
|
||||
(it is not updated for new features) and will be REMOVED in version 2.1
|
||||
in favor of python bindings to the libblockdev library.
|
||||
See https://github.com/storaged-project/libblockdev/releases that
|
||||
already supports LUKS2 and VeraCrypt devices handling through libcryptsetup.
|
||||
@@ -26,53 +26,58 @@
|
||||
|
||||
struct cipher_alg {
|
||||
const char *name;
|
||||
const char *mode;
|
||||
int blocksize;
|
||||
bool wrapped_key;
|
||||
};
|
||||
|
||||
/* FIXME: Getting block size should be dynamic from cipher backend. */
|
||||
static const struct cipher_alg cipher_algs[] = {
|
||||
{ "cipher_null", 16, false },
|
||||
{ "aes", 16, false },
|
||||
{ "serpent", 16, false },
|
||||
{ "twofish", 16, false },
|
||||
{ "anubis", 16, false },
|
||||
{ "blowfish", 8, false },
|
||||
{ "camellia", 16, false },
|
||||
{ "cast5", 8, false },
|
||||
{ "cast6", 16, false },
|
||||
{ "des", 8, false },
|
||||
{ "des3_ede", 8, false },
|
||||
{ "khazad", 8, false },
|
||||
{ "seed", 16, false },
|
||||
{ "tea", 8, false },
|
||||
{ "xtea", 8, false },
|
||||
{ "paes", 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||
{ NULL, 0, false }
|
||||
{ "cipher_null", NULL, 16, false },
|
||||
{ "aes", NULL, 16, false },
|
||||
{ "serpent", NULL, 16, false },
|
||||
{ "twofish", NULL, 16, false },
|
||||
{ "anubis", NULL, 16, false },
|
||||
{ "blowfish", NULL, 8, false },
|
||||
{ "camellia", NULL, 16, false },
|
||||
{ "cast5", NULL, 8, false },
|
||||
{ "cast6", NULL, 16, false },
|
||||
{ "des", NULL, 8, false },
|
||||
{ "des3_ede", NULL, 8, false },
|
||||
{ "khazad", NULL, 8, false },
|
||||
{ "seed", NULL, 16, false },
|
||||
{ "tea", NULL, 8, false },
|
||||
{ "xtea", NULL, 8, false },
|
||||
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||
{ "xchacha12,aes", "adiantum", 32, false },
|
||||
{ "xchacha20,aes", "adiantum", 32, false },
|
||||
{ NULL, NULL, 0, false }
|
||||
};
|
||||
|
||||
static const struct cipher_alg *_get_alg(const char *name)
|
||||
static const struct cipher_alg *_get_alg(const char *name, const char *mode)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (name && cipher_algs[i].name) {
|
||||
if (!strcasecmp(name, cipher_algs[i].name))
|
||||
return &cipher_algs[i];
|
||||
if (!mode || !cipher_algs[i].mode ||
|
||||
!strncasecmp(mode, cipher_algs[i].mode, strlen(cipher_algs[i].mode)))
|
||||
return &cipher_algs[i];
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_cipher_blocksize(const char *name)
|
||||
int crypt_cipher_ivsize(const char *name, const char *mode)
|
||||
{
|
||||
const struct cipher_alg *ca = _get_alg(name);
|
||||
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||
|
||||
return ca ? ca->blocksize : -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_cipher_wrapped_key(const char *name)
|
||||
int crypt_cipher_wrapped_key(const char *name, const char *mode)
|
||||
{
|
||||
const struct cipher_alg *ca = _get_alg(name);
|
||||
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||
|
||||
return ca ? (int)ca->wrapped_key : 0;
|
||||
}
|
||||
|
||||
@@ -99,8 +99,8 @@ int argon2(const char *type, const char *password, size_t password_length,
|
||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
|
||||
|
||||
/* ciphers */
|
||||
int crypt_cipher_blocksize(const char *name);
|
||||
int crypt_cipher_wrapped_key(const char *name);
|
||||
int crypt_cipher_ivsize(const char *name, const char *mode);
|
||||
int crypt_cipher_wrapped_key(const char *name, const char *mode);
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length);
|
||||
void crypt_cipher_destroy(struct crypt_cipher *ctx);
|
||||
@@ -111,6 +111,10 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length);
|
||||
|
||||
/* Check availability of a cipher */
|
||||
int crypt_cipher_check(const char *name, const char *mode,
|
||||
const char *integrity, size_t key_length);
|
||||
|
||||
/* storage encryption wrappers */
|
||||
int crypt_storage_init(struct crypt_storage **ctx, uint64_t sector_start,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
@@ -124,8 +128,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t sector,
|
||||
/* Memzero helper (memset on stack can be optimized out) */
|
||||
static inline void crypt_backend_memzero(void *s, size_t n)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
while(n--) *p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_H */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -51,22 +52,16 @@ struct crypt_cipher {
|
||||
* ENOTSUP - AF_ALG family not available
|
||||
* (but cannot check specifically for skcipher API)
|
||||
*/
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length)
|
||||
static int _crypt_cipher_init(struct crypt_cipher **ctx,
|
||||
const void *key, size_t key_length,
|
||||
struct sockaddr_alg *sa)
|
||||
{
|
||||
struct crypt_cipher *h;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "skcipher",
|
||||
};
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
|
||||
"%s(%s)", mode, name);
|
||||
|
||||
h->opfd = -1;
|
||||
h->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||
if (h->tfmfd < 0) {
|
||||
@@ -74,14 +69,11 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (bind(h->tfmfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
|
||||
if (bind(h->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) {
|
||||
crypt_cipher_destroy(h);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "cipher_null"))
|
||||
key_length = 0;
|
||||
|
||||
if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) {
|
||||
crypt_cipher_destroy(h);
|
||||
return -EINVAL;
|
||||
@@ -97,6 +89,22 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length)
|
||||
{
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "skcipher",
|
||||
};
|
||||
|
||||
if (!strcmp(name, "cipher_null"))
|
||||
key_length = 0;
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
|
||||
|
||||
return _crypt_cipher_init(ctx, key, key_length, &sa);
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
static int crypt_cipher_crypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
@@ -191,6 +199,68 @@ void crypt_cipher_destroy(struct crypt_cipher *ctx)
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int crypt_cipher_check(const char *name, const char *mode,
|
||||
const char *integrity, size_t key_length)
|
||||
{
|
||||
struct crypt_cipher *c = NULL;
|
||||
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
|
||||
const char *salg_type;
|
||||
bool aead;
|
||||
int r;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
};
|
||||
|
||||
aead = integrity && strcmp(integrity, "none");
|
||||
|
||||
/* Remove IV if present */
|
||||
if (mode) {
|
||||
strncpy(mode_name, mode, sizeof(mode_name));
|
||||
mode_name[sizeof(mode_name) - 1] = 0;
|
||||
cipher_iv = strchr(mode_name, '-');
|
||||
if (cipher_iv) {
|
||||
*cipher_iv = '\0';
|
||||
real_mode = mode_name;
|
||||
}
|
||||
}
|
||||
|
||||
salg_type = aead ? "aead" : "skcipher";
|
||||
snprintf((char *)sa.salg_type, sizeof(sa.salg_type), "%s", salg_type);
|
||||
memset(tmp_salg_name, 0, sizeof(tmp_salg_name));
|
||||
|
||||
/* FIXME: this is duplicating a part of devmapper backend */
|
||||
if (aead && !strcmp(integrity, "poly1305"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
|
||||
else if (!real_mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else if (aead && !strcmp(real_mode, "ccm"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
|
||||
|
||||
if (r <= 0 || r > (int)(sizeof(sa.salg_name) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(sa.salg_name, tmp_salg_name, sizeof(sa.salg_name));
|
||||
|
||||
key = malloc(key_length);
|
||||
if (!key)
|
||||
return -ENOMEM;
|
||||
|
||||
r = crypt_backend_rng(key, key_length, CRYPT_RND_NORMAL, 0);
|
||||
if (r < 0) {
|
||||
free (key);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, &sa);
|
||||
if (c)
|
||||
crypt_cipher_destroy(c);
|
||||
free(key);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#else /* ENABLE_AF_ALG */
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *buffer, size_t length)
|
||||
@@ -215,4 +285,9 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
int crypt_cipher_check(const char *name, const char *mode,
|
||||
const char *integrity, size_t key_length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -60,7 +60,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
|
||||
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
|
||||
if (ctx->iv_size < 8)
|
||||
return -ENOENT;
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ int crypt_pbkdf_get_limits(const char *kdf, struct crypt_pbkdf_limits *limits)
|
||||
limits->min_parallel = 0; /* N/A */
|
||||
limits->max_parallel = 0; /* N/A */
|
||||
return 0;
|
||||
} else if (!strncmp(kdf, "argon2", 6)) {
|
||||
} else if (!strcmp(kdf, "argon2i") || !strcmp(kdf, "argon2id")) {
|
||||
limits->min_iterations = 4;
|
||||
limits->max_iterations = UINT32_MAX;
|
||||
limits->min_memory = 32;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
/* to silent gcc -Wcast-qual for const cast */
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
#define SHIFT_4K 12
|
||||
#define SECTOR_SHIFT 9
|
||||
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
|
||||
#define MAX_SECTOR_SIZE 4096 /* min page size among all platforms */
|
||||
@@ -55,6 +56,11 @@
|
||||
|
||||
#define at_least(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); })
|
||||
|
||||
#define MISALIGNED(a, b) ((a) & ((b) - 1))
|
||||
#define MISALIGNED_4K(a) MISALIGNED((a), 1 << SHIFT_4K)
|
||||
#define MISALIGNED_512(a) MISALIGNED((a), 1 << SECTOR_SHIFT)
|
||||
#define NOTPOW2(a) MISALIGNED((a), (a))
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
@@ -104,6 +110,7 @@ int device_is_rotational(struct device *device);
|
||||
size_t device_alignment(struct device *device);
|
||||
int device_direct_io(const struct device *device);
|
||||
int device_fallocate(struct device *device, uint64_t size);
|
||||
void device_sync(struct device *device, int devfd);
|
||||
|
||||
int device_open_locked(struct device *device, int flags);
|
||||
int device_read_lock(struct crypt_device *cd, struct device *device);
|
||||
|
||||
@@ -368,7 +368,7 @@ struct crypt_params_plain {
|
||||
*/
|
||||
struct crypt_params_luks1 {
|
||||
const char *hash; /**< hash used in LUKS header */
|
||||
size_t data_alignment; /**< data alignment in sectors, data offset is multiple of this */
|
||||
size_t data_alignment; /**< data area alignment in 512B sectors, data offset is multiple of this */
|
||||
const char *data_device; /**< detached encrypted data device or @e NULL */
|
||||
};
|
||||
|
||||
@@ -490,7 +490,7 @@ struct crypt_params_luks2 {
|
||||
const struct crypt_pbkdf_type *pbkdf; /**< PBKDF (and hash) parameters or @e NULL*/
|
||||
const char *integrity; /**< integrity algorithm or @e NULL */
|
||||
const struct crypt_params_integrity *integrity_params; /**< Data integrity parameters or @e NULL*/
|
||||
size_t data_alignment; /**< data alignment in sectors, data offset is multiple of this */
|
||||
size_t data_alignment; /**< data area alignment in 512B sectors, data offset is multiple of this */
|
||||
const char *data_device; /**< detached encrypted data device or @e NULL */
|
||||
uint32_t sector_size; /**< encryption sector size */
|
||||
const char *label; /**< header label or @e NULL*/
|
||||
@@ -958,7 +958,7 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_IGNORE_PERSISTENT (1 << 14)
|
||||
/** dm-verity: check_at_most_once - check data blocks only the first time */
|
||||
#define CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE (1 << 15)
|
||||
/** allow activation check including unbound keyslots (kesylots without segments) */
|
||||
/** allow activation check including unbound keyslots (keyslots without segments) */
|
||||
#define CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY (1 << 16)
|
||||
|
||||
/**
|
||||
|
||||
@@ -376,15 +376,12 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
|
||||
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
|
||||
}
|
||||
|
||||
/* get string length for key_size written in decimal system */
|
||||
static size_t get_key_size_strlen(size_t key_size)
|
||||
static size_t int_log10(size_t x)
|
||||
{
|
||||
size_t ret = 1;
|
||||
|
||||
while ((key_size /= 10))
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
size_t r = 0;
|
||||
for (x /= 10; x > 0; x /= 10)
|
||||
r++;
|
||||
return r;
|
||||
}
|
||||
|
||||
#define CLEN 64 /* 2*MAX_CIPHER_LEN */
|
||||
@@ -397,7 +394,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
|
||||
char *i_dm, int i_dm_size)
|
||||
{
|
||||
int c_size = 0, i_size = 0, i;
|
||||
char cipher[CLEN], mode[CLEN], iv[CLEN], tmp[CLEN];
|
||||
char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN];
|
||||
char capi[CAPIL];
|
||||
|
||||
if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
|
||||
@@ -410,7 +407,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
|
||||
i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv);
|
||||
if (i == 1) {
|
||||
memset(iv, 0, sizeof(iv));
|
||||
strncpy(iv, mode, sizeof(iv) - 1);
|
||||
strncpy(iv, mode, sizeof(iv)-1);
|
||||
*mode = '\0';
|
||||
if (snprintf(capi, sizeof(capi), "%s", cipher) < 0)
|
||||
return -EINVAL;
|
||||
@@ -457,7 +454,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
|
||||
static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
|
||||
{
|
||||
char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN];
|
||||
char tmp[CAPIL*2], capi[CAPIL];
|
||||
char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1];
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
@@ -500,16 +497,16 @@ static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char
|
||||
} else
|
||||
*org_i = NULL;
|
||||
memset(capi, 0, sizeof(capi));
|
||||
strncpy(capi, tmp, sizeof(capi) - 1);
|
||||
strncpy(capi, tmp, sizeof(capi)-1);
|
||||
}
|
||||
|
||||
i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher);
|
||||
if (i == 2)
|
||||
snprintf(tmp, sizeof(tmp), "%s-%s-%s", cipher, mode, iv);
|
||||
snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
|
||||
else
|
||||
snprintf(tmp, sizeof(tmp), "%s-%s", capi, iv);
|
||||
snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
|
||||
|
||||
if (!(*org_c = strdup(tmp))) {
|
||||
if (!(*org_c = strdup(dmcrypt_tmp))) {
|
||||
free(*org_i);
|
||||
*org_i = NULL;
|
||||
return -ENOMEM;
|
||||
@@ -561,7 +558,7 @@ static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd, uint32_t fl
|
||||
null_cipher = 1;
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
|
||||
keystr_len = strlen(dmd->u.crypt.vk->key_description) + get_key_size_strlen(dmd->u.crypt.vk->keylength) + 9;
|
||||
keystr_len = strlen(dmd->u.crypt.vk->key_description) + int_log10(dmd->u.crypt.vk->keylength) + 10;
|
||||
hexkey = crypt_safe_alloc(keystr_len);
|
||||
} else
|
||||
hexkey = crypt_safe_alloc(null_cipher ? 2 : (dmd->u.crypt.vk->keylength * 2 + 1));
|
||||
@@ -687,7 +684,7 @@ static char *get_dm_integrity_params(struct crypt_dm_active_device *dmd, uint32_
|
||||
{
|
||||
int r, max_size, num_options = 0;
|
||||
char *params, *hexkey, mode;
|
||||
char features[256], feature[256];
|
||||
char features[512], feature[256];
|
||||
|
||||
if (!dmd)
|
||||
return NULL;
|
||||
@@ -2131,7 +2128,7 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
goto out;
|
||||
|
||||
if (vk->key_description)
|
||||
msg_size = strlen(vk->key_description) + get_key_size_strlen(vk->keylength) + 17;
|
||||
msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
|
||||
else
|
||||
msg_size = vk->keylength * 2 + 10; // key set <key>
|
||||
|
||||
|
||||
@@ -64,31 +64,34 @@ out:
|
||||
/* diffuse: Information spreading over the whole dataset with
|
||||
* the help of hash function.
|
||||
*/
|
||||
|
||||
static int diffuse(char *src, char *dst, size_t size, const char *hash_name)
|
||||
{
|
||||
int hash_size = crypt_hash_size(hash_name);
|
||||
int r, hash_size = crypt_hash_size(hash_name);
|
||||
unsigned int digest_size;
|
||||
unsigned int i, blocks, padding;
|
||||
|
||||
if (hash_size <= 0)
|
||||
return 1;
|
||||
return -EINVAL;
|
||||
digest_size = hash_size;
|
||||
|
||||
blocks = size / digest_size;
|
||||
padding = size % digest_size;
|
||||
|
||||
for (i = 0; i < blocks; i++)
|
||||
if(hash_buf(src + digest_size * i,
|
||||
for (i = 0; i < blocks; i++) {
|
||||
r = hash_buf(src + digest_size * i,
|
||||
dst + digest_size * i,
|
||||
i, (size_t)digest_size, hash_name))
|
||||
return 1;
|
||||
i, (size_t)digest_size, hash_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if(padding)
|
||||
if(hash_buf(src + digest_size * i,
|
||||
if (padding) {
|
||||
r = hash_buf(src + digest_size * i,
|
||||
dst + digest_size * i,
|
||||
i, (size_t)padding, hash_name))
|
||||
return 1;
|
||||
i, (size_t)padding, hash_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -104,17 +107,19 @@ int AF_split(const char *src, char *dst, size_t blocksize,
|
||||
{
|
||||
unsigned int i;
|
||||
char *bufblock;
|
||||
int r = -EINVAL;
|
||||
int r;
|
||||
|
||||
if((bufblock = calloc(blocksize, 1)) == NULL) return -ENOMEM;
|
||||
|
||||
/* process everything except the last block */
|
||||
for(i=0; i<blocknumbers-1; i++) {
|
||||
r = crypt_random_get(NULL, dst+(blocksize*i), blocksize, CRYPT_RND_NORMAL);
|
||||
if(r < 0) goto out;
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
XORblock(dst+(blocksize*i),bufblock,bufblock,blocksize);
|
||||
if(diffuse(bufblock, bufblock, blocksize, hash))
|
||||
r = diffuse(bufblock, bufblock, blocksize, hash);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
/* the last block is computed */
|
||||
@@ -130,7 +135,7 @@ int AF_merge(const char *src, char *dst, size_t blocksize,
|
||||
{
|
||||
unsigned int i;
|
||||
char *bufblock;
|
||||
int r = -EINVAL;
|
||||
int r;
|
||||
|
||||
if((bufblock = calloc(blocksize, 1)) == NULL)
|
||||
return -ENOMEM;
|
||||
@@ -138,7 +143,8 @@ int AF_merge(const char *src, char *dst, size_t blocksize,
|
||||
memset(bufblock,0,blocksize);
|
||||
for(i=0; i<blocknumbers-1; i++) {
|
||||
XORblock(src+(blocksize*i),bufblock,bufblock,blocksize);
|
||||
if(diffuse(bufblock, bufblock, blocksize, hash))
|
||||
r = diffuse(bufblock, bufblock, blocksize, hash);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
XORblock(src + blocksize * i, bufblock, dst, blocksize);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "luks.h"
|
||||
#include "af.h"
|
||||
#include "internal.h"
|
||||
@@ -150,7 +151,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
int devfd = -1, r = 0;
|
||||
|
||||
/* Only whole sector writes supported */
|
||||
if (srcLength % SECTOR_SIZE)
|
||||
if (MISALIGNED_512(srcLength))
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
@@ -193,8 +194,10 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
if (devfd >= 0)
|
||||
if (devfd >= 0) {
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
}
|
||||
if (r)
|
||||
log_err(ctx, _("IO error while encrypting keyslot."));
|
||||
|
||||
@@ -210,10 +213,11 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct crypt_storage *s;
|
||||
struct stat st;
|
||||
int devfd = -1, r = 0;
|
||||
|
||||
/* Only whole sector reads supported */
|
||||
if (dstLength % SECTOR_SIZE)
|
||||
if (MISALIGNED_512(dstLength))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
@@ -235,17 +239,26 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
|
||||
log_dbg("Using userspace crypto wrapper to access keyslot area.");
|
||||
|
||||
r = -EIO;
|
||||
|
||||
/* Read buffer from device */
|
||||
devfd = device_open(device, O_RDONLY);
|
||||
if (devfd < 0)
|
||||
goto bad;
|
||||
if (devfd < 0) {
|
||||
log_err(ctx, _("Cannot open device %s."), device_path(device));
|
||||
crypt_storage_destroy(s);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (read_lseek_blockwise(devfd, device_block_size(device),
|
||||
device_alignment(device), dst, dstLength,
|
||||
sector * SECTOR_SIZE) < 0)
|
||||
goto bad;
|
||||
sector * SECTOR_SIZE) < 0) {
|
||||
if (!fstat(devfd, &st) && (st.st_size < (off_t)dstLength))
|
||||
log_err(ctx, _("Device %s is too small."), device_path(device));
|
||||
else
|
||||
log_err(ctx, _("IO error while decrypting keyslot."));
|
||||
|
||||
close(devfd);
|
||||
crypt_storage_destroy(s);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
close(devfd);
|
||||
|
||||
@@ -253,13 +266,5 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
r = crypt_storage_decrypt(s, 0, dstLength / SECTOR_SIZE, dst);
|
||||
crypt_storage_destroy(s);
|
||||
|
||||
return r;
|
||||
bad:
|
||||
if (devfd >= 0)
|
||||
close(devfd);
|
||||
|
||||
log_err(ctx, _("IO error while decrypting keyslot."));
|
||||
crypt_storage_destroy(s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -378,8 +378,10 @@ int LUKS_hdr_restore(
|
||||
/* Be sure to reload new data */
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
out:
|
||||
if (devfd >= 0)
|
||||
if (devfd >= 0) {
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
}
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
@@ -681,6 +683,8 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
|
||||
&convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
||||
if (r)
|
||||
log_err(ctx, _("Error during update of LUKS header on device %s."), device_path(device));
|
||||
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
|
||||
/* Re-read header from disk to be sure that in-memory and on-disk data are the same. */
|
||||
@@ -1206,3 +1210,56 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
free(dm_cipher);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_wipe_header_areas(struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
int i, r;
|
||||
uint64_t offset, length;
|
||||
size_t wipe_block;
|
||||
|
||||
/* Wipe complete header, keyslots and padding areas with zeroes. */
|
||||
offset = 0;
|
||||
length = (uint64_t)hdr->payloadOffset * SECTOR_SIZE;
|
||||
wipe_block = 1024 * 1024;
|
||||
|
||||
/* On detached header or bogus header, wipe at least the first 4k */
|
||||
if (length == 0 || length > (LUKS_MAX_KEYSLOT_SIZE * LUKS_NUMKEYS)) {
|
||||
length = 4096;
|
||||
wipe_block = 4096;
|
||||
}
|
||||
|
||||
log_dbg("Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
|
||||
offset, length + offset);
|
||||
|
||||
r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_ZERO,
|
||||
offset, length, wipe_block, NULL, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Wipe keyslots areas */
|
||||
wipe_block = 1024 * 1024;
|
||||
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
r = LUKS_keyslot_area(hdr, i, &offset, &length);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Ignore too big LUKS1 keyslots here */
|
||||
if (length > LUKS_MAX_KEYSLOT_SIZE ||
|
||||
offset > (LUKS_MAX_KEYSLOT_SIZE - length))
|
||||
continue;
|
||||
|
||||
if (length == 0 || offset < 4096)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg("Wiping keyslot %i area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
|
||||
i, offset, length + offset);
|
||||
|
||||
r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_RANDOM,
|
||||
offset, length, wipe_block, NULL, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
/* Offset to keyslot area [in bytes] */
|
||||
#define LUKS_ALIGN_KEYSLOTS 4096
|
||||
|
||||
/* Maximal LUKS header size, for wipe [in bytes] */
|
||||
#define LUKS_MAX_KEYSLOT_SIZE 0x1000000 /* 16 MB, up to 32768 bits key */
|
||||
|
||||
/* Any integer values are stored in network byte order on disk and must be
|
||||
converted */
|
||||
|
||||
@@ -168,6 +171,9 @@ int LUKS_del_key(
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_wipe_header_areas(struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot);
|
||||
int LUKS_keyslot_find_empty(struct luks_phdr *hdr);
|
||||
int LUKS_keyslot_active_count(struct luks_phdr *hdr);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#define LUKS2_KEYSLOTS_MAX 32
|
||||
#define LUKS2_TOKENS_MAX 32
|
||||
#define LUKS2_SEGMENT_MAX 32
|
||||
|
||||
#define LUKS2_BUILTIN_TOKEN_PREFIX "luks2-"
|
||||
#define LUKS2_BUILTIN_TOKEN_PREFIX_LEN 6
|
||||
@@ -330,6 +331,12 @@ int LUKS2_generate_hdr(
|
||||
unsigned int alignOffset,
|
||||
int detached_metadata_device);
|
||||
|
||||
int LUKS2_check_metadata_area_size(uint64_t metadata_size);
|
||||
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size);
|
||||
|
||||
int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr);
|
||||
|
||||
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
|
||||
int LUKS2_get_sector_size(struct luks2_hdr *hdr);
|
||||
const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);
|
||||
|
||||
@@ -26,12 +26,13 @@
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
json_object *parse_json_len(const char *json_area, int length, int *end_offset)
|
||||
json_object *parse_json_len(const char *json_area, uint64_t max_length, int *json_len)
|
||||
{
|
||||
json_object *jobj;
|
||||
struct json_tokener *jtok;
|
||||
|
||||
if (!json_area || length <= 0)
|
||||
/* INT32_MAX is internal (json-c) json_tokener_parse_ex() limit */
|
||||
if (!json_area || max_length > INT32_MAX)
|
||||
return NULL;
|
||||
|
||||
jtok = json_tokener_new();
|
||||
@@ -40,13 +41,13 @@ json_object *parse_json_len(const char *json_area, int length, int *end_offset)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobj = json_tokener_parse_ex(jtok, json_area, length);
|
||||
jobj = json_tokener_parse_ex(jtok, json_area, max_length);
|
||||
if (!jobj)
|
||||
log_dbg("ERROR: Failed to parse json data (%d): %s",
|
||||
json_tokener_get_error(jtok),
|
||||
json_tokener_error_desc(json_tokener_get_error(jtok)));
|
||||
else
|
||||
*end_offset = jtok->char_offset;
|
||||
*json_len = jtok->char_offset;
|
||||
|
||||
json_tokener_free(jtok);
|
||||
|
||||
@@ -204,6 +205,12 @@ static int hdr_disk_sanity_check_pre(struct luks2_hdr_disk *hdr,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
|
||||
log_dbg("LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
|
||||
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* FIXME: sanity check checksum alg. */
|
||||
|
||||
log_dbg("LUKS2 header version %u of size %u bytes, checksum %s.",
|
||||
@@ -341,6 +348,7 @@ static int hdr_write_disk(struct device *device, struct luks2_hdr *hdr,
|
||||
LUKS2_HDR_BIN_LEN, offset) < (ssize_t)LUKS2_HDR_BIN_LEN)
|
||||
r = -EIO;
|
||||
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
@@ -387,11 +395,6 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdr->hdr_size != LUKS2_HDR_16K_LEN) {
|
||||
log_dbg("Unsupported LUKS2 header size (%zu).", hdr->hdr_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = LUKS2_check_device_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -448,7 +451,7 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
|
||||
return r;
|
||||
}
|
||||
|
||||
static int validate_json_area(const char *json_area, int start, int length)
|
||||
static int validate_json_area(const char *json_area, uint64_t json_len, uint64_t max_length)
|
||||
{
|
||||
char c;
|
||||
|
||||
@@ -458,7 +461,7 @@ static int validate_json_area(const char *json_area, int start, int length)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (start >= length) {
|
||||
if (json_len >= max_length) {
|
||||
log_dbg("ERROR: Missing trailing null byte beyond parsed json data string.");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -466,22 +469,22 @@ static int validate_json_area(const char *json_area, int start, int length)
|
||||
/*
|
||||
* TODO:
|
||||
* validate there are legal json format characters between
|
||||
* 'json_area' and 'json_area + start'
|
||||
* 'json_area' and 'json_area + json_len'
|
||||
*/
|
||||
|
||||
do {
|
||||
c = *(json_area + start);
|
||||
c = *(json_area + json_len);
|
||||
if (c != '\0') {
|
||||
log_dbg("ERROR: Forbidden ascii code 0x%02hhx found beyond json data string at offset %d.",
|
||||
c, start);
|
||||
log_dbg("ERROR: Forbidden ascii code 0x%02hhx found beyond json data string at offset %" PRIu64,
|
||||
c, json_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
} while (++start < length);
|
||||
} while (++json_len < max_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_luks2_json_object(json_object *jobj_hdr)
|
||||
static int validate_luks2_json_object(json_object *jobj_hdr, uint64_t length)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -492,14 +495,14 @@ static int validate_luks2_json_object(json_object *jobj_hdr)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = LUKS2_hdr_validate(jobj_hdr);
|
||||
r = LUKS2_hdr_validate(jobj_hdr, length);
|
||||
if (r) {
|
||||
log_dbg("Repairing JSON metadata.");
|
||||
/* try to correct known glitches */
|
||||
LUKS2_hdr_repair(jobj_hdr);
|
||||
|
||||
/* run validation again */
|
||||
r = LUKS2_hdr_validate(jobj_hdr);
|
||||
r = LUKS2_hdr_validate(jobj_hdr, length);
|
||||
}
|
||||
|
||||
if (r)
|
||||
@@ -508,20 +511,20 @@ static int validate_luks2_json_object(json_object *jobj_hdr)
|
||||
return r;
|
||||
}
|
||||
|
||||
static json_object *parse_and_validate_json(const char *json_area, int length)
|
||||
static json_object *parse_and_validate_json(const char *json_area, uint64_t max_length)
|
||||
{
|
||||
int offset, r;
|
||||
json_object *jobj = parse_json_len(json_area, length, &offset);
|
||||
int json_len, r;
|
||||
json_object *jobj = parse_json_len(json_area, max_length, &json_len);
|
||||
|
||||
if (!jobj)
|
||||
return NULL;
|
||||
|
||||
/* successful parse_json_len must not return offset <= 0 */
|
||||
assert(offset > 0);
|
||||
assert(json_len > 0);
|
||||
|
||||
r = validate_json_area(json_area, offset, length);
|
||||
r = validate_json_area(json_area, json_len, max_length);
|
||||
if (!r)
|
||||
r = validate_luks2_json_object(jobj);
|
||||
r = validate_luks2_json_object(jobj, max_length);
|
||||
|
||||
if (r) {
|
||||
json_object_put(jobj);
|
||||
|
||||
@@ -58,7 +58,7 @@ json_object *LUKS2_get_tokens_jobj(struct luks2_hdr *hdr);
|
||||
void hexprint_base64(struct crypt_device *cd, json_object *jobj,
|
||||
const char *sep, const char *line_sep);
|
||||
|
||||
json_object *parse_json_len(const char *json_area, int length, int *end_offset);
|
||||
json_object *parse_json_len(const char *json_area, uint64_t max_length, int *json_len);
|
||||
uint64_t json_object_get_uint64(json_object *jobj);
|
||||
uint32_t json_object_get_uint32(json_object *jobj);
|
||||
json_object *json_object_new_uint64(uint64_t value);
|
||||
@@ -73,7 +73,7 @@ void JSON_DBG(json_object *jobj, const char *desc);
|
||||
json_object *json_contains(json_object *jobj, const char *name, const char *section,
|
||||
const char *key, json_type type);
|
||||
|
||||
int LUKS2_hdr_validate(json_object *hdr_jobj);
|
||||
int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t json_size);
|
||||
int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key);
|
||||
int LUKS2_check_json_size(const struct luks2_hdr *hdr);
|
||||
int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const char *key);
|
||||
|
||||
@@ -114,6 +114,22 @@ int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUKS2_check_metadata_area_size(uint64_t metadata_size)
|
||||
{
|
||||
/* see LUKS2_HDR2_OFFSETS */
|
||||
return (metadata_size != 0x004000 &&
|
||||
metadata_size != 0x008000 && metadata_size != 0x010000 &&
|
||||
metadata_size != 0x020000 && metadata_size != 0x040000 &&
|
||||
metadata_size != 0x080000 && metadata_size != 0x100000 &&
|
||||
metadata_size != 0x200000 && metadata_size != 0x400000);
|
||||
}
|
||||
|
||||
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size)
|
||||
{
|
||||
return (MISALIGNED_4K(keyslots_size) ||
|
||||
keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE);
|
||||
}
|
||||
|
||||
int LUKS2_generate_hdr(
|
||||
struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
@@ -122,9 +138,9 @@ int LUKS2_generate_hdr(
|
||||
const char *cipherMode,
|
||||
const char *integrity,
|
||||
const char *uuid,
|
||||
unsigned int sector_size,
|
||||
unsigned int alignPayload,
|
||||
unsigned int alignOffset,
|
||||
unsigned int sector_size, /* in bytes */
|
||||
unsigned int alignPayload, /* in bytes */
|
||||
unsigned int alignOffset, /* in bytes */
|
||||
int detached_metadata_device)
|
||||
{
|
||||
struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config;
|
||||
@@ -182,11 +198,11 @@ int LUKS2_generate_hdr(
|
||||
jobj_segment = json_object_new_object();
|
||||
json_object_object_add(jobj_segment, "type", json_object_new_string("crypt"));
|
||||
if (detached_metadata_device)
|
||||
offset = (uint64_t)alignPayload * sector_size;
|
||||
offset = (uint64_t)alignPayload;
|
||||
else {
|
||||
//FIXME
|
||||
//offset = size_round_up(areas[7].offset + areas[7].length, alignPayload * SECTOR_SIZE);
|
||||
offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayload * sector_size);
|
||||
offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayload);
|
||||
offset += alignOffset;
|
||||
}
|
||||
|
||||
@@ -229,3 +245,44 @@ int LUKS2_generate_hdr(
|
||||
JSON_DBG(hdr->jobj, "Header JSON");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr)
|
||||
{
|
||||
int r;
|
||||
uint64_t offset, length;
|
||||
size_t wipe_block;
|
||||
|
||||
/* Wipe complete header, keyslots and padding areas with zeroes. */
|
||||
offset = 0;
|
||||
length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
|
||||
wipe_block = 1024 * 1024;
|
||||
|
||||
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
return -EINVAL;
|
||||
|
||||
/* On detached header wipe at least the first 4k */
|
||||
if (length == 0) {
|
||||
length = 4096;
|
||||
wipe_block = 4096;
|
||||
}
|
||||
|
||||
log_dbg("Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
|
||||
offset, length + offset);
|
||||
|
||||
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
|
||||
offset, length, wipe_block, NULL, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Wipe keyslot area */
|
||||
wipe_block = 1024 * 1024;
|
||||
offset = get_min_offset(hdr);
|
||||
length = LUKS2_keyslots_size(hdr->jobj);
|
||||
|
||||
log_dbg("Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
|
||||
offset, length + offset);
|
||||
|
||||
return crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_RANDOM,
|
||||
offset, length, wipe_block, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -363,12 +363,13 @@ static json_bool segment_has_digest(const char *segment_name, json_object *jobj_
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static json_bool validate_intervals(int length, const struct interval *ix, uint64_t *data_offset)
|
||||
static json_bool validate_intervals(int length, const struct interval *ix,
|
||||
uint64_t metadata_size, uint64_t keyslots_area_end)
|
||||
{
|
||||
int j, i = 0;
|
||||
|
||||
while (i < length) {
|
||||
if (ix[i].offset < 2 * LUKS2_HDR_16K_LEN) {
|
||||
if (ix[i].offset < 2 * metadata_size) {
|
||||
log_dbg("Illegal area offset: %" PRIu64 ".", ix[i].offset);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -378,10 +379,9 @@ static json_bool validate_intervals(int length, const struct interval *ix, uint6
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* first segment at offset 0 means we have detached header. Do not check then. */
|
||||
if (*data_offset && (ix[i].offset + ix[i].length) > *data_offset) {
|
||||
log_dbg("Area [%" PRIu64 ", %" PRIu64 "] intersects with segment starting at offset: %" PRIu64,
|
||||
ix[i].offset, ix[i].offset + ix[i].length, *data_offset);
|
||||
if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
|
||||
log_dbg("Area [%" PRIu64 ", %" PRIu64 "] overflows binary keyslots area (ends at offset: %" PRIu64 ").",
|
||||
ix[i].offset, ix[i].offset + ix[i].length, keyslots_area_end);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -402,7 +402,6 @@ static json_bool validate_intervals(int length, const struct interval *ix, uint6
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int hdr_validate_areas(json_object *hdr_jobj);
|
||||
int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key)
|
||||
{
|
||||
json_object *jobj_key_size;
|
||||
@@ -419,9 +418,6 @@ int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, cons
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (hdr_validate_areas(hdr_jobj))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -446,7 +442,7 @@ int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const c
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdr_validate_json_size(json_object *hdr_jobj)
|
||||
static int hdr_validate_json_size(json_object *hdr_jobj, uint64_t hdr_json_size)
|
||||
{
|
||||
json_object *jobj, *jobj1;
|
||||
const char *json;
|
||||
@@ -460,12 +456,22 @@ static int hdr_validate_json_size(json_object *hdr_jobj)
|
||||
json_area_size = json_object_get_uint64(jobj1);
|
||||
json_size = (uint64_t)strlen(json);
|
||||
|
||||
return json_size > json_area_size ? 1 : 0;
|
||||
if (hdr_json_size != json_area_size) {
|
||||
log_dbg("JSON area size doesn't match value in binary header.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json_size > json_area_size) {
|
||||
log_dbg("JSON doesn't fit in the designated area.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUKS2_check_json_size(const struct luks2_hdr *hdr)
|
||||
{
|
||||
return hdr_validate_json_size(hdr->jobj);
|
||||
return hdr_validate_json_size(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
|
||||
}
|
||||
|
||||
static int hdr_validate_keyslots(json_object *hdr_jobj)
|
||||
@@ -535,22 +541,14 @@ static int hdr_validate_crypt_segment(json_object *jobj, const char *key, json_o
|
||||
}
|
||||
|
||||
sector_size = json_object_get_uint32(jobj_sector_size);
|
||||
if (!sector_size || sector_size % SECTOR_SIZE) {
|
||||
if (!sector_size || MISALIGNED_512(sector_size)) {
|
||||
log_dbg("Illegal sector size: %" PRIu32, sector_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!numbered("iv_tweak", json_object_get_string(jobj_ivoffset)) ||
|
||||
!json_str_to_uint64(jobj_ivoffset, &ivoffset))
|
||||
return 1;
|
||||
|
||||
if (offset % sector_size) {
|
||||
log_dbg("Offset field has to be aligned to sector size: %" PRIu32, sector_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ivoffset % sector_size) {
|
||||
log_dbg("IV offset field has to be aligned to sector size: %" PRIu32, sector_size);
|
||||
!json_str_to_uint64(jobj_ivoffset, &ivoffset)) {
|
||||
log_dbg("Illegal iv_tweak value.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -564,7 +562,8 @@ static int hdr_validate_crypt_segment(json_object *jobj, const char *key, json_o
|
||||
|
||||
static int hdr_validate_segments(json_object *hdr_jobj)
|
||||
{
|
||||
json_object *jobj, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type;
|
||||
json_object *jobj, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags;
|
||||
int i;
|
||||
uint64_t offset, size;
|
||||
|
||||
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj)) {
|
||||
@@ -604,15 +603,24 @@ static int hdr_validate_segments(json_object *hdr_jobj)
|
||||
size = 0;
|
||||
|
||||
/* all device-mapper devices are aligned to 512 sector size */
|
||||
if (offset % SECTOR_SIZE) {
|
||||
if (MISALIGNED_512(offset)) {
|
||||
log_dbg("Offset field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE);
|
||||
return 1;
|
||||
}
|
||||
if (size % SECTOR_SIZE) {
|
||||
if (MISALIGNED_512(size)) {
|
||||
log_dbg("Size field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags array is optional and must contain strings */
|
||||
if (json_object_object_get_ex(val, "flags", NULL)) {
|
||||
if (!(jobj_flags = json_contains(val, key, "Segment", "flags", json_type_array)))
|
||||
return 1;
|
||||
for (i = 0; i < (int) json_object_array_length(jobj_flags); i++)
|
||||
if (!json_object_is_type(json_object_array_get_idx(jobj_flags, i), json_type_string))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* crypt */
|
||||
if (!strcmp(json_object_get_string(jobj_type), "crypt") &&
|
||||
hdr_validate_crypt_segment(val, key, jobj_digests, offset, size))
|
||||
@@ -622,12 +630,24 @@ static int hdr_validate_segments(json_object *hdr_jobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t LUKS2_metadata_size(json_object *jobj)
|
||||
{
|
||||
json_object *jobj1, *jobj2;
|
||||
uint64_t json_size;
|
||||
|
||||
json_object_object_get_ex(jobj, "config", &jobj1);
|
||||
json_object_object_get_ex(jobj1, "json_size", &jobj2);
|
||||
json_str_to_uint64(jobj2, &json_size);
|
||||
|
||||
return json_size + LUKS2_HDR_BIN_LEN;
|
||||
}
|
||||
|
||||
static int hdr_validate_areas(json_object *hdr_jobj)
|
||||
{
|
||||
struct interval *intervals;
|
||||
json_object *jobj_keyslots, *jobj_offset, *jobj_length, *jobj_segments, *jobj_area;
|
||||
int length, ret, i = 0;
|
||||
uint64_t first_offset;
|
||||
uint64_t metadata_size;
|
||||
|
||||
if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
|
||||
return 1;
|
||||
@@ -636,6 +656,9 @@ static int hdr_validate_areas(json_object *hdr_jobj)
|
||||
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
|
||||
return 1;
|
||||
|
||||
/* config is already validated */
|
||||
metadata_size = LUKS2_metadata_size(hdr_jobj);
|
||||
|
||||
length = json_object_object_length(jobj_keyslots);
|
||||
|
||||
/* Empty section */
|
||||
@@ -679,9 +702,7 @@ static int hdr_validate_areas(json_object *hdr_jobj)
|
||||
return 1;
|
||||
}
|
||||
|
||||
first_offset = get_first_data_offset(jobj_segments, NULL);
|
||||
|
||||
ret = validate_intervals(length, intervals, &first_offset) ? 0 : 1;
|
||||
ret = validate_intervals(length, intervals, metadata_size, LUKS2_hdr_and_areas_size(hdr_jobj)) ? 0 : 1;
|
||||
|
||||
free(intervals);
|
||||
|
||||
@@ -723,56 +744,11 @@ static int hdr_validate_digests(json_object *hdr_jobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* requires keyslots and segments sections being already validated */
|
||||
static int validate_keyslots_size(json_object *hdr_jobj, json_object *jobj_keyslots_size)
|
||||
{
|
||||
json_object *jobj_keyslots, *jobj, *jobj1;
|
||||
uint64_t keyslots_size, segment_offset, keyslots_area_sum = 0;
|
||||
|
||||
if (!json_str_to_uint64(jobj_keyslots_size, &keyslots_size))
|
||||
return 1;
|
||||
|
||||
if (keyslots_size % 4096) {
|
||||
log_dbg("keyslots_size is not 4 KiB aligned");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE) {
|
||||
log_dbg("keyslots_size is too large. The cap is %" PRIu64 " bytes", (uint64_t) LUKS2_MAX_KEYSLOTS_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
json_object_object_get_ex(hdr_jobj, "segments", &jobj);
|
||||
segment_offset = get_first_data_offset(jobj, "crypt");
|
||||
if (segment_offset &&
|
||||
(segment_offset < keyslots_size ||
|
||||
(segment_offset - keyslots_size) < (2 * LUKS2_HDR_16K_LEN))) {
|
||||
log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64 ", keyslots offset: %d", keyslots_size, segment_offset, 2 * LUKS2_HDR_16K_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots);
|
||||
|
||||
json_object_object_foreach(jobj_keyslots, key, val) {
|
||||
UNUSED(key);
|
||||
json_object_object_get_ex(val, "area", &jobj);
|
||||
json_object_object_get_ex(jobj, "size", &jobj1);
|
||||
keyslots_area_sum += json_object_get_uint64(jobj1);
|
||||
}
|
||||
|
||||
if (keyslots_area_sum > keyslots_size) {
|
||||
log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %" PRIu64, keyslots_area_sum, keyslots_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdr_validate_config(json_object *hdr_jobj)
|
||||
{
|
||||
json_object *jobj_config, *jobj, *jobj1;
|
||||
int i;
|
||||
uint64_t json_size;
|
||||
uint64_t keyslots_size, metadata_size, segment_offset;
|
||||
|
||||
if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) {
|
||||
log_dbg("Missing config section.");
|
||||
@@ -780,25 +756,40 @@ static int hdr_validate_config(json_object *hdr_jobj)
|
||||
}
|
||||
|
||||
if (!(jobj = json_contains(jobj_config, "section", "Config", "json_size", json_type_string)) ||
|
||||
!json_str_to_uint64(jobj, &json_size))
|
||||
!json_str_to_uint64(jobj, &metadata_size))
|
||||
return 1;
|
||||
|
||||
/* currently it's hardcoded */
|
||||
if (json_size != (LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN)) {
|
||||
log_dbg("Invalid json_size %" PRIu64, json_size);
|
||||
/* single metadata instance is assembled from json area size plus
|
||||
* binary header size */
|
||||
metadata_size += LUKS2_HDR_BIN_LEN;
|
||||
|
||||
if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)) ||
|
||||
!json_str_to_uint64(jobj, &keyslots_size))
|
||||
return 1;
|
||||
|
||||
if (LUKS2_check_metadata_area_size(metadata_size)) {
|
||||
log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", metadata_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json_size % 4096) {
|
||||
log_dbg("Json area is not properly aligned to 4 KiB.");
|
||||
if (LUKS2_check_keyslots_area_size(keyslots_size)) {
|
||||
log_dbg("Unsupported LUKS2 keyslots size (%" PRIu64 ").", keyslots_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)))
|
||||
return 1;
|
||||
|
||||
if (validate_keyslots_size(hdr_jobj, jobj))
|
||||
/*
|
||||
* validate keyslots_size fits in between (2 * metadata_size) and first
|
||||
* segment_offset (except detached header)
|
||||
*/
|
||||
json_object_object_get_ex(hdr_jobj, "segments", &jobj);
|
||||
segment_offset = get_first_data_offset(jobj, "crypt");
|
||||
if (segment_offset &&
|
||||
(segment_offset < keyslots_size ||
|
||||
(segment_offset - keyslots_size) < (2 * metadata_size))) {
|
||||
log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64
|
||||
", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Flags array is optional */
|
||||
if (json_object_object_get_ex(jobj_config, "flags", &jobj)) {
|
||||
@@ -831,7 +822,7 @@ static int hdr_validate_config(json_object *hdr_jobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_validate(json_object *hdr_jobj)
|
||||
int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t json_size)
|
||||
{
|
||||
struct {
|
||||
int (*validate)(json_object *);
|
||||
@@ -840,8 +831,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
|
||||
{ hdr_validate_digests },
|
||||
{ hdr_validate_segments },
|
||||
{ hdr_validate_keyslots },
|
||||
{ hdr_validate_areas },
|
||||
{ hdr_validate_config },
|
||||
{ hdr_validate_areas },
|
||||
{ NULL }
|
||||
};
|
||||
int i;
|
||||
@@ -853,10 +844,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
|
||||
if (checks[i].validate && checks[i].validate(hdr_jobj))
|
||||
return 1;
|
||||
|
||||
if (hdr_validate_json_size(hdr_jobj)) {
|
||||
log_dbg("Json header is too large.");
|
||||
if (hdr_validate_json_size(hdr_jobj, json_size))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* validate keyslot implementations */
|
||||
if (LUKS2_keyslots_validate(hdr_jobj))
|
||||
@@ -904,7 +893,7 @@ int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(hdr->jobj))
|
||||
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd));
|
||||
@@ -964,14 +953,7 @@ uint64_t LUKS2_keyslots_size(json_object *jobj)
|
||||
|
||||
uint64_t LUKS2_hdr_and_areas_size(json_object *jobj)
|
||||
{
|
||||
json_object *jobj1, *jobj2;
|
||||
uint64_t json_size;
|
||||
|
||||
json_object_object_get_ex(jobj, "config", &jobj1);
|
||||
json_object_object_get_ex(jobj1, "json_size", &jobj2);
|
||||
json_str_to_uint64(jobj2, &json_size);
|
||||
|
||||
return 2 * (json_size + LUKS2_HDR_BIN_LEN) + LUKS2_keyslots_size(jobj);
|
||||
return 2 * LUKS2_metadata_size(jobj) + LUKS2_keyslots_size(jobj);
|
||||
}
|
||||
|
||||
int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
@@ -1189,20 +1171,19 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
/* end of TODO */
|
||||
|
||||
out:
|
||||
LUKS2_hdr_free(hdr);
|
||||
LUKS2_hdr_free(&hdr_file);
|
||||
LUKS2_hdr_free(&tmp_hdr);
|
||||
crypt_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_free(buffer);
|
||||
|
||||
if (devfd >= 0)
|
||||
if (devfd >= 0) {
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
|
||||
if (!r) {
|
||||
LUKS2_hdr_free(hdr);
|
||||
r = LUKS2_hdr_read(cd, hdr, 1);
|
||||
}
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1265,9 +1246,11 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3
|
||||
jobj_flags = json_object_new_array();
|
||||
|
||||
for (i = 0; persistent_flags[i].description; i++) {
|
||||
if (flags & persistent_flags[i].flag)
|
||||
if (flags & persistent_flags[i].flag) {
|
||||
log_dbg("Setting persistent flag: %s.", persistent_flags[i].description);
|
||||
json_object_array_add(jobj_flags,
|
||||
json_object_new_string(persistent_flags[i].description));
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace or add new flags array */
|
||||
@@ -1539,40 +1522,56 @@ static void hdr_dump_tokens(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: sort segments when more segments available later */
|
||||
static void hdr_dump_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
{
|
||||
json_object *jobj1, *jobj2, *jobj3;
|
||||
char segment[16];
|
||||
json_object *jobj_segments, *jobj_segment, *jobj1, *jobj2;
|
||||
int i, j, flags;
|
||||
uint64_t value;
|
||||
|
||||
log_std(cd, "Data segments:\n");
|
||||
json_object_object_get_ex(hdr_jobj, "segments", &jobj1);
|
||||
json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments);
|
||||
|
||||
json_object_object_foreach(jobj1, key, val) {
|
||||
json_object_object_get_ex(val, "type", &jobj2);
|
||||
log_std(cd, " %s: %s\n", key, json_object_get_string(jobj2));
|
||||
for (i = 0; i < LUKS2_SEGMENT_MAX; i++) {
|
||||
(void) snprintf(segment, sizeof(segment), "%i", i);
|
||||
if (!json_object_object_get_ex(jobj_segments, segment, &jobj_segment))
|
||||
continue;
|
||||
|
||||
json_object_object_get_ex(val, "offset", &jobj3);
|
||||
json_str_to_uint64(jobj3, &value);
|
||||
json_object_object_get_ex(jobj_segment, "type", &jobj1);
|
||||
log_std(cd, " %s: %s\n", segment, json_object_get_string(jobj1));
|
||||
|
||||
json_object_object_get_ex(jobj_segment, "offset", &jobj1);
|
||||
json_str_to_uint64(jobj1, &value);
|
||||
log_std(cd, "\toffset: %" PRIu64 " [bytes]\n", value);
|
||||
|
||||
json_object_object_get_ex(val, "size", &jobj3);
|
||||
if (!(strcmp(json_object_get_string(jobj3), "dynamic")))
|
||||
json_object_object_get_ex(jobj_segment, "size", &jobj1);
|
||||
if (!(strcmp(json_object_get_string(jobj1), "dynamic")))
|
||||
log_std(cd, "\tlength: (whole device)\n");
|
||||
else {
|
||||
json_str_to_uint64(jobj3, &value);
|
||||
json_str_to_uint64(jobj1, &value);
|
||||
log_std(cd, "\tlength: %" PRIu64 " [bytes]\n", value);
|
||||
}
|
||||
|
||||
if (json_object_object_get_ex(val, "encryption", &jobj3))
|
||||
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj3));
|
||||
if (json_object_object_get_ex(jobj_segment, "encryption", &jobj1))
|
||||
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj1));
|
||||
|
||||
if (json_object_object_get_ex(val, "sector_size", &jobj3))
|
||||
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj3));
|
||||
if (json_object_object_get_ex(jobj_segment, "sector_size", &jobj1))
|
||||
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj1));
|
||||
|
||||
if (json_object_object_get_ex(val, "integrity", &jobj2) &&
|
||||
json_object_object_get_ex(jobj2, "type", &jobj3))
|
||||
log_std(cd, "\tintegrity: %s\n", json_object_get_string(jobj3));
|
||||
if (json_object_object_get_ex(jobj_segment, "integrity", &jobj1) &&
|
||||
json_object_object_get_ex(jobj1, "type", &jobj2))
|
||||
log_std(cd, "\tintegrity: %s\n", json_object_get_string(jobj2));
|
||||
|
||||
if (json_object_object_get_ex(jobj_segment, "flags", &jobj1) &&
|
||||
(flags = (int)json_object_array_length(jobj1)) > 0) {
|
||||
jobj2 = json_object_array_get_idx(jobj1, 0);
|
||||
log_std(cd, "\tflags : %s", json_object_get_string(jobj2));
|
||||
for (j = 1; j < flags; j++) {
|
||||
jobj2 = json_object_array_get_idx(jobj1, j);
|
||||
log_std(cd, ", %s", json_object_get_string(jobj2));
|
||||
}
|
||||
log_std(cd, "\n");
|
||||
}
|
||||
|
||||
log_std(cd, "\n");
|
||||
}
|
||||
@@ -1898,7 +1897,7 @@ int LUKS2_activate(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
snprintf(dm_int_name, sizeof(dm_int_name), "%s_dif", name);
|
||||
r = INTEGRITY_activate(cd, dm_int_name, NULL, NULL, NULL, NULL, flags);
|
||||
r = INTEGRITY_activate(cd, dm_int_name, NULL, NULL, NULL, NULL, dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -114,13 +114,18 @@ int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
|
||||
int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd)
|
||||
{
|
||||
const char *cipher = crypt_get_cipher(cd);
|
||||
const char *cipher_mode = crypt_get_cipher_mode(cd);
|
||||
|
||||
/* Keyslot is already authenticated; we cannot use integrity tags here */
|
||||
if (crypt_get_integrity_tag_size(cd) || !cipher)
|
||||
return 1;
|
||||
|
||||
/* Wrapped key schemes cannot be used for keyslot encryption */
|
||||
if (crypt_cipher_wrapped_key(cipher))
|
||||
if (crypt_cipher_wrapped_key(cipher, cipher_mode))
|
||||
return 1;
|
||||
|
||||
/* Check if crypto backend can use the cipher */
|
||||
if (crypt_cipher_ivsize(cipher, cipher_mode) < 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -48,7 +48,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
|
||||
int devfd = -1, r;
|
||||
|
||||
/* Only whole sector writes supported */
|
||||
if (srcLength % SECTOR_SIZE)
|
||||
if (MISALIGNED_512(srcLength))
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
@@ -79,6 +79,8 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
|
||||
r = -EIO;
|
||||
else
|
||||
r = 0;
|
||||
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
} else
|
||||
r = -EIO;
|
||||
@@ -111,7 +113,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
int devfd = -1, r;
|
||||
|
||||
/* Only whole sector writes supported */
|
||||
if (dstLength % SECTOR_SIZE)
|
||||
if (MISALIGNED_512(dstLength))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
|
||||
@@ -461,6 +461,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
crypt_memzero(buf, buf_size);
|
||||
free(buf);
|
||||
@@ -644,7 +645,7 @@ static int keyslot_LUKS1_compatible(struct luks2_hdr *hdr, int keyslot, uint32_t
|
||||
int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct luks_phdr *hdr1)
|
||||
{
|
||||
size_t buf_size, buf_offset;
|
||||
char cipher[LUKS_CIPHERNAME_L], cipher_mode[LUKS_CIPHERMODE_L];
|
||||
char cipher[LUKS_CIPHERNAME_L-1], cipher_mode[LUKS_CIPHERMODE_L-1];
|
||||
char digest[LUKS_DIGESTSIZE], digest_salt[LUKS_SALTSIZE];
|
||||
size_t len;
|
||||
json_object *jobj_keyslot, *jobj_digest, *jobj_segment, *jobj_kdf, *jobj_area, *jobj1, *jobj2;
|
||||
@@ -673,7 +674,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (crypt_cipher_wrapped_key(cipher)) {
|
||||
if (crypt_cipher_wrapped_key(cipher, cipher_mode)) {
|
||||
log_err(cd, _("Cannot convert to LUKS1 format - device uses wrapped key cipher %s."), cipher);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -828,7 +829,8 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
/* FIXME: LUKS1 requires offset == 0 || offset >= luks1_hdr_size */
|
||||
hdr1->payloadOffset = offset;
|
||||
|
||||
strncpy(hdr1->uuid, hdr2->uuid, UUID_STRING_L - 1); /* max 36 chars */
|
||||
strncpy(hdr1->uuid, hdr2->uuid, UUID_STRING_L); /* max 36 chars */
|
||||
hdr1->uuid[UUID_STRING_L-1] = '\0';
|
||||
|
||||
memcpy(hdr1->magic, luksMagic, LUKS_MAGIC_L);
|
||||
|
||||
|
||||
152
lib/setup.c
152
lib/setup.c
@@ -182,6 +182,11 @@ static const char *mdata_device_path(struct crypt_device *cd)
|
||||
return device_path(cd->metadata_device ?: cd->device);
|
||||
}
|
||||
|
||||
static const char *data_device_path(struct crypt_device *cd)
|
||||
{
|
||||
return device_path(cd->device);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
struct device *crypt_metadata_device(struct crypt_device *cd)
|
||||
{
|
||||
@@ -777,8 +782,11 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
* perform repair.
|
||||
*/
|
||||
r = _crypt_load_luks2(cd, cd->type != NULL, repair);
|
||||
} else
|
||||
} else {
|
||||
if (version > 2)
|
||||
log_err(cd, _("Unsupported LUKS version %d."), version);
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
|
||||
@@ -1340,6 +1348,7 @@ static int _crypt_format_plain(struct crypt_device *cd,
|
||||
struct crypt_params_plain *params)
|
||||
{
|
||||
unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE;
|
||||
uint64_t dev_size;
|
||||
|
||||
if (!cipher || !cipher_mode) {
|
||||
log_err(cd, _("Invalid plain crypt parameters."));
|
||||
@@ -1361,11 +1370,20 @@ static int _crypt_format_plain(struct crypt_device *cd,
|
||||
sector_size = SECTOR_SIZE;
|
||||
|
||||
if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE ||
|
||||
(sector_size & (sector_size - 1))) {
|
||||
NOTPOW2(sector_size)) {
|
||||
log_err(cd, _("Unsupported encryption sector size."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sector_size > SECTOR_SIZE && !device_size(cd->device, &dev_size)) {
|
||||
if (params && params->offset)
|
||||
dev_size -= (params->offset * SECTOR_SIZE);
|
||||
if (dev_size % sector_size) {
|
||||
log_err(cd, _("Device size is not aligned to requested sector size."));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cd->type = strdup(CRYPT_PLAIN)))
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1466,9 +1484,7 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Wipe first 8 sectors - fs magic numbers etc. */
|
||||
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO, 0,
|
||||
8 * SECTOR_SIZE, 8 * SECTOR_SIZE, NULL, NULL);
|
||||
r = LUKS_wipe_header_areas(&cd->u.luks1.hdr, cd);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Cannot wipe header on device %s."),
|
||||
mdata_device_path(cd));
|
||||
@@ -1493,6 +1509,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
unsigned long alignment_offset = 0;
|
||||
unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE;
|
||||
const char *integrity = params ? params->integrity : NULL;
|
||||
uint64_t dev_size;
|
||||
|
||||
cd->u.luks2.hdr.jobj = NULL;
|
||||
|
||||
@@ -1505,7 +1522,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE ||
|
||||
(sector_size & (sector_size - 1))) {
|
||||
NOTPOW2(sector_size)) {
|
||||
log_err(cd, _("Unsupported encryption sector size."));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1535,12 +1552,8 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
r = device_check_access(cd, crypt_metadata_device(cd), DEV_EXCL);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Cannot use device %s which is in use "
|
||||
"(already mapped or mounted)."),
|
||||
device_path(crypt_metadata_device(cd)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!(cd->type = strdup(CRYPT_LUKS2)))
|
||||
return -ENOMEM;
|
||||
@@ -1567,9 +1580,9 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
cd->device = NULL;
|
||||
if (device_alloc(&cd->device, params->data_device) < 0)
|
||||
return -ENOMEM;
|
||||
required_alignment = params->data_alignment * sector_size;
|
||||
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||
} else if (params && params->data_alignment) {
|
||||
required_alignment = params->data_alignment * sector_size;
|
||||
required_alignment = params->data_alignment * SECTOR_SIZE;
|
||||
} else
|
||||
device_topology_alignment(cd->device,
|
||||
&required_alignment,
|
||||
@@ -1583,8 +1596,16 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* FIXME: we have no way how to check AEAD ciphers,
|
||||
* only length preserving mode or authenc() composed modes */
|
||||
/* FIXME: allow this later also for normal ciphers (check AF_ALG availability. */
|
||||
if (integrity && !integrity_key_size) {
|
||||
r = crypt_cipher_check(cipher, cipher_mode, integrity, volume_key_size);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Cipher %s-%s (key size %zd bits) is not available."),
|
||||
cipher, cipher_mode, volume_key_size * 8);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!integrity || integrity_key_size) && !LUKS2_keyslot_cipher_incompatible(cd)) {
|
||||
r = LUKS_check_cipher(cd, volume_key_size - integrity_key_size,
|
||||
cipher, cipher_mode);
|
||||
@@ -1596,12 +1617,21 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
cipher, cipher_mode,
|
||||
integrity, uuid,
|
||||
sector_size,
|
||||
required_alignment / sector_size,
|
||||
alignment_offset / sector_size,
|
||||
required_alignment,
|
||||
alignment_offset,
|
||||
cd->metadata_device ? 1 : 0);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
if (!integrity && sector_size > SECTOR_SIZE && !device_size(crypt_data_device(cd), &dev_size)) {
|
||||
dev_size -= (crypt_get_data_offset(cd) * SECTOR_SIZE);
|
||||
if (dev_size % sector_size) {
|
||||
log_err(cd, _("Device size is not aligned to requested sector size."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (params && (params->label || params->subsystem)) {
|
||||
r = LUKS2_hdr_labels(cd, &cd->u.luks2.hdr,
|
||||
params->label, params->subsystem, 0);
|
||||
@@ -1609,41 +1639,37 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Cannot wipe header on device %s."),
|
||||
mdata_device_path(cd));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wipe integrity superblock and create integrity superblock */
|
||||
if (crypt_get_integrity_tag_size(cd)) {
|
||||
/* FIXME: this should be locked. */
|
||||
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
|
||||
r = crypt_wipe_device(cd, crypt_data_device(cd), CRYPT_WIPE_ZERO,
|
||||
crypt_get_data_offset(cd) * SECTOR_SIZE,
|
||||
8 * SECTOR_SIZE, 8 * SECTOR_SIZE, NULL, NULL);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Cannot format device %s which is still in use."),
|
||||
mdata_device_path(cd));
|
||||
data_device_path(cd));
|
||||
else if (r == -EACCES) {
|
||||
log_err(cd, _("Cannot format device %s, permission denied."),
|
||||
mdata_device_path(cd));
|
||||
data_device_path(cd));
|
||||
r = -EINVAL;
|
||||
} else
|
||||
log_err(cd, _("Cannot wipe header on device %s."),
|
||||
mdata_device_path(cd));
|
||||
data_device_path(cd));
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = device_write_lock(cd, crypt_metadata_device(cd));
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to acquire write lock on device %s."),
|
||||
mdata_device_path(cd));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = INTEGRITY_format(cd, params ? params->integrity_params : NULL, NULL, NULL);
|
||||
if (r)
|
||||
log_err(cd, _("Cannot format integrity for device %s."),
|
||||
mdata_device_path(cd));
|
||||
|
||||
device_write_unlock(crypt_metadata_device(cd));
|
||||
data_device_path(cd));
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
@@ -1740,12 +1766,12 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->hash_area_offset % 512) {
|
||||
if (MISALIGNED_512(params->hash_area_offset)) {
|
||||
log_err(cd, _("Unsupported VERITY hash offset."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->fec_area_offset % 512) {
|
||||
if (MISALIGNED_512(params->fec_area_offset)) {
|
||||
log_err(cd, _("Unsupported VERITY FEC offset."));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2112,7 +2138,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
if (new_size & ((dmd.u.crypt.sector_size >> SECTOR_SHIFT) - 1)) {
|
||||
if (MISALIGNED(new_size, dmd.u.crypt.sector_size >> SECTOR_SHIFT)) {
|
||||
log_err(cd, _("Device %s size is not aligned to requested sector size (%u bytes)."),
|
||||
crypt_get_device_name(cd), (unsigned)dmd.u.crypt.sector_size);
|
||||
r = -EINVAL;
|
||||
@@ -2255,17 +2281,20 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
else
|
||||
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
|
||||
|
||||
LUKS2_hdr_free(&hdr2);
|
||||
crypt_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
} else if (isLUKS2(cd->type) && (!requested_type || isLUKS2(requested_type))) {
|
||||
r = LUKS2_hdr_restore(cd, &cd->u.luks2.hdr, backup_file);
|
||||
/* FIXME: if (r != 0) context may be lost */
|
||||
} else if (isLUKS1(cd->type) && (!requested_type || isLUKS1(requested_type))) {
|
||||
if (r)
|
||||
_luks2_reload(cd);
|
||||
} else if (isLUKS1(cd->type) && (!requested_type || isLUKS1(requested_type)))
|
||||
r = LUKS_hdr_restore(backup_file, &cd->u.luks1.hdr, cd);
|
||||
} else
|
||||
else
|
||||
r = -EINVAL;
|
||||
|
||||
if (!r)
|
||||
r = _crypt_load_luks(cd, version == 1 ? CRYPT_LUKS1 : CRYPT_LUKS2, 1, 1);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2359,7 +2388,7 @@ int crypt_suspend(struct crypt_device *cd,
|
||||
key_desc = crypt_get_device_key_description(name);
|
||||
|
||||
/* we can't simply wipe wrapped keys */
|
||||
if (crypt_cipher_wrapped_key(crypt_get_cipher(cd)))
|
||||
if (crypt_cipher_wrapped_key(crypt_get_cipher(cd), crypt_get_cipher_mode(cd)))
|
||||
r = dm_suspend_device(cd, name);
|
||||
else
|
||||
r = dm_suspend_and_wipe_key(cd, name);
|
||||
@@ -2907,6 +2936,23 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot)
|
||||
return LUKS2_keyslot_wipe(cd, &cd->u.luks2.hdr, keyslot, 0);
|
||||
}
|
||||
|
||||
static int _check_header_data_overlap(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
if (!name || !isLUKS(cd->type))
|
||||
return 0;
|
||||
|
||||
if (!device_is_identical(crypt_data_device(cd), crypt_metadata_device(cd)))
|
||||
return 0;
|
||||
|
||||
/* FIXME: check real header size */
|
||||
if (crypt_get_data_offset(cd) == 0) {
|
||||
log_err(cd, _("Device header overlaps with data area."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Activation/deactivation of a device
|
||||
*/
|
||||
@@ -2926,6 +2972,10 @@ static int _activate_by_passphrase(struct crypt_device *cd,
|
||||
if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
|
||||
return -EINVAL;
|
||||
|
||||
r = _check_header_data_overlap(cd, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* plain, use hashed passphrase */
|
||||
if (isPLAIN(cd->type)) {
|
||||
if (!name)
|
||||
@@ -3126,6 +3176,10 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = _check_header_data_overlap(cd, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* use key directly, no hash */
|
||||
if (isPLAIN(cd->type)) {
|
||||
if (!name)
|
||||
@@ -3322,13 +3376,14 @@ int crypt_deactivate(struct crypt_device *cd, const char *name)
|
||||
int crypt_get_active_device(struct crypt_device *cd, const char *name,
|
||||
struct crypt_active_device *cad)
|
||||
{
|
||||
struct crypt_dm_active_device dmd;
|
||||
struct crypt_dm_active_device dmd = {}, dmdi = {};
|
||||
const char *namei = NULL;
|
||||
int r;
|
||||
|
||||
if (!cd || !name || !cad)
|
||||
return -EINVAL;
|
||||
|
||||
r = dm_query_device(cd, name, 0, &dmd);
|
||||
r = dm_query_device(cd, name, DM_ACTIVE_DEVICE, &dmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -3337,6 +3392,14 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name,
|
||||
dmd.target != DM_INTEGRITY)
|
||||
return -ENOTSUP;
|
||||
|
||||
/* For LUKS2 with integrity we need flags from underlying dm-integrity */
|
||||
if (isLUKS2(cd->type) && crypt_get_integrity_tag_size(cd)) {
|
||||
namei = device_dm_name(dmd.data_device);
|
||||
if (namei && dm_query_device(cd, namei, 0, &dmdi) >= 0)
|
||||
dmd.flags |= dmdi.flags;
|
||||
}
|
||||
device_free(dmd.data_device);
|
||||
|
||||
if (cd && isTCRYPT(cd->type)) {
|
||||
cad->offset = TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
cad->iv_offset = TCRYPT_get_iv_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
@@ -3386,7 +3449,8 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
|
||||
/* wrapped keys or unbound keys may be exported */
|
||||
if (crypt_fips_mode() && !crypt_cipher_wrapped_key(crypt_get_cipher(cd))) {
|
||||
if (crypt_fips_mode() &&
|
||||
!crypt_cipher_wrapped_key(crypt_get_cipher(cd), crypt_get_cipher_mode(cd))) {
|
||||
if (!isLUKS2(cd->type) || keyslot == CRYPT_ANY_SLOT ||
|
||||
!LUKS2_keyslot_for_segment(&cd->u.luks2.hdr, keyslot, CRYPT_DEFAULT_SEGMENT)) {
|
||||
log_err(cd, _("Function not available in FIPS mode."));
|
||||
|
||||
@@ -51,6 +51,8 @@ static const struct {
|
||||
{ 0, 1, "pbkdf2", "sha256", 200000, 0, 2048 }, // boot only
|
||||
{ 0, 1, "pbkdf2", "ripemd160", 655331, 15000, 1000 },
|
||||
{ 0, 1, "pbkdf2", "ripemd160", 327661, 0, 2048 }, // boot only
|
||||
{ 0, 1, "pbkdf2", "stribog512",500000, 15000, 1000 },
|
||||
// { 0, 1, "pbkdf2", "stribog512",200000, 0, 2048 }, // boot only
|
||||
{ 0, 0, NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -98,6 +100,26 @@ static struct tcrypt_algs tcrypt_cipher[] = {
|
||||
{0,2,128,"serpent-twofish","xts-plain64",
|
||||
{{"serpent",64,16, 0,64,0},
|
||||
{"twofish",64,16,32,96,0}}},
|
||||
{0,1,64,"camellia","xts-plain64",
|
||||
{{"camellia", 64,16,0,32,0}}},
|
||||
{0,1,64,"kuznyechik","xts-plain64",
|
||||
{{"kuznyechik", 64,16,0,32,0}}},
|
||||
{0,2,128,"kuznyechik-camellia","xts-plain64",
|
||||
{{"kuznyechik",64,16, 0,64,0},
|
||||
{"camellia", 64,16,32,96,0}}},
|
||||
{0,2,128,"twofish-kuznyechik","xts-plain64",
|
||||
{{"twofish", 64,16, 0,64,0},
|
||||
{"kuznyechik",64,16,32,96,0}}},
|
||||
{0,2,128,"serpent-camellia","xts-plain64",
|
||||
{{"serpent", 64,16, 0,64,0},
|
||||
{"camellia", 64,16,32,96,0}}},
|
||||
{0,2,128,"aes-kuznyechik","xts-plain64",
|
||||
{{"aes", 64,16, 0,64,0},
|
||||
{"kuznyechik",64,16,32,96,0}}},
|
||||
{0,3,192,"camellia-serpent-kuznyechik","xts-plain64",
|
||||
{{"camellia", 64,16, 0, 96,0},
|
||||
{"serpent", 64,16,32,128,0},
|
||||
{"kuznyechik",64,16,64,160,0}}},
|
||||
|
||||
/* LRW mode */
|
||||
{0,1,48,"aes","lrw-benbi",
|
||||
|
||||
@@ -155,10 +155,14 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
|
||||
*/
|
||||
void crypt_memzero(void *s, size_t n)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
|
||||
while(n--)
|
||||
*p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
|
||||
@@ -190,6 +190,12 @@ static int device_ready(struct device *device)
|
||||
r = -EINVAL;
|
||||
else if (!S_ISBLK(st.st_mode))
|
||||
r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
|
||||
if (r == -EINVAL) {
|
||||
log_err(NULL, _("Device %s is not compatible."),
|
||||
device_path(device));
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Allow only increase (loop device) */
|
||||
tmp_size = device_alignment_fd(devfd);
|
||||
@@ -229,6 +235,16 @@ static int _open_locked(struct device *device, int flags)
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common wrapper for device sync.
|
||||
* FIXME: file descriptor will be in struct later.
|
||||
*/
|
||||
void device_sync(struct device *device, int devfd)
|
||||
{
|
||||
if (fsync(devfd) == -1)
|
||||
log_dbg("Cannot sync device %s.", device_path(device));
|
||||
}
|
||||
|
||||
/*
|
||||
* in non-locked mode returns always fd or -1
|
||||
*
|
||||
@@ -242,7 +258,6 @@ static int device_open_internal(struct device *device, int flags)
|
||||
{
|
||||
int devfd;
|
||||
|
||||
flags |= O_SYNC;
|
||||
if (device->o_direct)
|
||||
flags |= O_DIRECT;
|
||||
|
||||
@@ -561,7 +576,7 @@ static int device_info(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
r = -EINVAL;
|
||||
r = errno ? -errno : -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -597,13 +612,14 @@ out:
|
||||
break;
|
||||
case -EBUSY:
|
||||
log_err(cd, _("Cannot use device %s which is in use "
|
||||
"(already mapped or mounted)."), device->path);
|
||||
"(already mapped or mounted)."), device_path(device));
|
||||
break;
|
||||
case -EACCES:
|
||||
log_err(cd, _("Cannot use device %s, permission denied."), device->path);
|
||||
log_err(cd, _("Cannot use device %s, permission denied."), device_path(device));
|
||||
break;
|
||||
default:
|
||||
log_err(cd, _("Cannot get info about device %s."), device->path);
|
||||
log_err(cd, _("Cannot get info about device %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -682,14 +698,14 @@ int device_block_adjust(struct crypt_device *cd,
|
||||
|
||||
if (device_offset >= real_size) {
|
||||
log_err(cd, _("Requested offset is beyond real size of device %s."),
|
||||
device->path);
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size && !*size) {
|
||||
*size = real_size;
|
||||
if (!*size) {
|
||||
log_err(cd, _("Device %s has zero size."), device->path);
|
||||
log_err(cd, _("Device %s has zero size."), device_path(device));
|
||||
return -ENOTBLK;
|
||||
}
|
||||
*size -= device_offset;
|
||||
@@ -700,7 +716,7 @@ int device_block_adjust(struct crypt_device *cd,
|
||||
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
|
||||
", backing device size = %" PRIu64,
|
||||
device->path, device_offset, *size, real_size);
|
||||
log_err(cd, _("Device %s is too small."), device->path);
|
||||
log_err(cd, _("Device %s is too small."), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,6 @@ struct crypt_dm_active_device {
|
||||
struct {
|
||||
const char *cipher;
|
||||
const char *integrity;
|
||||
char *key_description;
|
||||
|
||||
/* Active key for device */
|
||||
struct volume_key *vk;
|
||||
|
||||
@@ -184,7 +184,8 @@ ssize_t read_blockwise(int fd, size_t bsize, size_t alignment,
|
||||
out:
|
||||
free(hangover_buf);
|
||||
if (buf != orig_buf) {
|
||||
memcpy(orig_buf, buf, length);
|
||||
if (ret != -1)
|
||||
memcpy(orig_buf, buf, length);
|
||||
free(buf);
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -133,7 +133,8 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
|
||||
if (ret < 0) {
|
||||
err = errno;
|
||||
crypt_memzero(buf, len);
|
||||
if (buf)
|
||||
crypt_memzero(buf, len);
|
||||
free(buf);
|
||||
return -err;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,11 @@ int verify_pbkdf_params(struct crypt_device *cd,
|
||||
{
|
||||
struct crypt_pbkdf_limits pbkdf_limits;
|
||||
const char *pbkdf_type;
|
||||
int r = 0;
|
||||
int r;
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!pbkdf->type ||
|
||||
(!pbkdf->hash && !strcmp(pbkdf->type, "pbkdf2")))
|
||||
@@ -74,13 +78,17 @@ int verify_pbkdf_params(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: initialise crypto and check the hash and pbkdf are both available */
|
||||
r = crypt_parse_pbkdf(pbkdf->type, &pbkdf_type);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Unknown PBKDF type %s."), pbkdf->type);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (pbkdf->hash && crypt_hash_size(pbkdf->hash) < 0) {
|
||||
log_err(cd, _("Requested hash %s is not supported."), pbkdf->hash);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = crypt_pbkdf_get_limits(pbkdf->type, &pbkdf_limits);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -161,11 +169,6 @@ int init_pbkdf_type(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/*
|
||||
* Crypto backend may be not initialized here,
|
||||
* cannot check if algorithms are really available.
|
||||
* It will fail later anyway :-)
|
||||
*/
|
||||
type = strdup(pbkdf->type);
|
||||
hash = pbkdf->hash ? strdup(pbkdf->hash) : NULL;
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ int crypt_wipe_device(struct crypt_device *cd,
|
||||
/* FIXME: if wipe_block_size < bsize, then a wipe is highly ineffective */
|
||||
|
||||
/* Everything must be aligned to SECTOR_SIZE */
|
||||
if ((offset % SECTOR_SIZE) || (length % SECTOR_SIZE) || (wipe_block_size % SECTOR_SIZE))
|
||||
if (MISALIGNED_512(offset) || MISALIGNED_512(length) || MISALIGNED_512(wipe_block_size))
|
||||
return -EINVAL;
|
||||
|
||||
devfd = device_open(device, O_RDWR);
|
||||
@@ -161,9 +161,12 @@ int crypt_wipe_device(struct crypt_device *cd,
|
||||
return errno ? -errno : -EINVAL;
|
||||
|
||||
r = device_size(device, &dev_size);
|
||||
if (r)
|
||||
if (r || dev_size == 0)
|
||||
goto out;
|
||||
|
||||
if (dev_size < length)
|
||||
length = 0;
|
||||
|
||||
if (length) {
|
||||
if ((dev_size <= offset) || (dev_size - offset) < length) {
|
||||
r = -EINVAL;
|
||||
@@ -213,7 +216,7 @@ int crypt_wipe_device(struct crypt_device *cd,
|
||||
}
|
||||
}
|
||||
|
||||
fsync(devfd);
|
||||
device_sync(device, devfd);
|
||||
out:
|
||||
close(devfd);
|
||||
free(sf);
|
||||
|
||||
@@ -71,7 +71,7 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sb_offset % 512) {
|
||||
if (MISALIGNED_512(sb_offset)) {
|
||||
log_err(cd, _("Unsupported VERITY hash offset."));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -201,6 +201,8 @@ int VERITY_write_sb(struct crypt_device *cd,
|
||||
if (r)
|
||||
log_err(cd, _("Error during update of verity header on device %s."),
|
||||
device_path(device));
|
||||
|
||||
device_sync(device, devfd);
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
|
||||
@@ -487,10 +487,15 @@ to standard output.
|
||||
.PP
|
||||
\fIconvert\fR <device> \-\-type <format>
|
||||
.IP
|
||||
Converts the device between LUKS and LUKS2 format (if possible).
|
||||
The conversion will not be performed if there is an additional LUKS2 feature or LUKS has
|
||||
Converts the device between LUKS1 and LUKS2 format (if possible).
|
||||
The conversion will not be performed if there is an additional LUKS2 feature or LUKS1 has
|
||||
unsupported header size.
|
||||
|
||||
Conversion (both directions) must be performed on inactive device. There must not be active
|
||||
dm-crypt mapping established for LUKS header requested for conversion.
|
||||
|
||||
\fB\-\-type\fR option is mandatory with following accepted values: \fIluks1\fR or \fIluks2\fR.
|
||||
|
||||
\fBWARNING:\fR The \fIconvert\fR action can destroy the LUKS header in the case of a crash
|
||||
during conversion or if a media error occurs.
|
||||
Always create a header backup before performing this operation!
|
||||
@@ -1171,6 +1176,9 @@ Specify integrity algorithm to be used for authenticated disk encryption in LUKS
|
||||
|
||||
\fBWARNING: This extension is EXPERIMENTAL\fR and requires dm-integrity
|
||||
kernel target (available since kernel version 4.12).
|
||||
For native AEAD modes, also enable "User-space interface for AEAD cipher algorithms"
|
||||
in "Cryptographic API" section (CONFIG_CRYPTO_USER_API_AEAD .config option).
|
||||
|
||||
For more info, see \fIAUTHENTICATED DISK ENCRYPTION\fR section.
|
||||
.TP
|
||||
.B "\-\-integrity\-no\-journal"
|
||||
|
||||
@@ -14,6 +14,8 @@ lib/utils_benchmark.c
|
||||
lib/utils_device_locking.c
|
||||
lib/utils_wipe.c
|
||||
lib/utils_keyring.c
|
||||
lib/utils_blkid.c
|
||||
lib/utils_io.c
|
||||
lib/luks1/af.c
|
||||
lib/luks1/keyencryption.c
|
||||
lib/luks1/keymanage.c
|
||||
@@ -39,3 +41,4 @@ src/integritysetup.c
|
||||
src/cryptsetup_reencrypt.c
|
||||
src/utils_tools.c
|
||||
src/utils_password.c
|
||||
src/utils_luks2.c
|
||||
|
||||
1254
po/pt_BR.po
1254
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -1,30 +1,24 @@
|
||||
noinst_LTLIBRARIES += libutils_tools.la
|
||||
|
||||
libutils_tools_la_SOURCES = \
|
||||
src/utils_tools.c \
|
||||
src/utils_password.c \
|
||||
lib/utils_io.c \
|
||||
lib/utils_blkid.c \
|
||||
src/cryptsetup.h
|
||||
|
||||
libutils_tools_la_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
libutils_tools_la_LIBADD = -lm @BLKID_LIBS@ @PWQUALITY_LIBS@ @PASSWDQC_LIBS@
|
||||
|
||||
# cryptsetup
|
||||
if CRYPTSETUP
|
||||
|
||||
cryptsetup_SOURCES = \
|
||||
lib/utils_crypt.c \
|
||||
lib/utils_loop.c \
|
||||
lib/utils_io.c \
|
||||
lib/utils_blkid.c \
|
||||
src/utils_tools.c \
|
||||
src/utils_password.c \
|
||||
src/utils_luks2.c \
|
||||
src/cryptsetup.c \
|
||||
src/cryptsetup.h
|
||||
|
||||
cryptsetup_LDADD = \
|
||||
cryptsetup_LDADD = -lm \
|
||||
libcryptsetup.la \
|
||||
libutils_tools.la \
|
||||
@POPT_LIBS@ \
|
||||
@UUID_LIBS@
|
||||
@PWQUALITY_LIBS@ \
|
||||
@PASSWDQC_LIBS@ \
|
||||
@UUID_LIBS@ \
|
||||
@BLKID_LIBS@
|
||||
|
||||
sbin_PROGRAMS += cryptsetup
|
||||
|
||||
@@ -46,13 +40,16 @@ if VERITYSETUP
|
||||
veritysetup_SOURCES = \
|
||||
lib/utils_crypt.c \
|
||||
lib/utils_loop.c \
|
||||
lib/utils_io.c \
|
||||
lib/utils_blkid.c \
|
||||
src/utils_tools.c \
|
||||
src/veritysetup.c \
|
||||
src/cryptsetup.h
|
||||
|
||||
veritysetup_LDADD = \
|
||||
veritysetup_LDADD = -lm \
|
||||
libcryptsetup.la \
|
||||
libutils_tools.la \
|
||||
@POPT_LIBS@
|
||||
@POPT_LIBS@ \
|
||||
@BLKID_LIBS@
|
||||
|
||||
sbin_PROGRAMS += veritysetup
|
||||
|
||||
@@ -74,14 +71,17 @@ if INTEGRITYSETUP
|
||||
integritysetup_SOURCES = \
|
||||
lib/utils_crypt.c \
|
||||
lib/utils_loop.c \
|
||||
lib/utils_io.c \
|
||||
lib/utils_blkid.c \
|
||||
src/utils_tools.c \
|
||||
src/integritysetup.c \
|
||||
src/cryptsetup.h
|
||||
|
||||
integritysetup_LDADD = \
|
||||
integritysetup_LDADD = -lm \
|
||||
libcryptsetup.la \
|
||||
libutils_tools.la \
|
||||
@POPT_LIBS@ \
|
||||
@UUID_LIBS@
|
||||
@UUID_LIBS@ \
|
||||
@BLKID_LIBS@
|
||||
|
||||
sbin_PROGRAMS += integritysetup
|
||||
|
||||
@@ -101,14 +101,20 @@ endif
|
||||
if REENCRYPT
|
||||
cryptsetup_reencrypt_SOURCES = \
|
||||
lib/utils_crypt.c \
|
||||
lib/utils_io.c \
|
||||
lib/utils_blkid.c \
|
||||
src/utils_tools.c \
|
||||
src/utils_password.c \
|
||||
src/cryptsetup_reencrypt.c \
|
||||
src/cryptsetup.h
|
||||
|
||||
cryptsetup_reencrypt_LDADD = \
|
||||
cryptsetup_reencrypt_LDADD = -lm \
|
||||
libcryptsetup.la \
|
||||
libutils_tools.la \
|
||||
@POPT_LIBS@ \
|
||||
@UUID_LIBS@
|
||||
@PWQUALITY_LIBS@ \
|
||||
@PASSWDQC_LIBS@ \
|
||||
@UUID_LIBS@ \
|
||||
@BLKID_LIBS@
|
||||
|
||||
sbin_PROGRAMS += cryptsetup-reencrypt
|
||||
|
||||
|
||||
149
src/cryptsetup.c
149
src/cryptsetup.c
@@ -166,7 +166,7 @@ static void _set_activation_flags(uint32_t *flags)
|
||||
static int action_open_plain(void)
|
||||
{
|
||||
struct crypt_device *cd = NULL;
|
||||
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
char *msg, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
struct crypt_params_plain params = {
|
||||
.hash = opt_hash ?: DEFAULT_PLAIN_HASH,
|
||||
.skip = opt_skip,
|
||||
@@ -175,8 +175,8 @@ static int action_open_plain(void)
|
||||
.sector_size = opt_sector_size,
|
||||
};
|
||||
char *password = NULL;
|
||||
size_t passwordLen, key_size_max;
|
||||
size_t key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
|
||||
size_t passwordLen, key_size_max, signatures = 0,
|
||||
key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
|
||||
uint32_t activate_flags = 0;
|
||||
int r;
|
||||
|
||||
@@ -205,6 +205,27 @@ static int action_open_plain(void)
|
||||
if ((r = crypt_init(&cd, action_argv[0])))
|
||||
goto out;
|
||||
|
||||
/* Skip blkid scan when activating plain device with offset */
|
||||
if (!opt_offset) {
|
||||
/* Print all present signatures in read-only mode */
|
||||
r = tools_detect_signatures(action_argv[0], 0, &signatures);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (signatures) {
|
||||
r = asprintf(&msg, _("Detected device signature(s) on %s. Proceeding further may damage existing data."), action_argv[0]);
|
||||
if (r == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
|
||||
free(msg);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = crypt_format(cd, CRYPT_PLAIN,
|
||||
cipher, cipher_mode,
|
||||
NULL, NULL,
|
||||
@@ -748,7 +769,7 @@ static int action_benchmark(void)
|
||||
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
double enc_mbr = 0, dec_mbr = 0;
|
||||
int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
|
||||
int iv_size = 16, skipped = 0;
|
||||
int iv_size = 16, skipped = 0, width;
|
||||
char *c;
|
||||
int i, r;
|
||||
|
||||
@@ -775,13 +796,19 @@ static int action_benchmark(void)
|
||||
if (!strcmp(cipher_mode, "ecb"))
|
||||
iv_size = 0;
|
||||
|
||||
if (!strcmp(cipher_mode, "adiantum"))
|
||||
iv_size = 32;
|
||||
|
||||
r = benchmark_cipher_loop(cipher, cipher_mode,
|
||||
key_size, iv_size,
|
||||
&enc_mbr, &dec_mbr);
|
||||
if (!r) {
|
||||
width = strlen(cipher) + strlen(cipher_mode) + 1;
|
||||
if (width < 11)
|
||||
width = 11;
|
||||
/* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */
|
||||
log_std(_("# Algorithm | Key | Encryption | Decryption\n"));
|
||||
log_std("%11s-%s %9db %10.1f MiB/s %10.1f MiB/s\n",
|
||||
log_std(_("#%*s Algorithm | Key | Encryption | Decryption\n"), width - 11, "");
|
||||
log_std("%*s-%s %9db %10.1f MiB/s %10.1f MiB/s\n", width - (int)strlen(cipher_mode) - 1,
|
||||
cipher, cipher_mode, key_size*8, enc_mbr, dec_mbr);
|
||||
} else if (r == -ENOENT)
|
||||
log_err(_("Cipher %s is not available."), opt_cipher);
|
||||
@@ -923,7 +950,7 @@ static int _wipe_data_device(struct crypt_device *cd)
|
||||
|
||||
static int action_luksFormat(void)
|
||||
{
|
||||
int r = -EINVAL, keysize, integrity_keysize = 0, fd;
|
||||
int r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0;
|
||||
struct stat st;
|
||||
const char *header_device, *type;
|
||||
char *msg = NULL, *key = NULL, *password = NULL;
|
||||
@@ -977,8 +1004,10 @@ static int action_luksFormat(void)
|
||||
fd = open(opt_header_device, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
|
||||
if (fd == -1 || posix_fallocate(fd, 0, 4096))
|
||||
log_err(_("Cannot create header file %s."), opt_header_device);
|
||||
else
|
||||
else {
|
||||
r = 0;
|
||||
created = 1;
|
||||
}
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (r < 0)
|
||||
@@ -987,20 +1016,6 @@ static int action_luksFormat(void)
|
||||
|
||||
header_device = opt_header_device ?: action_argv[0];
|
||||
|
||||
/* Print all present signatures in read-only mode */
|
||||
r = tools_detect_signatures(header_device, 0, &signatures);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), header_device);
|
||||
if (r == -1)
|
||||
return -ENOMEM;
|
||||
|
||||
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
|
||||
free(msg);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
|
||||
cipher, NULL, cipher_mode);
|
||||
if (r < 0) {
|
||||
@@ -1028,6 +1043,24 @@ static int action_luksFormat(void)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Print all present signatures in read-only mode */
|
||||
r = tools_detect_signatures(header_device, 0, &signatures);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
if (!created) {
|
||||
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), header_device);
|
||||
if (r == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
|
||||
free(msg);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8 + integrity_keysize;
|
||||
|
||||
if (opt_random)
|
||||
@@ -1066,8 +1099,10 @@ static int action_luksFormat(void)
|
||||
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
|
||||
key, keysize,
|
||||
password, passwordLen);
|
||||
if (r < 0) /* FIXME: call wipe signatures again */
|
||||
if (r < 0) {
|
||||
(void) tools_wipe_all_signatures(header_device);
|
||||
goto out;
|
||||
}
|
||||
tools_keyslot_msg(r, CREATED);
|
||||
|
||||
if (opt_integrity && !opt_integrity_no_wipe)
|
||||
@@ -1098,8 +1133,11 @@ static int action_open_luks(void)
|
||||
if ((r = crypt_init(&cd, header_device)))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
header_device);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (data_device &&
|
||||
(r = crypt_set_data_device(cd, data_device)))
|
||||
@@ -1217,8 +1255,11 @@ static int action_luksKillSlot(void)
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ki = crypt_keyslot_status(cd, opt_key_slot);
|
||||
switch (ki) {
|
||||
@@ -1253,7 +1294,7 @@ static int action_luksKillSlot(void)
|
||||
}
|
||||
|
||||
r = crypt_keyslot_destroy(cd, opt_key_slot);
|
||||
tools_keyslot_msg(r, REMOVED);
|
||||
tools_keyslot_msg(opt_key_slot, REMOVED);
|
||||
out:
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
@@ -1271,8 +1312,11 @@ static int action_luksRemoveKey(void)
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = tools_get_key(_("Enter passphrase to be deleted: "),
|
||||
&password, &passwordLen,
|
||||
@@ -1303,7 +1347,7 @@ static int action_luksRemoveKey(void)
|
||||
}
|
||||
|
||||
r = crypt_keyslot_destroy(cd, opt_key_slot);
|
||||
tools_keyslot_msg(r, REMOVED);
|
||||
tools_keyslot_msg(opt_key_slot, REMOVED);
|
||||
out:
|
||||
crypt_safe_free(password);
|
||||
crypt_free(cd);
|
||||
@@ -1324,8 +1368,11 @@ static int luksAddUnboundKey(void)
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Never call pwquality if using null cipher */
|
||||
if (tools_is_cipher_null(crypt_get_cipher(cd)))
|
||||
@@ -1384,8 +1431,11 @@ static int action_luksAddKey(void)
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Never call pwquality if using null cipher */
|
||||
if (tools_is_cipher_null(crypt_get_cipher(cd)))
|
||||
@@ -1473,8 +1523,11 @@ static int action_luksChangeKey(void)
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Never call pwquality if using null cipher */
|
||||
if (tools_is_cipher_null(crypt_get_cipher(cd)))
|
||||
@@ -1495,7 +1548,7 @@ static int action_luksChangeKey(void)
|
||||
|
||||
/* Check password before asking for new one */
|
||||
r = crypt_activate_by_passphrase(cd, NULL, opt_key_slot,
|
||||
password, password_size, 0);
|
||||
password, password_size, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY);
|
||||
tools_passphrase_msg(r);
|
||||
check_signal(&r);
|
||||
if (r < 0)
|
||||
@@ -1530,8 +1583,17 @@ static int action_luksConvertKey(void)
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (crypt_keyslot_status(cd, opt_key_slot) == CRYPT_SLOT_INACTIVE) {
|
||||
r = -EINVAL;
|
||||
log_err(_("Keyslot %d is not active."), opt_key_slot);
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = set_pbkdf_params(cd, crypt_get_type(cd));
|
||||
if (r) {
|
||||
@@ -1677,8 +1739,11 @@ static int action_luksDump(void)
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_dump_master_key)
|
||||
r = luksDump_with_volume_key(cd);
|
||||
@@ -1823,8 +1888,11 @@ static int action_luksErase(void)
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(asprintf(&msg, _("This operation will erase all keyslots on device %s.\n"
|
||||
"Device will become unusable after this operation."),
|
||||
@@ -1849,7 +1917,7 @@ static int action_luksErase(void)
|
||||
r = crypt_keyslot_destroy(cd, i);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
tools_keyslot_msg(r, REMOVED);
|
||||
tools_keyslot_msg(i, REMOVED);
|
||||
}
|
||||
}
|
||||
out:
|
||||
@@ -1881,6 +1949,8 @@ static int action_luksConvert(void)
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS, NULL)) ||
|
||||
!(from_type = crypt_get_type(cd))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
@@ -1944,8 +2014,11 @@ static int action_luksConfig(void)
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
return r;
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device_header(NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_priority && (r = _config_priority(cd)))
|
||||
goto out;
|
||||
@@ -2106,6 +2179,8 @@ static int action_token(void)
|
||||
return r;
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
|
||||
log_err(_("Device %s is not a valid LUKS device."),
|
||||
uuid_or_device(opt_header_device ?: action_argv[1]));
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -588,8 +588,9 @@ static int create_new_header(struct reenc_ctx *rc, struct crypt_device *cd_old,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = crypt_format(cd_new, type, cipher, cipher_mode,
|
||||
uuid, key, key_size, params)))
|
||||
r = crypt_format(cd_new, type, cipher, cipher_mode, uuid, key, key_size, params);
|
||||
check_signal(&r);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
log_verbose(_("New LUKS header for device %s created."), rc->device);
|
||||
|
||||
@@ -598,6 +599,7 @@ static int create_new_header(struct reenc_ctx *rc, struct crypt_device *cd_old,
|
||||
continue;
|
||||
|
||||
r = create_new_keyslot(rc, i, cd_old, cd_new);
|
||||
check_signal(&r);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
tools_keyslot_msg(r, CREATED);
|
||||
@@ -835,11 +837,13 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
|
||||
r = crypt_format(cd_new, CRYPT_LUKS1, "cipher_null", "ecb",
|
||||
NO_UUID, NULL, opt_key_size / 8, ¶ms);
|
||||
check_signal(&r);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = crypt_keyslot_add_by_volume_key(cd_new, rc->keyslot, NULL, 0,
|
||||
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
|
||||
check_signal(&r);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -1535,6 +1539,8 @@ static int run_reencrypt(const char *device)
|
||||
.stained = 1
|
||||
};
|
||||
|
||||
set_int_handler(0);
|
||||
|
||||
if (initialize_context(&rc, device))
|
||||
goto out;
|
||||
|
||||
@@ -1654,8 +1660,6 @@ int main(int argc, const char **argv)
|
||||
|
||||
crypt_set_log_callback(NULL, tool_log, NULL);
|
||||
|
||||
set_int_block(1);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
@@ -209,19 +209,6 @@ static int action_format(int arg)
|
||||
params.journal_crypt = journal_crypt;
|
||||
}
|
||||
|
||||
r = tools_detect_signatures(action_argv[0], 0, &signatures);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]);
|
||||
if (r == -1)
|
||||
return -ENOMEM;
|
||||
|
||||
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
|
||||
free(msg);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = _read_keys(&integrity_key, ¶ms);
|
||||
if (r)
|
||||
goto out;
|
||||
@@ -230,6 +217,21 @@ static int action_format(int arg)
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]);
|
||||
if (r == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
|
||||
free(msg);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = tools_detect_signatures(action_argv[0], 0, &signatures);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* Signature candidates found */
|
||||
if (signatures && ((r = tools_wipe_all_signatures(action_argv[0])) < 0))
|
||||
goto out;
|
||||
|
||||
139
src/utils_luks2.c
Normal file
139
src/utils_luks2.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Helper utilities for LUKS2 features
|
||||
*
|
||||
* Copyright (C) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018, Milan Broz
|
||||
* Copyright (C) 2018, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cryptsetup.h"
|
||||
|
||||
/*
|
||||
* FIXME: 4MiBs is max LUKS2 mda length (including binary header).
|
||||
* In future, read max allowed JSON size from config section.
|
||||
*/
|
||||
#define LUKS2_MAX_MDA_SIZE 0x400000
|
||||
int tools_read_json_file(struct crypt_device *cd, const char *file, char **json, size_t *json_size)
|
||||
{
|
||||
ssize_t ret;
|
||||
int fd, block, r;
|
||||
void *buf = NULL;
|
||||
|
||||
block = tools_signals_blocked();
|
||||
if (block)
|
||||
set_int_block(0);
|
||||
|
||||
if (tools_is_stdin(file)) {
|
||||
fd = STDIN_FILENO;
|
||||
log_dbg("STDIN descriptor JSON read requested.");
|
||||
} else {
|
||||
log_dbg("File descriptor JSON read requested.");
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
log_err(_("Failed to open file %s in read-only mode."), file);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
buf = malloc(LUKS2_MAX_MDA_SIZE);
|
||||
if (!buf) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (isatty(fd) && !opt_batch_mode)
|
||||
log_std(_("Provide valid LUKS2 token JSON:\n"));
|
||||
|
||||
/* we expect JSON (string) */
|
||||
r = 0;
|
||||
ret = read_buffer_intr(fd, buf, LUKS2_MAX_MDA_SIZE - 1, &quit);
|
||||
if (ret < 0) {
|
||||
r = -EIO;
|
||||
log_err(_("Failed to read JSON file."));
|
||||
goto out;
|
||||
}
|
||||
check_signal(&r);
|
||||
if (r) {
|
||||
log_err(_("\nRead interrupted."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
*json_size = (size_t)ret;
|
||||
*json = buf;
|
||||
*(*json + ret) = '\0';
|
||||
out:
|
||||
if (block && !quit)
|
||||
set_int_block(1);
|
||||
if (fd >= 0 && fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
if (r && buf) {
|
||||
memset(buf, 0, LUKS2_MAX_MDA_SIZE);
|
||||
free(buf);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int tools_write_json_file(struct crypt_device *cd, const char *file, const char *json)
|
||||
{
|
||||
int block, fd, r;
|
||||
size_t json_len;
|
||||
ssize_t ret;
|
||||
|
||||
if (!json || !(json_len = strlen(json)) || json_len >= LUKS2_MAX_MDA_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
block = tools_signals_blocked();
|
||||
if (block)
|
||||
set_int_block(0);
|
||||
|
||||
if (tools_is_stdin(file)) {
|
||||
fd = STDOUT_FILENO;
|
||||
log_dbg("STDOUT descriptor JSON write requested.");
|
||||
} else {
|
||||
log_dbg("File descriptor JSON write requested.");
|
||||
fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
log_err(_("Failed to open file %s in write mode."), file ?: "");
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
ret = write_buffer_intr(fd, json, json_len, &quit);
|
||||
check_signal(&r);
|
||||
if (r) {
|
||||
log_err(_("\nWrite interrupted."));
|
||||
goto out;
|
||||
}
|
||||
if (ret < 0 || (size_t)ret != json_len) {
|
||||
log_err(_("Failed to write JSON file."));
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (isatty(fd))
|
||||
(void) write_buffer_intr(fd, "\n", 1, &quit);
|
||||
out:
|
||||
if (block && !quit)
|
||||
set_int_block(1);
|
||||
if (fd >=0 && fd != STDOUT_FILENO)
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
@@ -94,25 +94,6 @@ static int tools_check_pwquality(const char *password)
|
||||
}
|
||||
#endif /* ENABLE_PWQUALITY || ENABLE_PASSWDQC */
|
||||
|
||||
int tools_is_cipher_null(const char *cipher)
|
||||
{
|
||||
if (!cipher)
|
||||
return 0;
|
||||
|
||||
return !strcmp(cipher, "cipher_null") ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keyfile - is standard input treated as a binary file (no EOL handling).
|
||||
*/
|
||||
int tools_is_stdin(const char *key_file)
|
||||
{
|
||||
if (!key_file)
|
||||
return 1;
|
||||
|
||||
return strcmp(key_file, "-") ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Password reading helpers */
|
||||
static int untimed_read(int fd, char *pass, size_t maxlen)
|
||||
{
|
||||
@@ -334,7 +315,7 @@ int tools_write_mk(const char *file, const char *key, int keysize)
|
||||
{
|
||||
int fd, r = -EINVAL;
|
||||
|
||||
fd = open(file, O_WRONLY);
|
||||
fd = open(file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
|
||||
if (fd < 0) {
|
||||
log_err(_("Cannot open keyfile %s for write."), file);
|
||||
return r;
|
||||
|
||||
@@ -583,118 +583,21 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int tools_is_cipher_null(const char *cipher)
|
||||
{
|
||||
if (!cipher)
|
||||
return 0;
|
||||
|
||||
return !strcmp(cipher, "cipher_null") ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: 4MiBs is max LUKS2 mda length (including binary header).
|
||||
* In future, read max allowed JSON size from config section.
|
||||
* Keyfile - is standard input treated as a binary file (no EOL handling).
|
||||
*/
|
||||
#define LUKS2_MAX_MDA_SIZE 0x400000
|
||||
int tools_read_json_file(struct crypt_device *cd, const char *file, char **json, size_t *json_size)
|
||||
int tools_is_stdin(const char *key_file)
|
||||
{
|
||||
ssize_t ret;
|
||||
int fd, block, r;
|
||||
void *buf = NULL;
|
||||
if (!key_file)
|
||||
return 1;
|
||||
|
||||
block = tools_signals_blocked();
|
||||
if (block)
|
||||
set_int_block(0);
|
||||
|
||||
if (tools_is_stdin(file)) {
|
||||
fd = STDIN_FILENO;
|
||||
log_dbg("STDIN descriptor JSON read requested.");
|
||||
} else {
|
||||
log_dbg("File descriptor JSON read requested.");
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
log_err(_("Failed to open file %s in read-only mode."), file);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
buf = malloc(LUKS2_MAX_MDA_SIZE);
|
||||
if (!buf) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (isatty(fd) && !opt_batch_mode)
|
||||
log_std(_("Provide valid LUKS2 token JSON:\n"));
|
||||
|
||||
/* we expect JSON (string) */
|
||||
r = 0;
|
||||
ret = read_buffer_intr(fd, buf, LUKS2_MAX_MDA_SIZE - 1, &quit);
|
||||
if (ret < 0) {
|
||||
r = -EIO;
|
||||
log_err(_("Failed to read JSON file."));
|
||||
goto out;
|
||||
}
|
||||
check_signal(&r);
|
||||
if (r) {
|
||||
log_err(_("\nRead interrupted."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
*json_size = (size_t)ret;
|
||||
*json = buf;
|
||||
*(*json + ret) = '\0';
|
||||
out:
|
||||
if (block && !quit)
|
||||
set_int_block(1);
|
||||
if (fd >= 0 && fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
if (r && buf) {
|
||||
memset(buf, 0, LUKS2_MAX_MDA_SIZE);
|
||||
free(buf);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int tools_write_json_file(struct crypt_device *cd, const char *file, const char *json)
|
||||
{
|
||||
int block, fd, r;
|
||||
size_t json_len;
|
||||
ssize_t ret;
|
||||
|
||||
if (!json || !(json_len = strlen(json)) || json_len >= LUKS2_MAX_MDA_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
block = tools_signals_blocked();
|
||||
if (block)
|
||||
set_int_block(0);
|
||||
|
||||
if (tools_is_stdin(file)) {
|
||||
fd = STDOUT_FILENO;
|
||||
log_dbg("STDOUT descriptor JSON write requested.");
|
||||
} else {
|
||||
log_dbg("File descriptor JSON write requested.");
|
||||
fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
log_err(_("Failed to open file %s in write mode."), file ?: "");
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
ret = write_buffer_intr(fd, json, json_len, &quit);
|
||||
check_signal(&r);
|
||||
if (r) {
|
||||
log_err(_("\nWrite interrupted."));
|
||||
goto out;
|
||||
}
|
||||
if (ret < 0 || (size_t)ret != json_len) {
|
||||
log_err(_("Failed to write JSON file."));
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (isatty(fd))
|
||||
(void) write_buffer_intr(fd, "\n", 1, &quit);
|
||||
out:
|
||||
if (block && !quit)
|
||||
set_int_block(1);
|
||||
if (fd >=0 && fd != STDOUT_FILENO)
|
||||
close(fd);
|
||||
return r;
|
||||
return strcmp(key_file, "-") ? 0 : 1;
|
||||
}
|
||||
|
||||
28
tests/00modules-test
Executable file
28
tests/00modules-test
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Cryptsetup test environment ($(date))"
|
||||
uname -a
|
||||
|
||||
if [ -f /etc/os-release ] ; then
|
||||
source /etc/os-release
|
||||
echo "$PRETTY_NAME ($NAME) $VERSION"
|
||||
fi
|
||||
|
||||
[ -x ../cryptsetup ] && ../cryptsetup --version
|
||||
[ -x ../veritysetup ] && ../veritysetup --version
|
||||
[ -x ../integritysetup ] && ../integritysetup --version
|
||||
[ -x ../cryptsetup-reencrypt ] && ../cryptsetup-reencrypt --version
|
||||
|
||||
[ $(id -u) != 0 ] && exit 77
|
||||
|
||||
modprobe dm-crypt >/dev/null 2>&1
|
||||
modprobe dm-verity >/dev/null 2>&1
|
||||
modprobe dm-integrity >/dev/null 2>&1
|
||||
modprobe dm-zero >/dev/null 2>&1
|
||||
|
||||
dmsetup version
|
||||
|
||||
echo "Device mapper targets:"
|
||||
dmsetup targets
|
||||
|
||||
exit 0
|
||||
@@ -1,9 +1,11 @@
|
||||
TESTS = api-test \
|
||||
TESTS = 00modules-test \
|
||||
api-test \
|
||||
api-test-2 \
|
||||
compat-test \
|
||||
compat-test2 \
|
||||
loopaes-test \
|
||||
align-test \
|
||||
align-test2 \
|
||||
discards-test \
|
||||
mode-test \
|
||||
password-hash-test \
|
||||
@@ -30,26 +32,28 @@ if INTEGRITYSETUP
|
||||
TESTS += integrity-compat-test
|
||||
endif
|
||||
|
||||
EXTRA_DIST = compatimage.img.bz2 compatv10image.img.bz2 \
|
||||
EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \
|
||||
compatimage2.img.xz \
|
||||
conversion_imgs.tar.xz \
|
||||
luks2_keyslot_unassigned.img.xz \
|
||||
img_fs_ext4.img.bz2 img_fs_vfat.img.bz2 img_fs_xfs.img.bz2 \
|
||||
valid_header_file.bz2 \
|
||||
img_fs_ext4.img.xz img_fs_vfat.img.xz img_fs_xfs.img.xz \
|
||||
valid_header_file.xz \
|
||||
luks2_valid_hdr.img.xz \
|
||||
luks2_header_requirements.xz \
|
||||
luks2_header_requirements_free.xz \
|
||||
evil_hdr-payload_overwrite.bz2 \
|
||||
evil_hdr-stripes_payload_dmg.bz2 \
|
||||
evil_hdr-luks_hdr_damage.bz2 \
|
||||
evil_hdr-small_luks_device.bz2 \
|
||||
evil_hdr-keyslot_overlap.bz2 \
|
||||
tcrypt-images.tar.bz2 \
|
||||
luks1-images.tar.bz2 \
|
||||
luks2_mda_images.tar.xz \
|
||||
evil_hdr-payload_overwrite.xz \
|
||||
evil_hdr-stripes_payload_dmg.xz \
|
||||
evil_hdr-luks_hdr_damage.xz \
|
||||
evil_hdr-small_luks_device.xz \
|
||||
evil_hdr-keyslot_overlap.xz \
|
||||
tcrypt-images.tar.xz \
|
||||
luks1-images.tar.xz \
|
||||
00modules-test \
|
||||
compat-test \
|
||||
compat-test2 \
|
||||
loopaes-test align-test discards-test mode-test password-hash-test \
|
||||
verity-compat-test \
|
||||
align-test2 verity-compat-test \
|
||||
reencryption-compat-test \
|
||||
reencryption-compat-test2 \
|
||||
tcrypt-compat-test \
|
||||
@@ -101,7 +105,7 @@ conversion_imgs:
|
||||
@tar xJf conversion_imgs.tar.xz
|
||||
|
||||
compatimage.img:
|
||||
@bzip2 -k -d compatimage.img.bz2
|
||||
@xz -k -d compatimage.img.xz
|
||||
|
||||
valgrind-check: api-test api-test-2 differ
|
||||
@VALG=1 ./compat-test
|
||||
|
||||
122
tests/align-test
122
tests/align-test
@@ -3,9 +3,11 @@
|
||||
CRYPTSETUP="../cryptsetup"
|
||||
DEV=""
|
||||
DEV_STACKED="luks0xbabe"
|
||||
DEV_NAME="dummyalign"
|
||||
MNT_DIR="./mnt_luks"
|
||||
PWD1="93R4P4pIqAH8"
|
||||
PWD2="mymJeD8ivEhE"
|
||||
FAST_PBKDF="--pbkdf-force-iterations 1000"
|
||||
|
||||
cleanup() {
|
||||
udevadm settle >/dev/null 2>&1
|
||||
@@ -13,7 +15,8 @@ cleanup() {
|
||||
umount -f $MNT_DIR 2>/dev/null
|
||||
rmdir $MNT_DIR 2>/dev/null
|
||||
fi
|
||||
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove $DEV_STACKED >/dev/null 2>&1
|
||||
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1
|
||||
# FIXME scsi_debug sometimes in-use here
|
||||
sleep 1
|
||||
rmmod scsi_debug 2>/dev/null
|
||||
@@ -34,8 +37,31 @@ skip()
|
||||
exit 0
|
||||
}
|
||||
|
||||
function dm_crypt_features()
|
||||
{
|
||||
VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
|
||||
[ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
|
||||
|
||||
VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
|
||||
VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
|
||||
VER_PTC=$(echo $VER_STR | cut -f 3 -d.)
|
||||
|
||||
[ $VER_MAJ -lt 1 ] && return
|
||||
[ $VER_MAJ -gt 1 ] && {
|
||||
DM_PERF_CPU=1
|
||||
DM_SECTOR_SIZE=1
|
||||
return
|
||||
}
|
||||
|
||||
[ $VER_MIN -lt 14 ] && return
|
||||
DM_PERF_CPU=1
|
||||
if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then
|
||||
DM_SECTOR_SIZE=1
|
||||
fi
|
||||
}
|
||||
|
||||
add_device() {
|
||||
modprobe scsi_debug $@
|
||||
modprobe scsi_debug $@ delay=0
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "This kernel seems to not support proper scsi_debug module, test skipped."
|
||||
exit 77
|
||||
@@ -58,12 +84,16 @@ format() # key_bits expected [forced]
|
||||
{
|
||||
if [ -z "$3" ] ; then
|
||||
echo -n "Formatting using topology info ($1 bits key)..."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -c aes-cbc-essiv:sha256 -s $1
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c aes-cbc-essiv:sha256 -s $1 || fail
|
||||
else
|
||||
echo -n "Formatting using forced sector alignment $3 ($1 bits key)..."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -s $1 -c aes-cbc-essiv:sha256 --align-payload=$2
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -s $1 -c aes-cbc-essiv:sha256 --align-payload=$3 ||fail
|
||||
fi
|
||||
|
||||
# check the device can be activated
|
||||
echo $PWD1 | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
|
||||
ALIGN=$($CRYPTSETUP luksDump $DEV |grep "Payload offset" | sed -e s/.*\\t//)
|
||||
#echo "ALIGN = $ALIGN"
|
||||
|
||||
@@ -71,7 +101,7 @@ format() # key_bits expected [forced]
|
||||
[ $ALIGN -ne $2 ] && fail "Expected alignment differs: expected $2 != detected $ALIGN"
|
||||
|
||||
# test some operation, just in case
|
||||
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --key-slot 1
|
||||
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --key-slot 1
|
||||
[ $? -ne 0 ] && fail "Keyslot add failed."
|
||||
|
||||
$CRYPTSETUP -q luksKillSlot $DEV 1
|
||||
@@ -89,18 +119,22 @@ format_null()
|
||||
{
|
||||
if [ $3 -eq 0 ] ; then
|
||||
echo -n "Formatting using topology info ($1 bits key) [slot 0"
|
||||
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -c null -s $1
|
||||
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 || fail
|
||||
else
|
||||
echo -n "Formatting using forced sector alignment $3 ($1 bits key) [slot 0"
|
||||
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -c null -s $1 --align-payload=$3
|
||||
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 --align-payload=$3 || fail
|
||||
fi
|
||||
|
||||
# check the device can be activated
|
||||
echo | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
|
||||
POFF=$(get_offsets "Payload offset")
|
||||
[ -z "$POFF" ] && fail
|
||||
[ $POFF != $2 ] && fail "Expected data offset differs: expected $2 != detected $POFF"
|
||||
if [ -n "$4" ] ; then
|
||||
for j in 1 2 3 4 5 6 7 ; do
|
||||
echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q -i1 --key-slot $j -c null $PARAMS
|
||||
echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q $FAST_PBKDF --key-slot $j -c null $PARAMS
|
||||
echo -n $j
|
||||
[ $? -ne 0 ] && fail
|
||||
done
|
||||
@@ -113,11 +147,35 @@ format_null()
|
||||
echo "]...PASSED"
|
||||
}
|
||||
|
||||
format_plain() # sector size
|
||||
{
|
||||
echo -n "Formatting plain device (sector size $1)..."
|
||||
if [ -n "$DM_SECTOR_SIZE" ] ; then
|
||||
echo $PWD1 | $CRYPTSETUP open --type plain --sector-size $1 $DEV $DEV_NAME || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
echo "PASSED"
|
||||
else
|
||||
echo "N/A"
|
||||
fi
|
||||
}
|
||||
|
||||
format_plain_fail() # sector size
|
||||
{
|
||||
echo -n "Formatting plain device (sector size $1, must fail)..."
|
||||
if [ -n "$DM_SECTOR_SIZE" ] ; then
|
||||
echo $PWD1 | $CRYPTSETUP open --type plain --sector-size $1 $DEV $DEV_NAME >/dev/null 2>&1 && fail
|
||||
echo "PASSED"
|
||||
else
|
||||
echo "N/A"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ $(id -u) != 0 ]; then
|
||||
echo "WARNING: You must be root to run this test, test skipped."
|
||||
exit 77
|
||||
fi
|
||||
|
||||
dm_crypt_features
|
||||
modprobe --dry-run scsi_debug || exit 77
|
||||
cleanup
|
||||
|
||||
@@ -125,9 +183,9 @@ echo "# Create desktop-class 4K drive"
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1
|
||||
format 256 4096
|
||||
format 256 2112 8
|
||||
format 256 2056 8
|
||||
format 128 2048
|
||||
format 128 1088 8
|
||||
format 128 1032 8
|
||||
format 256 8192 8192
|
||||
format 128 8192 8192
|
||||
cleanup
|
||||
@@ -136,9 +194,9 @@ echo "# Create desktop-class 4K drive with misaligned opt-io (some bad USB enclo
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0, opt-io=1025)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1 opt_blks=1025
|
||||
format 256 4096
|
||||
format 256 2112 8
|
||||
format 256 2056 8
|
||||
format 128 2048
|
||||
format 128 1088 8
|
||||
format 128 1032 8
|
||||
format 256 8192 8192
|
||||
format 128 8192 8192
|
||||
cleanup
|
||||
@@ -147,18 +205,18 @@ echo "# Create desktop-class 4K drive w/ 63-sector DOS partition compensation"
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=3584)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=7 num_tgts=1
|
||||
format 256 4103
|
||||
format 256 2119 8
|
||||
format 256 2056 8
|
||||
format 128 2055
|
||||
format 128 1095 8
|
||||
format 128 1032 8
|
||||
cleanup
|
||||
|
||||
echo "# Create enterprise-class 4K drive"
|
||||
echo "# (logical_block_size=4096, physical_block_size=4096, alignment_offset=0)"
|
||||
add_device dev_size_mb=16 sector_size=4096 num_tgts=1 opt_blks=64
|
||||
format 256 4096
|
||||
format 256 2560 8
|
||||
format 256 2056 8
|
||||
format 128 2048
|
||||
format 128 1536 8
|
||||
format 128 1032 8
|
||||
cleanup
|
||||
|
||||
echo "# Create classic 512B drive and stack dm-linear"
|
||||
@@ -168,12 +226,32 @@ DEV2=$DEV
|
||||
DEV=/dev/mapper/$DEV_STACKED
|
||||
dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0"
|
||||
format 256 4096
|
||||
format 256 2112 8
|
||||
format 256 2056 8
|
||||
format 128 2048
|
||||
format 128 1088 8
|
||||
format 128 1032 8
|
||||
format 128 8192 8192
|
||||
cleanup
|
||||
|
||||
echo "# Create classic 512B drive and stack dm-linear (plain mode)"
|
||||
add_device dev_size_mb=16 sector_size=512 num_tgts=1
|
||||
DEV2=$DEV
|
||||
DEV=/dev/mapper/$DEV_STACKED
|
||||
dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0"
|
||||
format_plain 512
|
||||
format_plain 1024
|
||||
format_plain 2048
|
||||
format_plain 4096
|
||||
format_plain_fail 1111
|
||||
format_plain_fail 8192
|
||||
echo "# Create classic 512B drive, unaligned to 4096 and stack dm-linear (plain mode)"
|
||||
dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1
|
||||
dmsetup create $DEV_STACKED --table "0 32762 linear $DEV2 0"
|
||||
format_plain 512
|
||||
format_plain 1024
|
||||
format_plain_fail 2048
|
||||
format_plain_fail 4096
|
||||
cleanup
|
||||
|
||||
echo "# Offset check: 512B sector drive"
|
||||
add_device dev_size_mb=16 sector_size=512 num_tgts=1
|
||||
# |k| expO reqO expected slot offsets
|
||||
@@ -227,13 +305,13 @@ echo "# Create enterprise-class 4K drive with fs and LUKS images."
|
||||
# loop device here presents 512 block but images have 4k block
|
||||
# cryptsetup should properly use 4k block on direct-io
|
||||
add_device dev_size_mb=32 sector_size=4096 physblk_exp=0 num_tgts=1 opt_blks=64
|
||||
for file in $(ls img_fs_*.img.bz2) ; do
|
||||
for file in $(ls img_fs_*.img.xz) ; do
|
||||
echo "Format using fs image $file."
|
||||
bzip2 -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
|
||||
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
|
||||
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
|
||||
mount $DEV $MNT_DIR || skip "Mounting image is not available."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 -i 1 $MNT_DIR/luks.img || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksFormat --type luks1 -i 1 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF $MNT_DIR/luks.img || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
|
||||
umount $MNT_DIR
|
||||
done
|
||||
cleanup
|
||||
|
||||
334
tests/align-test2
Executable file
334
tests/align-test2
Executable file
@@ -0,0 +1,334 @@
|
||||
#!/bin/bash
|
||||
|
||||
CRYPTSETUP="../cryptsetup"
|
||||
DEV=""
|
||||
DEV_STACKED="luks0xbabe"
|
||||
DEV_NAME="dummyalign"
|
||||
MNT_DIR="./mnt_luks"
|
||||
PWD1="93R4P4pIqAH8"
|
||||
PWD2="mymJeD8ivEhE"
|
||||
FAST_PBKDF="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
|
||||
|
||||
EXPCT=8192
|
||||
|
||||
cleanup() {
|
||||
udevadm settle >/dev/null 2>&1
|
||||
if [ -d "$MNT_DIR" ] ; then
|
||||
umount -f $MNT_DIR 2>/dev/null
|
||||
rmdir $MNT_DIR 2>/dev/null
|
||||
fi
|
||||
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1
|
||||
# FIXME scsi_debug sometimes in-use here
|
||||
sleep 1
|
||||
rmmod scsi_debug 2>/dev/null
|
||||
sleep 1
|
||||
}
|
||||
|
||||
fail()
|
||||
{
|
||||
if [ -n "$1" ] ; then echo "FAIL $1" ; fi
|
||||
echo "FAILED at line $(caller)"
|
||||
cleanup
|
||||
exit 100
|
||||
}
|
||||
|
||||
skip()
|
||||
{
|
||||
echo "TEST SKIPPED: $1"
|
||||
cleanup
|
||||
exit 0
|
||||
}
|
||||
|
||||
function dm_crypt_features()
|
||||
{
|
||||
VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
|
||||
[ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
|
||||
|
||||
VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
|
||||
VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
|
||||
VER_PTC=$(echo $VER_STR | cut -f 3 -d.)
|
||||
|
||||
[ $VER_MAJ -lt 1 ] && return
|
||||
[ $VER_MAJ -gt 1 ] && {
|
||||
DM_PERF_CPU=1
|
||||
DM_SECTOR_SIZE=1
|
||||
return
|
||||
}
|
||||
|
||||
[ $VER_MIN -lt 14 ] && return
|
||||
DM_PERF_CPU=1
|
||||
if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then
|
||||
DM_SECTOR_SIZE=1
|
||||
fi
|
||||
}
|
||||
|
||||
add_device() {
|
||||
modprobe scsi_debug $@ delay=0
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "This kernel seems to not support proper scsi_debug module, test skipped."
|
||||
exit 77
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
||||
|
||||
if [ ! -e /sys/block/$DEV/alignment_offset ] ; then
|
||||
echo "This kernel seems to not support topology info, test skipped."
|
||||
cleanup
|
||||
exit 77
|
||||
fi
|
||||
|
||||
DEV="/dev/$DEV"
|
||||
[ -b $DEV ] || fail "Cannot find $DEV."
|
||||
}
|
||||
|
||||
format() # expected [forced] [encryption_sector_size]
|
||||
{
|
||||
local _sec_size=512
|
||||
|
||||
local _exp=$1
|
||||
|
||||
if [ "${2:0:1}" = "s" ]; then
|
||||
_sec_size=${2:1}
|
||||
shift
|
||||
fi
|
||||
|
||||
test "${3:0:1}" = "s" && _sec_size=${3:1}
|
||||
|
||||
test $_sec_size -eq 512 || local _smsg=" (encryption sector size $_sec_size)"
|
||||
|
||||
if [ -z "$2" ] ; then
|
||||
echo -n "Formatting using topology info$_smsg..."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size || fail
|
||||
else
|
||||
echo -n "Formatting using forced sector alignment $2$_smsg..."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size || fail
|
||||
fi
|
||||
|
||||
# check the device can be activated
|
||||
if [ -n "$DM_SECTOR_SIZE" ] ; then
|
||||
echo $PWD1 | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
fi
|
||||
|
||||
ALIGN=$($CRYPTSETUP luksDump $DEV | tee /tmp/last_dump | grep -A1 "0: crypt" | grep "offset:" | cut -d ' ' -f2)
|
||||
# echo "ALIGN = $ALIGN"
|
||||
|
||||
[ -z "$ALIGN" ] && fail
|
||||
ALIGN=$((ALIGN/512))
|
||||
[ $ALIGN -ne $_exp ] && fail "Expected alignment differs: expected $_exp != detected $ALIGN"
|
||||
|
||||
# test some operation, just in case
|
||||
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --key-slot 1
|
||||
[ $? -ne 0 ] && fail "Keyslot add failed."
|
||||
|
||||
$CRYPTSETUP -q luksKillSlot $DEV 1
|
||||
[ $? -ne 0 ] && fail "Keyslot removal failed."
|
||||
|
||||
echo "PASSED"
|
||||
}
|
||||
|
||||
format_fail() # expected [forced] [encryption_sector_size]
|
||||
{
|
||||
local _sec_size=512
|
||||
|
||||
local _exp=$1
|
||||
|
||||
if [ "${2:0:1}" = "s" ]; then
|
||||
_sec_size=${2:1}
|
||||
shift
|
||||
fi
|
||||
|
||||
test "${3:0:1}" = "s" && _sec_size=${3:1}
|
||||
|
||||
test $_sec_size -eq 512 || local _smsg=" (encryption sector size $_sec_size)"
|
||||
|
||||
if [ -z "$2" ] ; then
|
||||
echo -n "Formatting using topology info$_smsg (must fail)..."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size >/dev/null 2>&1 && fail
|
||||
else
|
||||
echo -n "Formatting using forced sector alignment $2$_smsg (must fail)..."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size >/dev/null 2>&1 && fail
|
||||
fi
|
||||
|
||||
echo "PASSED"
|
||||
}
|
||||
|
||||
if [ $(id -u) != 0 ]; then
|
||||
echo "WARNING: You must be root to run this test, test skipped."
|
||||
exit 77
|
||||
fi
|
||||
|
||||
dm_crypt_features
|
||||
modprobe --dry-run scsi_debug || exit 77
|
||||
cleanup
|
||||
|
||||
echo "# Create desktop-class 4K drive"
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1
|
||||
format $EXPCT
|
||||
format $EXPCT s1024
|
||||
format $EXPCT s2048
|
||||
format $EXPCT s4096
|
||||
format $EXPCT 1
|
||||
format $EXPCT 1 s1024
|
||||
format $EXPCT 1 s2048
|
||||
format $EXPCT 1 s4096
|
||||
format $EXPCT 8
|
||||
format $EXPCT 8 s1024
|
||||
format $EXPCT 8 s2048
|
||||
format $EXPCT 8 s4096
|
||||
format $((EXPCT+1)) $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
|
||||
format $EXPCT $EXPCT
|
||||
format $EXPCT $EXPCT s1024
|
||||
format $EXPCT $EXPCT s2048
|
||||
format $EXPCT $EXPCT s4096
|
||||
cleanup
|
||||
|
||||
echo "# Create desktop-class 4K drive with misaligned opt-io (some bad USB enclosures)"
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0, opt-io=1025)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1 opt_blks=1025
|
||||
format $EXPCT
|
||||
format $EXPCT s1024
|
||||
format $EXPCT s2048
|
||||
format $EXPCT s4096
|
||||
format $EXPCT 1
|
||||
format $EXPCT 1 s1024
|
||||
format $EXPCT 1 s2048
|
||||
format $EXPCT 1 s4096
|
||||
format $EXPCT 8
|
||||
format $EXPCT 8 s1024
|
||||
format $EXPCT 8 s2048
|
||||
format $EXPCT 8 s4096
|
||||
format $((EXPCT+1)) $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
|
||||
format $EXPCT $EXPCT
|
||||
format $EXPCT $EXPCT s1024
|
||||
format $EXPCT $EXPCT s2048
|
||||
format $EXPCT $EXPCT s4096
|
||||
cleanup
|
||||
|
||||
echo "# Create desktop-class 4K drive w/ 1-sector shift (original bug report)"
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=512)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=1 num_tgts=1
|
||||
format $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) s4096
|
||||
format $EXPCT 1
|
||||
format $EXPCT 1 s1024
|
||||
format $EXPCT 1 s2048
|
||||
format $EXPCT 1 s4096
|
||||
format $EXPCT 8
|
||||
format $EXPCT 8 s1024
|
||||
format $EXPCT 8 s2048
|
||||
format $EXPCT 8 s4096
|
||||
format $((EXPCT+1)) $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
|
||||
format $EXPCT $EXPCT
|
||||
format $EXPCT $EXPCT s1024
|
||||
format $EXPCT $EXPCT s2048
|
||||
format $EXPCT $EXPCT s4096
|
||||
cleanup
|
||||
|
||||
echo "# Create desktop-class 4K drive w/ 63-sector DOS partition compensation"
|
||||
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=3584)"
|
||||
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=7 num_tgts=1
|
||||
format $((EXPCT+7))
|
||||
format_fail $((EXPCT+7)) s1024
|
||||
format_fail $((EXPCT+7)) s2048
|
||||
format_fail $((EXPCT+7)) s4096
|
||||
format $EXPCT 1
|
||||
format $EXPCT 1 s1024
|
||||
format $EXPCT 1 s2048
|
||||
format $EXPCT 1 s4096
|
||||
format $EXPCT 8
|
||||
format $EXPCT 8 s1024
|
||||
format $EXPCT 8 s2048
|
||||
format $EXPCT 8 s4096
|
||||
format $((EXPCT+1)) $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
|
||||
format $EXPCT $EXPCT
|
||||
format $EXPCT $EXPCT s1024
|
||||
format $EXPCT $EXPCT s2048
|
||||
format $EXPCT $EXPCT s4096
|
||||
cleanup
|
||||
|
||||
echo "# Create enterprise-class 4K drive"
|
||||
echo "# (logical_block_size=4096, physical_block_size=4096, alignment_offset=0)"
|
||||
add_device dev_size_mb=16 sector_size=4096 num_tgts=1 opt_blks=64
|
||||
format $EXPCT
|
||||
format $EXPCT s1024
|
||||
format $EXPCT s2048
|
||||
format $EXPCT s4096
|
||||
format $EXPCT 1
|
||||
format $EXPCT 1 s1024
|
||||
format $EXPCT 1 s2048
|
||||
format $EXPCT 1 s4096
|
||||
format $EXPCT 8
|
||||
format $EXPCT 8 s1024
|
||||
format $EXPCT 8 s2048
|
||||
format $EXPCT 8 s4096
|
||||
#FIXME: kernel limits issue?
|
||||
##format $((EXPCT+1)) $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
|
||||
format $EXPCT $EXPCT
|
||||
format $EXPCT $EXPCT s1024
|
||||
format $EXPCT $EXPCT s2048
|
||||
format $EXPCT $EXPCT s4096
|
||||
cleanup
|
||||
|
||||
echo "# Create classic 512B drive and stack dm-linear"
|
||||
echo "# (logical_block_size=512, physical_block_size=512, alignment_offset=0)"
|
||||
add_device dev_size_mb=16 sector_size=512 num_tgts=1
|
||||
DEV2=$DEV
|
||||
DEV=/dev/mapper/$DEV_STACKED
|
||||
dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0"
|
||||
format $EXPCT
|
||||
format $EXPCT s1024
|
||||
format $EXPCT s2048
|
||||
format $EXPCT s4096
|
||||
format $EXPCT 1
|
||||
format $EXPCT 1 s1024
|
||||
format $EXPCT 1 s2048
|
||||
format $EXPCT 1 s4096
|
||||
format $EXPCT 8
|
||||
format $EXPCT 8 s1024
|
||||
format $EXPCT 8 s2048
|
||||
format $EXPCT 8 s4096
|
||||
format $((EXPCT+1)) $((EXPCT+1))
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
|
||||
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
|
||||
format $EXPCT $EXPCT
|
||||
format $EXPCT $EXPCT s1024
|
||||
format $EXPCT $EXPCT s2048
|
||||
format $EXPCT $EXPCT s4096
|
||||
cleanup
|
||||
|
||||
echo "# Create enterprise-class 4K drive with fs and LUKS images."
|
||||
# loop device here presents 512 block but images have 4k block
|
||||
# cryptsetup should properly use 4k block on direct-io
|
||||
add_device dev_size_mb=32 sector_size=4096 physblk_exp=0 num_tgts=1 opt_blks=64
|
||||
for file in $(ls img_fs_*.img.xz) ; do
|
||||
echo "Format using fs image $file."
|
||||
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
|
||||
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
|
||||
mount $DEV $MNT_DIR || skip "Mounting image is not available."
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
|
||||
umount $MNT_DIR
|
||||
done
|
||||
cleanup
|
||||
@@ -354,7 +354,7 @@ static int _setup(void)
|
||||
fd = loop_attach(&DEVICE_6, IMAGE_PV_LUKS2_SEC, 0, 0, &ro);
|
||||
close(fd);
|
||||
|
||||
_system(" [ ! -d " CONV_DIR " ] && tar xJf " CONV_DIR ".tar.xz", 1);
|
||||
_system(" [ ! -d " CONV_DIR " ] && tar xJf " CONV_DIR ".tar.xz 2>/dev/null", 1);
|
||||
|
||||
if (_system("modprobe dm-crypt", 1))
|
||||
return 1;
|
||||
@@ -426,13 +426,11 @@ static int test_open(struct crypt_device *cd,
|
||||
void *usrptr)
|
||||
{
|
||||
const char *str = (const char *)usrptr;
|
||||
char *buf = malloc(strlen(str));
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
strncpy(buf, str, strlen(str));
|
||||
*buffer = buf;
|
||||
*buffer_len = strlen(str);
|
||||
*buffer = strdup(str);
|
||||
if (!*buffer)
|
||||
return -ENOMEM;
|
||||
*buffer_len = strlen(*buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -868,6 +866,7 @@ static void UseTempVolumes(void)
|
||||
|
||||
static void Luks2HeaderRestore(void)
|
||||
{
|
||||
char key[128];
|
||||
struct crypt_device *cd;
|
||||
struct crypt_pbkdf_type pbkdf = {
|
||||
.type = CRYPT_KDF_ARGON2I,
|
||||
@@ -890,7 +889,7 @@ static void Luks2HeaderRestore(void)
|
||||
struct crypt_params_luks1 luks1 = {
|
||||
.data_alignment = 8192, // 4M offset to pass alignment test
|
||||
};
|
||||
char key[128];
|
||||
uint32_t flags = 0;
|
||||
|
||||
const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
|
||||
size_t key_size = strlen(mk_hex) / 2;
|
||||
@@ -945,6 +944,22 @@ static void Luks2HeaderRestore(void)
|
||||
FAIL_(crypt_header_restore(cd, CRYPT_LUKS2, NO_REQS_LUKS2_HEADER), "LUKS1 format detected");
|
||||
crypt_free(cd);
|
||||
|
||||
/* check crypt_header_restore() properly loads crypt_device context */
|
||||
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
|
||||
OK_(crypt_header_restore(cd, CRYPT_LUKS2, NO_REQS_LUKS2_HEADER));
|
||||
/* check LUKS2 specific API call returns non-error code */
|
||||
OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags));
|
||||
EQ_(flags, 0);
|
||||
/* same test, any LUKS */
|
||||
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
|
||||
OK_(crypt_header_restore(cd, CRYPT_LUKS, NO_REQS_LUKS2_HEADER));
|
||||
/* check LUKS2 specific API call returns non-error code */
|
||||
OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags));
|
||||
EQ_(flags, 0);
|
||||
|
||||
crypt_free(cd);
|
||||
|
||||
_cleanup_dmdevices();
|
||||
}
|
||||
|
||||
@@ -2254,9 +2269,8 @@ static void Pbkdf(void)
|
||||
bad.type = NULL;
|
||||
bad.hash = DEFAULT_LUKS1_HASH;
|
||||
FAIL_(crypt_set_pbkdf_type(cd, &bad), "Pbkdf type member is empty");
|
||||
// following test fails atm
|
||||
// bad.hash = "hamster_hash";
|
||||
// FAIL_(crypt_set_pbkdf_type(cd, &pbkdf2), "Unknown hash member");
|
||||
bad.hash = "hamster_hash";
|
||||
FAIL_(crypt_set_pbkdf_type(cd, &pbkdf2), "Unknown hash member");
|
||||
crypt_free(cd);
|
||||
// test whether crypt_get_pbkdf_type() behaves accordingly after second crypt_load() call
|
||||
OK_(crypt_init(&cd, DEVICE_1));
|
||||
@@ -2974,23 +2988,23 @@ int main(int argc, char *argv[])
|
||||
crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
|
||||
|
||||
RUN_(AddDeviceLuks2, "Format and use LUKS2 device");
|
||||
RUN_(Luks2HeaderLoad, "test header load");
|
||||
RUN_(Luks2HeaderRestore, "test LUKS2 header restore");
|
||||
RUN_(Luks2HeaderBackup, "test LUKS2 header backup");
|
||||
RUN_(ResizeDeviceLuks2, "Luks device resize tests");
|
||||
RUN_(Luks2HeaderLoad, "LUKS2 header load");
|
||||
RUN_(Luks2HeaderRestore, "LUKS2 header restore");
|
||||
RUN_(Luks2HeaderBackup, "LUKS2 header backup");
|
||||
RUN_(ResizeDeviceLuks2, "LUKS2 device resize tests");
|
||||
RUN_(UseLuks2Device, "Use pre-formated LUKS2 device");
|
||||
RUN_(SuspendDevice, "Suspend/Resume test");
|
||||
RUN_(SuspendDevice, "LUKS2 Suspend/Resume");
|
||||
RUN_(UseTempVolumes, "Format and use temporary encrypted device");
|
||||
RUN_(Tokens, "General tokens API tests");
|
||||
RUN_(TokenActivationByKeyring, "Builtin kernel keyring token tests");
|
||||
RUN_(LuksConvert, "Test LUKS1 <-> LUKS2 conversions");
|
||||
RUN_(Pbkdf, "Exercice default pbkdf manipulation routines");
|
||||
RUN_(Luks2KeyslotAdd, "Add new keyslot by unused key");
|
||||
RUN_(Luks2ActivateByKeyring, "Test LUKS2 activation by passphrase in keyring");
|
||||
RUN_(Luks2Requirements, "Test LUKS2 requirements flags");
|
||||
RUN_(Luks2Integrity, "Test LUKS2 with data integrity");
|
||||
RUN_(Luks2Flags, "Test LUKS2 persistent flags");
|
||||
RUN_(Luks2Repair, "Test LUKS2 repair"); // test disables metadata locking. Run alwas last!
|
||||
RUN_(Tokens, "General tokens API");
|
||||
RUN_(TokenActivationByKeyring, "Builtin kernel keyring token");
|
||||
RUN_(LuksConvert, "LUKS1 <-> LUKS2 conversions");
|
||||
RUN_(Pbkdf, "Default PBKDF manipulation routines");
|
||||
RUN_(Luks2KeyslotAdd, "Add a new keyslot by unused key");
|
||||
RUN_(Luks2ActivateByKeyring, "LUKS2 activation by passphrase in keyring");
|
||||
RUN_(Luks2Requirements, "LUKS2 requirements flags");
|
||||
RUN_(Luks2Integrity, "LUKS2 with data integrity");
|
||||
RUN_(Luks2Flags, "LUKS2 persistent flags");
|
||||
RUN_(Luks2Repair, "LUKS2 repair"); // test disables metadata locking. Run always last!
|
||||
out:
|
||||
_cleanup();
|
||||
return 0;
|
||||
|
||||
@@ -100,14 +100,18 @@ static int get_luks_offsets(int metadata_device,
|
||||
uint64_t current_sector;
|
||||
uint32_t sectors_per_stripes_set;
|
||||
|
||||
if (!keylength)
|
||||
if (!keylength) {
|
||||
if (r_header_size)
|
||||
*r_header_size = 0;
|
||||
if (r_payload_offset)
|
||||
*r_payload_offset = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sectors_per_stripes_set = DIV_ROUND_UP(keylength*LUKS_STRIPES, SECTOR_SIZE);
|
||||
printf("sectors_per_stripes %" PRIu32 "\n", sectors_per_stripes_set);
|
||||
current_sector = DIV_ROUND_UP_MODULO(DIV_ROUND_UP(LUKS_PHDR_SIZE_B, SECTOR_SIZE),
|
||||
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
for(i=0;i < (LUKS_NUMKEYS - 1);i++)
|
||||
for (i=0; i < (LUKS_NUMKEYS - 1); i++)
|
||||
current_sector = DIV_ROUND_UP_MODULO(current_sector + sectors_per_stripes_set,
|
||||
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
if (r_header_size)
|
||||
@@ -255,7 +259,7 @@ static int _setup(void)
|
||||
_system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"", 1);
|
||||
_system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1);
|
||||
|
||||
_system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1);
|
||||
_system(" [ ! -e " IMAGE1 " ] && xz -dk " IMAGE1 ".xz", 1);
|
||||
fd = loop_attach(&DEVICE_1, IMAGE1, 0, 0, &ro);
|
||||
close(fd);
|
||||
|
||||
@@ -264,22 +268,22 @@ static int _setup(void)
|
||||
close(fd);
|
||||
|
||||
/* Keymaterial offset is less than 8 sectors */
|
||||
_system(" [ ! -e " EVL_HEADER_1 " ] && bzip2 -dk " EVL_HEADER_1 ".bz2", 1);
|
||||
_system(" [ ! -e " EVL_HEADER_1 " ] && xz -dk " EVL_HEADER_1 ".xz", 1);
|
||||
/* keymaterial offset aims into payload area */
|
||||
_system(" [ ! -e " EVL_HEADER_2 " ] && bzip2 -dk " EVL_HEADER_2 ".bz2", 1);
|
||||
_system(" [ ! -e " EVL_HEADER_2 " ] && xz -dk " EVL_HEADER_2 ".xz", 1);
|
||||
/* keymaterial offset is valid, number of stripes causes payload area to be overwritten */
|
||||
_system(" [ ! -e " EVL_HEADER_3 " ] && bzip2 -dk " EVL_HEADER_3 ".bz2", 1);
|
||||
_system(" [ ! -e " EVL_HEADER_3 " ] && xz -dk " EVL_HEADER_3 ".xz", 1);
|
||||
/* luks device header for data and header on same device. payloadOffset is greater than
|
||||
* device size (crypt_load() test) */
|
||||
_system(" [ ! -e " EVL_HEADER_4 " ] && bzip2 -dk " EVL_HEADER_4 ".bz2", 1);
|
||||
_system(" [ ! -e " EVL_HEADER_4 " ] && xz -dk " EVL_HEADER_4 ".xz", 1);
|
||||
/* two keyslots with same offset (overlapping keyslots) */
|
||||
_system(" [ ! -e " EVL_HEADER_5 " ] && bzip2 -dk " EVL_HEADER_5 ".bz2", 1);
|
||||
_system(" [ ! -e " EVL_HEADER_5 " ] && xz -dk " EVL_HEADER_5 ".xz", 1);
|
||||
/* valid header: payloadOffset=4096, key_size=32,
|
||||
* volume_key = bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a */
|
||||
_system(" [ ! -e " VALID_HEADER " ] && bzip2 -dk " VALID_HEADER ".bz2", 1);
|
||||
_system(" [ ! -e " VALID_HEADER " ] && xz -dk " VALID_HEADER ".xz", 1);
|
||||
|
||||
/* Prepare tcrypt images */
|
||||
_system(" [ ! -d tcrypt-images ] && tar xjf tcrypt-images.tar.bz2 2>/dev/null", 1);
|
||||
_system(" [ ! -d tcrypt-images ] && tar xJf tcrypt-images.tar.xz 2>/dev/null", 1);
|
||||
|
||||
_system("modprobe dm-crypt", 0);
|
||||
_system("modprobe dm-verity", 0);
|
||||
@@ -1072,6 +1076,18 @@ static void LuksHeaderRestore(void)
|
||||
//_system("dmsetup table;sleep 1",1);
|
||||
crypt_free(cd);
|
||||
|
||||
/* check crypt_header_restore() properly loads crypt_device context */
|
||||
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
|
||||
OK_(crypt_header_restore(cd, CRYPT_LUKS1, VALID_HEADER));
|
||||
OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
|
||||
/* same test, any LUKS */
|
||||
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
|
||||
OK_(crypt_header_restore(cd, CRYPT_LUKS, VALID_HEADER));
|
||||
OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
|
||||
|
||||
crypt_free(cd);
|
||||
|
||||
_cleanup_dmdevices();
|
||||
}
|
||||
|
||||
@@ -1762,20 +1778,20 @@ int main(int argc, char *argv[])
|
||||
crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
|
||||
|
||||
RUN_(NonFIPSAlg, "Crypto is properly initialised in format"); //must be the first!
|
||||
RUN_(AddDevicePlain, "plain device API creation exercise");
|
||||
RUN_(HashDevicePlain, "plain device API hash test");
|
||||
RUN_(AddDevicePlain, "A plain device API creation");
|
||||
RUN_(HashDevicePlain, "A plain device API hash");
|
||||
RUN_(AddDeviceLuks, "Format and use LUKS device");
|
||||
RUN_(LuksHeaderLoad, "test header load");
|
||||
RUN_(LuksHeaderRestore, "test LUKS header restore");
|
||||
RUN_(LuksHeaderBackup, "test LUKS header backup");
|
||||
RUN_(ResizeDeviceLuks, "Luks device resize tests");
|
||||
RUN_(LuksHeaderLoad, "Header load");
|
||||
RUN_(LuksHeaderRestore, "LUKS header restore");
|
||||
RUN_(LuksHeaderBackup, "LUKS header backup");
|
||||
RUN_(ResizeDeviceLuks, "LUKS device resize");
|
||||
RUN_(UseLuksDevice, "Use pre-formated LUKS device");
|
||||
RUN_(SuspendDevice, "Suspend/Resume test");
|
||||
RUN_(SuspendDevice, "Suspend/Resume");
|
||||
RUN_(UseTempVolumes, "Format and use temporary encrypted device");
|
||||
RUN_(CallbacksTest, "API callbacks test");
|
||||
RUN_(VerityTest, "DM verity test");
|
||||
RUN_(TcryptTest, "Tcrypt API test");
|
||||
RUN_(IntegrityTest, "Integrity API test");
|
||||
RUN_(CallbacksTest, "API callbacks");
|
||||
RUN_(VerityTest, "DM verity");
|
||||
RUN_(TcryptTest, "Tcrypt API");
|
||||
RUN_(IntegrityTest, "Integrity API");
|
||||
out:
|
||||
_cleanup();
|
||||
return 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
BW_UNIT=./unit-utils-io
|
||||
STRACE=strace
|
||||
MNT_DIR=./mnt_bwunit
|
||||
LOCAL_FILE=./blocwise_localfile
|
||||
LOCAL_FILE=./blockwise_localfile
|
||||
|
||||
# $1 path to scsi debug bdev
|
||||
scsi_debug_teardown() {
|
||||
@@ -42,10 +42,16 @@ fail()
|
||||
|
||||
fail_count()
|
||||
{
|
||||
echo "[WRONG]"
|
||||
echo "$MSG[FAIL]"
|
||||
FAILS=$((FAILS+1))
|
||||
}
|
||||
|
||||
warn_count()
|
||||
{
|
||||
echo "$MSG[WARNING]"
|
||||
WARNS=$((WARNS+1))
|
||||
}
|
||||
|
||||
skip()
|
||||
{
|
||||
echo "TEST SKIPPED: $1"
|
||||
@@ -54,7 +60,7 @@ skip()
|
||||
}
|
||||
|
||||
add_device() {
|
||||
modprobe scsi_debug $@
|
||||
modprobe scsi_debug $@ delay=0
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "This kernel seems to not support proper scsi_debug module, test skipped."
|
||||
exit 77
|
||||
@@ -65,15 +71,19 @@ add_device() {
|
||||
}
|
||||
|
||||
falloc() {
|
||||
fallocate -l"$1"m $2 2>/dev/null || dd if=/dev/zero of=$2 bs=1M count=$1 2> /dev/null
|
||||
dd if=/dev/zero of=$2 bs=1M count=$1 2> /dev/null
|
||||
}
|
||||
|
||||
run_all_in_fs() {
|
||||
for file in $(ls img_fs_*.img.bz2) ; do
|
||||
for file in $(ls img_fs_*.img.xz) ; do
|
||||
echo "Run tests in $file put on top block device."
|
||||
bzip2 -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
|
||||
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
|
||||
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
|
||||
mount $DEV $MNT_DIR || skip "Mounting image $file failed."
|
||||
mount $DEV $MNT_DIR
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Mounting image $file failed, skipped."
|
||||
continue;
|
||||
fi
|
||||
rm -rf $MNT_DIR/* 2>/dev/null
|
||||
local tfile=$MNT_DIR/bwunit_tstfile
|
||||
falloc $DEVSIZEMB $tfile || fail "enospc?"
|
||||
@@ -108,25 +118,33 @@ RUN() {
|
||||
|
||||
case "$_res" in
|
||||
P)
|
||||
echo -n "Testing $_fn on $_type with params $@ [should PASS]..."
|
||||
MSG="Testing $_fn on $_type with params $@ [expecting TRUE]..."
|
||||
$BW_UNIT $_dev $_fn $@
|
||||
if [ $? -ne 0 ]; then
|
||||
fail_count
|
||||
if [ $_type = "file" ]; then
|
||||
warn_count
|
||||
else
|
||||
fail_count
|
||||
fi
|
||||
trunc_file $_fsize $_dev
|
||||
test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-pass.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
|
||||
else
|
||||
echo "[OK]"
|
||||
MSG="$MSG[OK]"
|
||||
fi
|
||||
;;
|
||||
F)
|
||||
echo -n "Testing $_fn on $_type with params $@ [should FAIL]..."
|
||||
MSG="Testing $_fn on $_type with params $@ [expecting FALSE]..."
|
||||
$BW_UNIT $_dev $_fn $@ 2> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
fail_count
|
||||
if [ $_type = "file" ]; then
|
||||
warn_count
|
||||
else
|
||||
fail_count
|
||||
fi
|
||||
trunc_file $_fsize $_dev
|
||||
test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-fail.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
|
||||
else
|
||||
echo "[OK]"
|
||||
MSG="$MSG[OK]"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@@ -290,6 +308,7 @@ which $STRACE > /dev/null 2>&1 || unset STRACE
|
||||
test -x $BW_UNIT || skip "Run \"make `basename $BW_UNIT`\" first"
|
||||
|
||||
FAILS=0
|
||||
WARNS=0
|
||||
DEVSIZEMB=2
|
||||
DEVSIZE=$((DEVSIZEMB*1024*1024))
|
||||
|
||||
@@ -299,16 +318,12 @@ echo "System PAGE_SIZE=$PAGE_SIZE"
|
||||
echo "Run tests in local filesystem"
|
||||
falloc $DEVSIZEMB $LOCAL_FILE || fail "Failed to create file in local filesystem."
|
||||
BSIZE=$(stat -c "%o" $LOCAL_FILE)
|
||||
if [ $BSIZE -gt $PAGE_SIZE ]; then
|
||||
if [ $BSIZE -gt $((512*1024)) ]; then
|
||||
echo "Detected file block size: $BSIZE bytes"
|
||||
if [ -n "$_FORCE_LOCAL" ]; then
|
||||
run_all $LOCAL_FILE
|
||||
else
|
||||
echo "Nfs? I'm not going to run blockwise tests on this."
|
||||
fi
|
||||
else
|
||||
run_all $LOCAL_FILE
|
||||
echo "Tuning it down to system page size ($PAGE_SIZE bytes)"
|
||||
BSIZE=$PAGE_SIZE
|
||||
fi
|
||||
run_all $LOCAL_FILE
|
||||
|
||||
[ $(id -u) -eq 0 ] || {
|
||||
echo "WARNING: You must be root to run remaining tests."
|
||||
@@ -356,4 +371,5 @@ add_device dev_size_mb=$DEVSIZEMBIMG sector_size=$DEVBSIZE physblk_exp=$EXP num_
|
||||
run_all_in_fs
|
||||
cleanup
|
||||
|
||||
test $WARNS -eq 0 || echo "(WARNING: $WARNS suspicious result(s) in total)"
|
||||
test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"
|
||||
|
||||
@@ -104,19 +104,19 @@ function prepare()
|
||||
;;
|
||||
new)
|
||||
remove_mapping
|
||||
bzip2 -cd compatimage.img.bz2 > $IMG
|
||||
xz -cd compatimage.img.xz > $IMG
|
||||
# FIXME: switch to internal loop (no losetup at all)
|
||||
echo "bad" | $CRYPTSETUP luksOpen --key-slot 0 --test-passphrase $IMG 2>&1 | \
|
||||
grep "autoclear flag" && skip "WARNING: Too old kernel, test skipped."
|
||||
losetup $LOOPDEV $IMG
|
||||
bzip2 -cd compatv10image.img.bz2 > $IMG10
|
||||
xz -cd compatv10image.img.xz > $IMG10
|
||||
;;
|
||||
reuse | *)
|
||||
if [ ! -e $IMG ]; then
|
||||
bzip2 -cd compatimage.img.bz2 > $IMG
|
||||
xz -cd compatimage.img.xz > $IMG
|
||||
losetup $LOOPDEV $IMG
|
||||
fi
|
||||
[ ! -e $IMG10 ] && bzip2 -cd compatv10image.img.bz2 > $IMG10
|
||||
[ ! -e $IMG10 ] && xz -cd compatv10image.img.xz > $IMG10
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -138,10 +138,6 @@ function prepare()
|
||||
touch $KEYE
|
||||
fi
|
||||
|
||||
if [ ! -e $VK_FILE ]; then
|
||||
touch $VK_FILE
|
||||
fi
|
||||
|
||||
cp $IMG $ORIG_IMG
|
||||
[ -n "$1" ] && echo "CASE: $1"
|
||||
}
|
||||
@@ -241,8 +237,8 @@ $CRYPTSETUP luksDump $IMG | grep -q $TEST_UUID || fail
|
||||
echo $PWDW | $CRYPTSETUP luksDump $IMG --dump-master-key 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksDump $IMG --dump-master-key | grep -q "MK dump:" || can_fail_fips
|
||||
$CRYPTSETUP luksDump -q $IMG --dump-master-key -d $KEY1 | grep -q "MK dump:" || can_fail_fips
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file missing-file 2> /dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE > /dev/null || can_fail_fips
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE >/dev/null || can_fail_fips
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail
|
||||
fips_mode || {
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $IMG || fail
|
||||
}
|
||||
@@ -853,7 +849,7 @@ prepare "[37] Interactive add key." new
|
||||
expect - >/dev/null <<EOF
|
||||
proc abort {} { send_error "Timeout. "; exit 2 }
|
||||
set timeout 10
|
||||
eval spawn $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -v $LOOPDEV
|
||||
eval spawn $CRYPTSETUP luksAddKey -S 2 $FAST_PBKDF_OPT -v $LOOPDEV
|
||||
expect timeout abort "Enter any existing passphrase:"
|
||||
sleep 0.1
|
||||
send "$PWD0\n"
|
||||
@@ -871,6 +867,15 @@ sleep 0.1
|
||||
send "$PWD1\n"
|
||||
expect timeout abort "Command successful."
|
||||
expect timeout abort eof
|
||||
eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 1
|
||||
expect timeout abort "Keyslot 1 is not active."
|
||||
expect timeout abort eof
|
||||
eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 2
|
||||
expect timeout abort "Enter any remaining passphrase:"
|
||||
sleep 0.1
|
||||
send "$PWD0\n"
|
||||
expect timeout abort "Key slot 2 removed."
|
||||
expect timeout abort eof
|
||||
exit
|
||||
EOF
|
||||
[ $? -eq 0 ] || fail "Expect script failed."
|
||||
|
||||
@@ -23,11 +23,15 @@ PWD0="compatkey"
|
||||
PWD1="93R4P4pIqAH8"
|
||||
PWD2="mymJeD8ivEhE"
|
||||
PWD3="ocMakf3fAcQO"
|
||||
PWD4="Qx3qn46vq0v"
|
||||
PWDW="rUkL4RUryBom"
|
||||
TEST_KEYRING_NAME="compattest2_keyring"
|
||||
TEST_TOKEN0="compattest2_desc0"
|
||||
TEST_TOKEN1="compattest2_desc1"
|
||||
VK_FILE="compattest2_vkfile"
|
||||
IMPORT_TOKEN="{\"type\":\"some_type\",\"keyslots\":[],\"base64_data\":\"zxI7vKB1Qwl4VPB4D-N-OgcC14hPCG0IDu8O7eCqaQ\"}"
|
||||
TOKEN_FILE0=test-token-file0
|
||||
TOKEN_FILE1=test-token-file1
|
||||
|
||||
FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
|
||||
|
||||
@@ -47,7 +51,7 @@ function remove_mapping()
|
||||
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
|
||||
losetup -d $LOOPDEV >/dev/null 2>&1
|
||||
rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE $HEADER_LUKS2_PV missing-file >/dev/null 2>&1
|
||||
rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE $HEADER_LUKS2_PV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* >/dev/null 2>&1
|
||||
|
||||
# unlink whole test keyring
|
||||
[ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
|
||||
@@ -93,26 +97,26 @@ function prepare()
|
||||
case "$2" in
|
||||
wipe)
|
||||
remove_mapping
|
||||
dd if=/dev/zero of=$IMG bs=1k count=10000 >/dev/null 2>&1
|
||||
dd if=/dev/zero of=$IMG bs=4096 count=5000 >/dev/null 2>&1
|
||||
sync
|
||||
losetup $LOOPDEV $IMG
|
||||
;;
|
||||
new)
|
||||
remove_mapping
|
||||
bzip2 -cd compatimage.img.bz2 > $IMG
|
||||
xz -cd compatimage.img.xz > $IMG
|
||||
xz -dk $HEADER_KEYU.xz
|
||||
# FIXME: switch to internal loop (no losetup at all)
|
||||
echo "bad" | $CRYPTSETUP luksOpen --key-slot 0 --test-passphrase $IMG 2>&1 | \
|
||||
grep "autoclear flag" && skip "WARNING: Too old kernel, test skipped."
|
||||
losetup $LOOPDEV $IMG
|
||||
bzip2 -cd compatv10image.img.bz2 > $IMG10
|
||||
xz -cd compatv10image.img.xz > $IMG10
|
||||
;;
|
||||
reuse | *)
|
||||
if [ ! -e $IMG ]; then
|
||||
bzip2 -cd compatimage.img.bz2 > $IMG
|
||||
xz -cd compatimage.img.xz > $IMG
|
||||
losetup $LOOPDEV $IMG
|
||||
fi
|
||||
[ ! -e $IMG10 ] && bzip2 -cd compatv10image.img.bz2 > $IMG10
|
||||
[ ! -e $IMG10 ] && xz -cd compatv10image.img.xz > $IMG10
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -134,10 +138,6 @@ function prepare()
|
||||
touch $KEYE
|
||||
fi
|
||||
|
||||
if [ ! -e $VK_FILE ]; then
|
||||
touch $VK_FILE
|
||||
fi
|
||||
|
||||
cp $IMG $ORIG_IMG
|
||||
[ -n "$1" ] && echo "CASE: $1"
|
||||
}
|
||||
@@ -209,7 +209,21 @@ export LANG=C
|
||||
[ -z "$LOOPDEV" ] && skip "WARNING: Cannot find free loop device, test skipped."
|
||||
[ -d "$LOCK_DIR" ] || skip "WARNING: LUKS2 locking directory ($LOCK_DIR) is missing, test skipped."
|
||||
|
||||
# LUKS tests
|
||||
prepare "[2] Sector size and old payload alignment" wipe
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 511 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 256 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 8192 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 512 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --align-payload 5 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 512 --align-payload 5 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 2048 --align-payload 32 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 4096 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 2048 --align-payload 32768 || fail
|
||||
$CRYPTSETUP -q luksDump $LOOPDEV | grep -q "offset: $((512 * 32768)) \[bytes\]" || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 2048 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 4096 --align-payload 32768 || fail
|
||||
$CRYPTSETUP -q luksDump $LOOPDEV | grep -q "offset: $((512 * 32768)) \[bytes\]" || fail
|
||||
|
||||
prepare "[3] format" new
|
||||
echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 $LOOPDEV || fail
|
||||
prepare "[4] format using hash sha512" wipe
|
||||
@@ -398,7 +412,7 @@ $CRYPTSETUP -q status $DEV_NAME | grep "mode:" | grep -q "readonly" || fail
|
||||
$CRYPTSETUP -q resize $DEV_NAME --size 100 || fail
|
||||
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail
|
||||
$CRYPTSETUP -q resize $DEV_NAME || fail
|
||||
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "19997 sectors" || fail
|
||||
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "39997 sectors" || fail
|
||||
# Resize underlying loop device as well
|
||||
truncate -s 16M $IMG || fail
|
||||
$CRYPTSETUP -q resize $DEV_NAME || fail
|
||||
@@ -460,18 +474,18 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q $TEST_UUID || fail
|
||||
echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key | grep -q "MK dump:" || can_fail_fips
|
||||
$CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" || can_fail_fips
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file missing-file 2> /dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE > /dev/null || can_fail_fips
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE >/dev/null || can_fail_fips
|
||||
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail
|
||||
fips_mode || {
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $LOOPDEV || fail
|
||||
}
|
||||
|
||||
prepare "[22] remove disappeared device" wipe
|
||||
dmsetup create $DEV_NAME --table "0 10000 linear $LOOPDEV 2" || fail
|
||||
dmsetup create $DEV_NAME --table "0 39998 linear $LOOPDEV 2" || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 /dev/mapper/$DEV_NAME || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksOpen /dev/mapper/$DEV_NAME $DEV_NAME2 || fail
|
||||
# underlying device now returns error but node is still present
|
||||
dmsetup load $DEV_NAME --table "0 10000 error" || fail
|
||||
dmsetup load $DEV_NAME --table "0 40000 error" || fail
|
||||
dmsetup resume $DEV_NAME || fail
|
||||
$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
|
||||
dmsetup remove $DEV_NAME || fail
|
||||
@@ -673,7 +687,7 @@ if dm_crypt_keyring_flawed; then
|
||||
fi
|
||||
|
||||
if dm_crypt_keyring_support; then
|
||||
prepare "[32b] LUKS2 key in keyring" wipe
|
||||
prepare "[32] LUKS2 key in keyring" wipe
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || fail
|
||||
# check keyring support detection works as expected
|
||||
rmmod dm-crypt > /dev/null 2>&1 || true
|
||||
@@ -699,12 +713,12 @@ if dm_crypt_keyring_support; then
|
||||
fi
|
||||
|
||||
# FIXME: candidate for non-root tests
|
||||
prepare "[33] tokens" wipe
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail
|
||||
if [ $HAVE_KEYRING -gt 0 ]; then
|
||||
prepare "[33] tokens" wipe
|
||||
|
||||
test_and_prepare_keyring
|
||||
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail
|
||||
$CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN0 --token-id 3 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q -e "3: luks2-keyring" || fail
|
||||
# keyslot 5 is inactive
|
||||
@@ -727,6 +741,18 @@ if [ $HAVE_KEYRING -gt 0 ]; then
|
||||
$CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN1 --key-slot 4 || fail
|
||||
$CRYPTSETUP -q luksKillSlot $LOOPDEV 4 || fail
|
||||
fi
|
||||
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 10 || fail
|
||||
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 11 --json-file - || fail
|
||||
echo -n "$IMPORT_TOKEN" > $TOKEN_FILE0
|
||||
$CRYPTSETUP token import $LOOPDEV --token-id 12 --json-file $TOKEN_FILE0 || fail
|
||||
$CRYPTSETUP token import $LOOPDEV --token-id 12 --json-file $TOKEN_FILE0 2>/dev/null && fail
|
||||
$CRYPTSETUP token export $LOOPDEV --token-id 10 | diff --from-file - $TOKEN_FILE0 || fail
|
||||
$CRYPTSETUP token export $LOOPDEV --token-id 11 | diff --from-file - $TOKEN_FILE0 || fail
|
||||
$CRYPTSETUP token export $LOOPDEV --token-id 12 | diff --from-file - $TOKEN_FILE0 || fail
|
||||
$CRYPTSETUP token export $LOOPDEV --token-id 12 --json-file $TOKEN_FILE1 || fail
|
||||
diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
|
||||
$CRYPTSETUP token export $LOOPDEV --token-id 12 > $TOKEN_FILE1 || fail
|
||||
diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
|
||||
|
||||
prepare "[34] LUKS keyslot priority" wipe
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -S 1 || fail
|
||||
@@ -763,7 +789,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 1234 $LOOPDEV || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep "Iterations:" | grep -q "1234" || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 3 $LOOPDEV 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 4 $LOOPDEV || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 4 --pbkdf-memory 100000 $LOOPDEV || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "argon2id" || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2i --pbkdf-force-iterations 4 \
|
||||
--pbkdf-memory 1234 --pbkdf-parallel 1 $LOOPDEV || fail
|
||||
@@ -780,7 +806,7 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf pbkdf2 -i 500 $LOOPD
|
||||
|
||||
prepare "[37] LUKS Keyslot convert" wipe
|
||||
$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks1 $LOOPDEV $KEY5 --key-slot 5 || fail
|
||||
$CRYPTSETUP -q luksConvertKey $LOOPDEV --key-file $KEY5 && fail
|
||||
$CRYPTSETUP -q luksConvertKey $LOOPDEV --key-file $KEY5 2>/dev/null && fail
|
||||
$CRYPTSETUP -q convert --type luks2 $LOOPDEV || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "pbkdf2" || fail
|
||||
@@ -792,6 +818,8 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "pbkdf2" || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksConvertKey $LOOPDEV -S 1 --pbkdf argon2i -i1 --pbkdf-memory 32 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail
|
||||
echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 21 --unbound -s 16 $LOOPDEV || fail
|
||||
echo $PWD3 | $CRYPTSETUP luksConvertKey --pbkdf-force-iterations 1001 --pbkdf pbkdf2 -S 21 $LOOPDEV || fail
|
||||
|
||||
prepare "[38] luksAddKey unbound tests" wipe
|
||||
$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY5 --key-slot 5 || fail
|
||||
@@ -812,8 +840,12 @@ echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV --test-passphrase || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail
|
||||
# check we're able to change passphrase for unbound keyslot
|
||||
echo -e "$PWD2\n$PWD3" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail
|
||||
echo $PWD3 | $CRYPTSETUP open --test-passphrase $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail
|
||||
echo $PWD3 | $CRYPTSETUP -q open -S 2 $LOOPDEV $DEV_NAME 2> /dev/null && fail
|
||||
# do not allow adding keyslot by unbound keyslot
|
||||
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $LOOPDEV 2> /dev/null && fail
|
||||
echo -e "$PWD3\n$PWD1" | $CRYPTSETUP -q luksAddKey $LOOPDEV 2> /dev/null && fail
|
||||
# check adding keyslot works when there's unbound keyslot
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --key-file $KEY5 -S8 || fail
|
||||
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail
|
||||
@@ -823,5 +855,21 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2 (unbound)" && fail
|
||||
$CRYPTSETUP luksKillSlot -q $LOOPDEV 3
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" && fail
|
||||
|
||||
prepare "[39] LUKS2 metadata variants" wipe
|
||||
tar xJf luks2_mda_images.tar.xz
|
||||
echo -n "$IMPORT_TOKEN" > $TOKEN_FILE0
|
||||
for mda in 16 32 64 128 256 512 1024 2048 4096 ; do
|
||||
echo -n "[$mda KiB]"
|
||||
echo $PWD4 | $CRYPTSETUP open test_image_$mda $DEV_NAME || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
echo -e "$PWD4\n$PWD3" | $CRYPTSETUP luksAddKey -S9 $FAST_PBKDF_OPT test_image_$mda || fail
|
||||
echo $PWD4 | $CRYPTSETUP open --test-passphrase test_image_$mda || fail
|
||||
echo $PWD3 | $CRYPTSETUP open -S9 --test-passphrase test_image_$mda || fail
|
||||
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import test_image_$mda --token-id 10 || fail
|
||||
$CRYPTSETUP token export test_image_$mda --token-id 10 | diff --from-file - $TOKEN_FILE0 || fail
|
||||
echo -n "[OK]"
|
||||
done
|
||||
echo
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
Binary file not shown.
BIN
tests/compatimage.img.xz
Normal file
BIN
tests/compatimage.img.xz
Normal file
Binary file not shown.
Binary file not shown.
BIN
tests/compatv10image.img.xz
Normal file
BIN
tests/compatv10image.img.xz
Normal file
Binary file not shown.
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#define MAX_BLOCK_SIZE 128
|
||||
|
||||
static void printhex(const char *s, const char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
@@ -237,6 +239,10 @@ struct kdf_test_vector kdf_test_vectors[] = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Hash tests
|
||||
*/
|
||||
|
||||
struct hash_alg {
|
||||
const char *name;
|
||||
int length;
|
||||
@@ -333,6 +339,69 @@ struct hash_out hash_outputs[] = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* HMAC tests
|
||||
*/
|
||||
// RFC 4231 - HMAC test vectors for SHA-256, SHA-512
|
||||
// RFC 2202 - HMAC test vectors for SHA-1
|
||||
|
||||
struct hmac_test_vector {
|
||||
const char *key;
|
||||
unsigned int key_length;
|
||||
const char *data;
|
||||
unsigned int data_length;
|
||||
const char *hmac_sha_1;
|
||||
const char *hmac_sha_256;
|
||||
const char *hmac_sha_512;
|
||||
};
|
||||
|
||||
struct hmac_test_vector hmac_test_vectors[] = {
|
||||
{
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20,
|
||||
"\x48\x69\x20\x54\x68\x65\x72\x65", 8, // "Hi There"
|
||||
"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00",
|
||||
"\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7",
|
||||
"\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54"
|
||||
},
|
||||
{
|
||||
"\x4a\x65\x66\x65", 4, // "Jefe"
|
||||
"\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f", 28, // "what do ya want for nothing?"
|
||||
"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
|
||||
"\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43",
|
||||
"\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37"
|
||||
},
|
||||
{
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20,
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50,
|
||||
"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3",
|
||||
"\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe",
|
||||
"\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb"
|
||||
},
|
||||
{
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", 50,
|
||||
"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda",
|
||||
"\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b",
|
||||
"\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd"
|
||||
},
|
||||
{
|
||||
// Long key
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131,
|
||||
"\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 54, // "Test Using Larger Than Block-Size Key - Hash Key First"
|
||||
"\x90\xd0\xda\xce\x1c\x1b\xdc\x95\x73\x39\x30\x78\x03\x16\x03\x35\xbd\xe6\xdf\x2b",
|
||||
"\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54",
|
||||
"\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98"
|
||||
},
|
||||
{
|
||||
// Long key and long data
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131,
|
||||
"\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 152,
|
||||
"\x21\x7e\x44\xbb\x08\xb6\xe0\x6a\x2d\x6c\x30\xf3\xcb\x9f\x53\x7f\x97\xc6\x33\x56",
|
||||
"\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2",
|
||||
"\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58"
|
||||
}
|
||||
};
|
||||
|
||||
static int pbkdf_test_vectors(void)
|
||||
{
|
||||
char result[256];
|
||||
@@ -447,6 +516,96 @@ static int hash_test(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* get_hmac_res(struct hmac_test_vector* out, int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0:
|
||||
return out->hmac_sha_1;
|
||||
case 1:
|
||||
return out->hmac_sha_256;
|
||||
case 2:
|
||||
return out->hmac_sha_512;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int hmac_test(void)
|
||||
{
|
||||
struct crypt_hmac *hmac;
|
||||
struct hmac_test_vector *vector;
|
||||
struct crypt_hash *h;
|
||||
unsigned int hmac_length;
|
||||
int i, j, r;
|
||||
|
||||
char result[64];
|
||||
char key[MAX_BLOCK_SIZE];
|
||||
|
||||
for (i = 0; i < (sizeof(hmac_test_vectors) / sizeof(*hmac_test_vectors)); i++) {
|
||||
vector = &hmac_test_vectors[i];
|
||||
printf("HMAC vector %02d: ", i);
|
||||
|
||||
for(j = 0; j < 3; j++) {
|
||||
struct hash_alg* hash = &hash_algs[j];
|
||||
hmac_length = crypt_hmac_size(hash->name);
|
||||
if (hmac_length != hash->length) {
|
||||
if (hmac_length < 0) {
|
||||
printf("[%s N/A]", hash->name);
|
||||
continue;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
printf("[%s]", hash->name);
|
||||
|
||||
int key_length = vector->key_length;
|
||||
|
||||
// hash key first if key size is greater than max block size
|
||||
if (key_length > MAX_BLOCK_SIZE) {
|
||||
if (crypt_hash_init(&h, hash->name))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_hash_write(h, vector->key, vector->key_length);
|
||||
|
||||
if (!r)
|
||||
r = crypt_hash_final(h, key, hash->length);
|
||||
|
||||
crypt_hash_destroy(h);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
key_length = hash->length;
|
||||
} else {
|
||||
memcpy(key, vector->key, vector->key_length);
|
||||
}
|
||||
|
||||
if (crypt_hmac_init(&hmac, hash->name, key, key_length))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_hmac_write(hmac, vector->data, vector->data_length);
|
||||
|
||||
if (!r)
|
||||
r = crypt_hmac_final(hmac, result, hmac_length);
|
||||
|
||||
crypt_hmac_destroy(hmac);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (memcmp(result, get_hmac_res(vector, j), hash->length)) {
|
||||
printf("expected output [FAILED].\n");
|
||||
printhex(" got", result, hash->length);
|
||||
printhex("want", get_hmac_res(vector, j), hash->length);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (crypt_backend_init(NULL)) {
|
||||
@@ -461,6 +620,9 @@ int main(int argc, char *argv[])
|
||||
if (hash_test())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (hmac_test())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
crypt_backend_destroy();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ function dm_crypt_features()
|
||||
|
||||
format() # format
|
||||
{
|
||||
dd if=/dev/zero of=$DEV bs=1M count=5 >/dev/null 2>&1
|
||||
dd if=/dev/zero of=$DEV bs=1M count=9 >/dev/null 2>&1
|
||||
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type $1 $DEV -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256
|
||||
[ $? -ne 0 ] && fail "Format failed."
|
||||
@@ -97,11 +97,11 @@ if [ -z "$DM_PERF_CPU" ]; then
|
||||
SKIP_COUNT=$((SKIP_COUNT+1))
|
||||
else
|
||||
# plain
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
|
||||
echo -e "$PWD1" | $CRYPTSETUP open -q --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
|
||||
echo -e "$PWD1" | $CRYPTSETUP open -q --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep -q discards || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
@@ -152,7 +152,7 @@ else
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size 1234 >/dev/null 2>&1 && fail
|
||||
for S in 512 1024 2048 4096; do
|
||||
echo -n "[$S]"
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size $S || fail
|
||||
echo -e "$PWD1" | $CRYPTSETUP open -q --type plain $DEV $DEV_NAME --sector-size $S || fail
|
||||
check_sector_size $S
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
done
|
||||
|
||||
@@ -20,7 +20,7 @@ fail()
|
||||
}
|
||||
|
||||
add_device() {
|
||||
modprobe scsi_debug $@
|
||||
modprobe scsi_debug $@ delay=0
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "This kernel seems to not support proper scsi_debug module, test skipped."
|
||||
exit 77
|
||||
@@ -74,7 +74,7 @@ dmsetup table $DEV_NAME | grep allow_discards >/dev/null || fail
|
||||
$CRYPTSETUP luksClose $DEV_NAME || fail
|
||||
|
||||
echo "[2] Allowing discards for plain device"
|
||||
echo $PWD1 | $CRYPTSETUP create $DEV_NAME $DEV --hash sha1 --allow-discards || fail
|
||||
echo $PWD1 | $CRYPTSETUP create -q $DEV_NAME $DEV --hash sha1 --allow-discards || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
|
||||
$CRYPTSETUP resize $DEV_NAME --size 100 || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
|
||||
|
||||
Binary file not shown.
BIN
tests/evil_hdr-keyslot_overlap.xz
Normal file
BIN
tests/evil_hdr-keyslot_overlap.xz
Normal file
Binary file not shown.
Binary file not shown.
BIN
tests/evil_hdr-luks_hdr_damage.xz
Normal file
BIN
tests/evil_hdr-luks_hdr_damage.xz
Normal file
Binary file not shown.
Binary file not shown.
BIN
tests/evil_hdr-payload_overwrite.xz
Normal file
BIN
tests/evil_hdr-payload_overwrite.xz
Normal file
Binary file not shown.
Binary file not shown.
BIN
tests/evil_hdr-small_luks_device.xz
Normal file
BIN
tests/evil_hdr-small_luks_device.xz
Normal file
Binary file not shown.
Binary file not shown.
BIN
tests/evil_hdr-stripes_payload_dmg.xz
Normal file
BIN
tests/evil_hdr-stripes_payload_dmg.xz
Normal file
Binary file not shown.
85
tests/generators/generate-luks2-invalid-json-size-c2.img.sh
Executable file
85
tests/generators/generate-luks2-invalid-json-size-c2.img.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary header with config json size mismatching
|
||||
# value in binary header
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512))
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
|
||||
json_str=$(jq -c '.' $TMPDIR/json0)
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0
|
||||
local str_res1=$(head -c 4 $TMPDIR/hdr_res0)
|
||||
test "$str_res1" = "LUKS" || exit 2
|
||||
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 4 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "SKUL" || exit 2
|
||||
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
|
||||
jq -c --arg js $JS 'if .config.json_size != ( $js | tostring )
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 128 KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-128k.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-128k.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 128KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 16 KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 1 MiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-1m.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-1m.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 1 MiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 256 KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-256k.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-256k.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 256KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
96
tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh
Executable file
96
tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 2 MiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-2m.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-2m.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 2 MiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 32 KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-32k.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-32k.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary header with non-default metadata json_size.
|
||||
# There's only limited set of values allowed as json size in
|
||||
# config section of LUKS2 metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 32KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
96
tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh
Executable file
96
tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 4 MiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-4m.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-4m.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 4 MiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 512 KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-512k.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-512k.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size. There's only limited
|
||||
# set of values allowed as json size in config section of LUKS2
|
||||
# metadata
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 512KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
94
tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh
Executable file
94
tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary header with non-default metadata json_size
|
||||
# and keyslots area trespassing in json area.
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 64KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024-1))
|
||||
# overlap in json area by exactly one byte
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024-1))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
96
tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh
Executable file
96
tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary header with non-default metadata json_size
|
||||
# and keyslot area overflowing out of keyslots area.
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 64KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
--arg mda $((2*TEST_MDA_SIZE_BYTES)) \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.keyslots."7".area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots."7".area.size | tonumber) + 1) | tostring ) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
# .keyslots.7.area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots.7.area.size | tonumber) + 1) | tostring ) |
|
||||
jq -c --arg mda $((2*TEST_MDA_SIZE_BYTES)) --arg jsize $JSON_SIZE \
|
||||
'if (.keyslots."7".area.offset != ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots."7".area.size | tonumber) + 1) | tostring )) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate primary with predefined json_size where keyslots size
|
||||
# overflows in data area (segment offset)
|
||||
#
|
||||
# secondary header is corrupted on purpose as well
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 64KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
--arg mda $((2*TEST_MDA_SIZE_BYTES)) \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.config.keyslots_size = (((($off | tonumber) - ($mda | tonumber) + 4096)) | tostring ) |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area1
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
|
||||
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
|
||||
test "$str_res1" = "VACUUM" || exit 2
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE --arg off $DATA_OFFSET --arg mda $((2*TEST_MDA_SIZE_BYTES)) \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize) or
|
||||
(.config.keyslots_size != (((($off | tonumber) - ($mda | tonumber) + 4096)) | tostring ))
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
97
tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh
Executable file
97
tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
. lib.sh
|
||||
|
||||
#
|
||||
# *** Description ***
|
||||
#
|
||||
# generate secondary header with one of allowed json area
|
||||
# size values. Test wheter auto-recovery code is able
|
||||
# to validate secondary header with non-default json area
|
||||
# size.
|
||||
#
|
||||
# primary header is corrupted on purpose.
|
||||
#
|
||||
|
||||
# $1 full target dir
|
||||
# $2 full source luks2 image
|
||||
|
||||
function prepare()
|
||||
{
|
||||
cp $SRC_IMG $TGT_IMG
|
||||
test -d $TMPDIR || mkdir $TMPDIR
|
||||
read_luks2_json0 $TGT_IMG $TMPDIR/json0
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
|
||||
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
# 64 KiB metadata
|
||||
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
|
||||
|
||||
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
|
||||
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
|
||||
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
|
||||
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
|
||||
JSON_SIZE=$((TEST_JSN_SIZE*512))
|
||||
DATA_OFFSET=16777216
|
||||
|
||||
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
|
||||
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
|
||||
.config.json_size = $jsize |
|
||||
.segments."0".offset = $off' $TMPDIR/json0)
|
||||
test -n "$json_str" || exit 2
|
||||
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
|
||||
|
||||
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
|
||||
|
||||
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
|
||||
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
|
||||
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
|
||||
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
|
||||
|
||||
erase_checksum $TMPDIR/area0
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
|
||||
write_checksum $chks0 $TMPDIR/area0
|
||||
|
||||
erase_checksum $TMPDIR/area1
|
||||
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
|
||||
write_checksum $chks0 $TMPDIR/area1
|
||||
|
||||
kill_bin_hdr $TMPDIR/area0
|
||||
|
||||
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
|
||||
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
|
||||
}
|
||||
|
||||
function check()
|
||||
{
|
||||
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
|
||||
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
|
||||
test "$str_res0" = "VACUUM" || exit 2
|
||||
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
|
||||
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
|
||||
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
|
||||
(.config.json_size != $jsize)
|
||||
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
rm -f $TMPDIR/*
|
||||
rm -fd $TMPDIR
|
||||
}
|
||||
|
||||
test $# -eq 2 || exit 1
|
||||
|
||||
TGT_IMG=$1/$(test_img_name $0)
|
||||
SRC_IMG=$2
|
||||
|
||||
prepare
|
||||
generate
|
||||
check
|
||||
cleanup
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user