mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-07 00:40:01 +01:00
Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ae863e380 | ||
|
|
f238e8c075 | ||
|
|
7d9a14fd24 | ||
|
|
2f964d95d8 | ||
|
|
00f419e5ea | ||
|
|
cc698dcde3 | ||
|
|
edced6cfed | ||
|
|
4fb11976d2 | ||
|
|
68ba5b2b36 | ||
|
|
65fa22ff23 | ||
|
|
c25d81d2a1 | ||
|
|
57d16a7a55 | ||
|
|
def397d0c8 | ||
|
|
7843415243 | ||
|
|
5a8b045bdd | ||
|
|
ab62f45d57 | ||
|
|
e521edd6ca | ||
|
|
3a0293a299 | ||
|
|
8a4db1ad7b | ||
|
|
1aba9ab444 | ||
|
|
dfa2755aba | ||
|
|
6e82bdd9a5 | ||
|
|
0dc245401f | ||
|
|
a57f1b1b64 | ||
|
|
1a50fee1d0 | ||
|
|
046e0e5280 | ||
|
|
656b55cd4b | ||
|
|
8d7af433d8 | ||
|
|
dc3de39eb7 | ||
|
|
3d403a7bd0 | ||
|
|
91f6296699 | ||
|
|
bd94eb36b3 | ||
|
|
1a19329b18 | ||
|
|
78a43c053a | ||
|
|
d7d76e72f7 | ||
|
|
dd0dcc05df | ||
|
|
3be8731fef | ||
|
|
86d0ff1a2b | ||
|
|
3adfe80601 | ||
|
|
0bc437d92c | ||
|
|
6b10f30eb9 | ||
|
|
fedd5bc969 | ||
|
|
8aee4f95fb | ||
|
|
1f2d8de95f | ||
|
|
dced269426 | ||
|
|
b834a59eaf | ||
|
|
4f7b413638 | ||
|
|
e4355c2973 | ||
|
|
31a4d552a2 | ||
|
|
6d51e8ab69 | ||
|
|
8157e47ad4 | ||
|
|
62b0138dad | ||
|
|
c13a8003fa | ||
|
|
979aec773e | ||
|
|
b789b011a2 | ||
|
|
ea8864badf | ||
|
|
49335b600f | ||
|
|
7245af59d3 | ||
|
|
f7b61b2617 | ||
|
|
dc40b91cdf | ||
|
|
eccf347568 | ||
|
|
e24a72f84c | ||
|
|
2c70c057d6 | ||
|
|
f16f37233f | ||
|
|
3cffadb508 | ||
|
|
ce30d5f1fd | ||
|
|
6e0f0408a0 | ||
|
|
3d6bcae84c | ||
|
|
b8beedb621 | ||
|
|
fd5c2a5000 | ||
|
|
69bc154fca | ||
|
|
387041ccf2 | ||
|
|
64d6b339a0 | ||
|
|
4f5f1b78c4 | ||
|
|
3e886ecf57 | ||
|
|
210ea612b3 | ||
|
|
3350ff017f | ||
|
|
7b42254975 | ||
|
|
e84b1ed7c0 | ||
|
|
f3f1bfd73a | ||
|
|
89f795d7b4 | ||
|
|
c36a7968f4 | ||
|
|
3762c8b76e | ||
|
|
872becdbbd | ||
|
|
c9694437d2 | ||
|
|
64ad90f73c | ||
|
|
166d23a813 | ||
|
|
59fdf2a6bb | ||
|
|
3640eaa726 | ||
|
|
2250d5f71f | ||
|
|
d9678325a2 | ||
|
|
dc8c47d936 | ||
|
|
5b7100ff87 | ||
|
|
4afa592160 |
11
FAQ
11
FAQ
@@ -23,7 +23,7 @@ A. Contributors
|
||||
with one master key, anti-forensic features, metadata block at
|
||||
start of device, ...). The latest version of this FAQ should
|
||||
usually be available at
|
||||
http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions
|
||||
https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions
|
||||
|
||||
|
||||
* 1.2 WARNINGS
|
||||
@@ -173,7 +173,7 @@ A. Contributors
|
||||
|
||||
* 1.6 Where is the project website?
|
||||
|
||||
There is the project website at http://code.google.com/p/cryptsetup/
|
||||
There is the project website at https://gitlab.com/cryptsetup/cryptsetup/
|
||||
Please do not post questions there, nobody will read them. Use
|
||||
the mailing-list instead.
|
||||
|
||||
@@ -1993,7 +1993,7 @@ A. Contributors
|
||||
process, except generating a new LUKS header with the old master
|
||||
key (it prints the command for that though):
|
||||
|
||||
http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
|
||||
https://gitlab.com/cryptsetup/cryptsetup/blob/master/misc/luks-header-from-active
|
||||
|
||||
You can also do this manually. Here is how:
|
||||
|
||||
@@ -2091,7 +2091,7 @@ http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
|
||||
bulk data at 0x200000.
|
||||
|
||||
The exact specification of the format is here:
|
||||
http://code.google.com/p/cryptsetup/wiki/Specification
|
||||
https://gitlab.com/cryptsetup/cryptsetup/wikis/Specification
|
||||
|
||||
For your convenience, here is the LUKS header with hex offsets.
|
||||
NOTE: The spec counts key-slots from 1 to 8, but the cryptsetup
|
||||
@@ -2458,8 +2458,7 @@ offset length name data type description
|
||||
* Specifications
|
||||
|
||||
- LUKS on-disk format spec:
|
||||
http://code.google.com/p/cryptsetup/wiki/Specification
|
||||
|
||||
https://gitlab.com/cryptsetup/cryptsetup/wikis/Specification
|
||||
|
||||
* Code Examples
|
||||
|
||||
|
||||
8
README
8
README
@@ -5,11 +5,11 @@ setup cryptographic volumes for dm-crypt (including LUKS extension)
|
||||
|
||||
WEB PAGE:
|
||||
|
||||
http://code.google.com/p/cryptsetup/
|
||||
https://gitlab.com/cryptsetup/cryptsetup/
|
||||
|
||||
FAQ:
|
||||
|
||||
http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions
|
||||
https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions
|
||||
|
||||
MAILING LIST:
|
||||
|
||||
@@ -22,8 +22,8 @@ DOWNLOAD:
|
||||
|
||||
SOURCE CODE:
|
||||
|
||||
URL: http://code.google.com/p/cryptsetup/source/browse/
|
||||
Checkout: git clone https://code.google.com/p/cryptsetup/
|
||||
URL: https://gitlab.com/cryptsetup/cryptsetup/tree/master
|
||||
Checkout: git clone https://gitlab.com/cryptsetup/cryptsetup.git
|
||||
|
||||
NLS (PO TRANSLATIONS):
|
||||
|
||||
|
||||
75
README.md
Normal file
75
README.md
Normal file
@@ -0,0 +1,75 @@
|
||||

|
||||
|
||||
What the ...?
|
||||
=============
|
||||
**Cryptsetup** is utility used to conveniently setup disk encryption based
|
||||
on [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
|
||||
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
|
||||
and **TrueCrypt** (including **VeraCrypt** extension) format.
|
||||
|
||||
Project also includes **veritysetup** utility used to conveniently setup
|
||||
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module.
|
||||
|
||||
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.
|
||||
|
||||
Why LUKS?
|
||||
---------
|
||||
* compatiblity via standardization,
|
||||
* secure against low entropy attacks,
|
||||
* support for multiple keys,
|
||||
* effective passphrase revocation,
|
||||
* free.
|
||||
|
||||
[Project home page](https://gitlab.com/cryptsetup/cryptsetup/).
|
||||
-----------------
|
||||
|
||||
[Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
|
||||
--------------------------------
|
||||
|
||||
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 1.6.8**
|
||||
* [cryptsetup-1.6.8.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.8.tar.xz)
|
||||
* Signature [cryptsetup-1.6.8.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.8.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 1.6.8 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.8-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 1.6.7](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.7.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.7.tar.sign) -
|
||||
* [Version 1.6.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.6.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.6.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.6-ReleaseNotes).
|
||||
* [Version 1.6.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.5.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.5.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.5-ReleaseNotes).
|
||||
* [Version 1.6.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.4.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.4.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.4-ReleaseNotes).
|
||||
|
||||
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.
|
||||
|
||||
NLS PO files are maintained by [TranslationProject](http://translationproject.org/domain/cryptsetup.html).
|
||||
|
||||
Help!
|
||||
-----
|
||||
Please always read [FAQ](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions) first.
|
||||
For cryptsetup and LUKS related questions, please use the dm-crypt mailing list, [dm-crypt@saout.de](mailto:dm-crypt@saout.de).
|
||||
|
||||
If you want to subscribe just send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
|
||||
|
||||
You can also browse [list archive](http://www.saout.de/pipermail/dm-crypt/) or read it through
|
||||
[web interface](http://news.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt).
|
||||
1
TODO
1
TODO
@@ -4,6 +4,5 @@ Version 1.7:
|
||||
- TRIM for keyslots
|
||||
- Do we need crypt_data_path() - path to data device (if differs)?
|
||||
- Resync ETA time is not accurate, calculate it better (last minute window?).
|
||||
- crypto backend should initialise itself only once (debug log)
|
||||
- Extend existing LUKS header to use another KDF? (https://password-hashing.net/)
|
||||
- Fix all crazy automake warnings (or switch to Cmake).
|
||||
|
||||
31
configure.ac
31
configure.ac
@@ -1,13 +1,11 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[1.6.5])
|
||||
AC_INIT([cryptsetup],[1.6.8])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=10:0:6
|
||||
dnl library file name for FIPS selfcheck
|
||||
LIBCRYPTSETUP_VERSION_FIPS="libcryptsetup.so.4"
|
||||
FIPS_MODULE_FILE="/etc/system-fips"
|
||||
LIBCRYPTSETUP_VERSION_INFO=11:0:7
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
@@ -62,6 +60,7 @@ AC_TYPE_OFF_T
|
||||
AC_SYS_LARGEFILE
|
||||
AC_FUNC_FSEEKO
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_STRERROR_R
|
||||
|
||||
dnl ==========================================================================
|
||||
|
||||
@@ -77,27 +76,17 @@ AC_SUBST(POPT_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl FIPS extensions
|
||||
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
|
||||
AC_DEFINE(ENABLE_FIPS, 1, [Enable FIPS mode restrictions])
|
||||
AC_DEFINE_UNQUOTED(LIBCRYPTSETUP_VERSION_FIPS, ["$LIBCRYPTSETUP_VERSION_FIPS"],
|
||||
[library file name for FIPS selfcheck])
|
||||
AC_DEFINE_UNQUOTED(FIPS_MODULE_FILE, ["$FIPS_MODULE_FILE"],
|
||||
[file checked to determine if running in FIPS mode])
|
||||
|
||||
if test "x$enable_static" = "xyes" -o "x$enable_static_cryptsetup" = "xyes" ; then
|
||||
AC_MSG_ERROR([Static build is not compatible with FIPS.])
|
||||
fi
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(fipscheck, FIPSCHECK_verify, ,[AC_MSG_ERROR([You need the fipscheck library.])])
|
||||
AC_SUBST(FIPSCHECK_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
fi
|
||||
|
||||
AC_DEFUN([NO_FIPS], [
|
||||
@@ -140,6 +129,14 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
|
||||
[AM_PATH_LIBGCRYPT([1.6.1], [use_internal_pbkdf2=0], [use_internal_pbkdf2=1])])
|
||||
AM_PATH_LIBGCRYPT($GCRYPT_REQ_VERSION,,[AC_MSG_ERROR([You need the gcrypt library.])])
|
||||
|
||||
AC_MSG_CHECKING([if internal cryptsetup PBKDF2 is compiled-in])
|
||||
if test $use_internal_pbkdf2 = 0; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
NO_FIPS([])
|
||||
fi
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
saved_LIBS=$LIBS
|
||||
LIBS="$saved_LIBS $LIBGCRYPT_LIBS -static"
|
||||
@@ -354,8 +351,6 @@ AC_SUBST([CRYPTO_STATIC_LIBS])
|
||||
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_FIPS])
|
||||
AC_SUBST([FIPS_MODULE_FILE])
|
||||
|
||||
dnl ==========================================================================
|
||||
AC_ARG_ENABLE([dev-random], AS_HELP_STRING([--enable-dev-random],
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
* in a persistent way on the device. Keyslot area is an array beyond LUKS header, where
|
||||
* volume key is stored in the encrypted form using user input passphrase. For more info about
|
||||
* LUKS keyslots and how it's actually protected, please look at
|
||||
* <A HREF="http://code.google.com/p/cryptsetup/wiki/Specification">LUKS specification</A>.
|
||||
* <A HREF="https://gitlab.com/cryptsetup/cryptsetup/wikis/Specification">LUKS specification</A>.
|
||||
* There are two basic methods to create a new keyslot:
|
||||
*
|
||||
* @subsection ckeyslot_vol crypt_keyslot_add_by_volume_key()
|
||||
|
||||
29
docs/v1.6.6-ReleaseNotes
Normal file
29
docs/v1.6.6-ReleaseNotes
Normal file
@@ -0,0 +1,29 @@
|
||||
Cryptsetup 1.6.6 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.5
|
||||
|
||||
* LUKS: Fix keyslot device access for devices which
|
||||
do not support direct IO operations. (Regression in 1.6.5.)
|
||||
|
||||
* LUKS: Fallback to old temporary keyslot device mapping method
|
||||
if hash (for ESSIV) is not supported by userspace crypto
|
||||
library. (Regression in 1.6.5.)
|
||||
|
||||
* Properly activate device with discard (TRIM for SSDs)
|
||||
if requested even if dm_crypt module is not yet loaded.
|
||||
Only if discard is not supported by the old kernel then
|
||||
the discard option is ignored.
|
||||
|
||||
* Fix some static analysis build warnings (scan-build).
|
||||
|
||||
* Report crypto lib version only once (and always add kernel
|
||||
version) in debug output.
|
||||
|
||||
Cryptsetup API NOTE:
|
||||
The direct terminal handling for passphrase entry will be removed from
|
||||
libcryptsetup in next major version (application should handle it itself).
|
||||
|
||||
It means that you have to always either provide password in buffer or set
|
||||
your own password callback function through crypt_set_password_callback().
|
||||
See API documentation (or libcryptsetup.h) for more info.
|
||||
84
docs/v1.6.7-ReleaseNotes
Normal file
84
docs/v1.6.7-ReleaseNotes
Normal file
@@ -0,0 +1,84 @@
|
||||
Cryptsetup 1.6.7 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.6
|
||||
|
||||
* Cryptsetup git and wiki are now hosted on GitLab.
|
||||
https://gitlab.com/cryptsetup/cryptsetup
|
||||
|
||||
Repository of stable releases remains on kernel.org site
|
||||
https://www.kernel.org/pub/linux/utils/cryptsetup/
|
||||
|
||||
For more info please see README file.
|
||||
|
||||
* Cryptsetup TCRYPT mode now supports VeraCrypt devices (TrueCrypt extension).
|
||||
|
||||
The VeraCrypt extension only increases iteration count for the key
|
||||
derivation function (on-disk format is the same as TrueCrypt format).
|
||||
|
||||
Note that unlocking of a VeraCrypt device can take very long time if used
|
||||
on slow machines.
|
||||
|
||||
To use this extension, add --veracrypt option, for example
|
||||
cryptsetup open --type tcrypt --veracrypt <container> <name>
|
||||
|
||||
For use through libcryptsetup, just add CRYPT_TCRYPT_VERA_MODES flag.
|
||||
|
||||
* Support keyfile-offset and keyfile-size options even for plain volumes.
|
||||
|
||||
* Support keyfile option for luksAddKey if the master key is specified.
|
||||
|
||||
* For historic reasons, hashing in the plain mode is not used
|
||||
if keyfile is specified (with exception of --key-file=-).
|
||||
Print a warning if these parameters are ignored.
|
||||
|
||||
* Support permanent device decryption for cryptsetup-reencrypt.
|
||||
To remove LUKS encryption from a device, you can now use --decrypt option.
|
||||
|
||||
* Allow to use --header option in all LUKS commands.
|
||||
The --header always takes precedence over positional device argument.
|
||||
|
||||
* Allow luksSuspend without need to specify a detached header.
|
||||
|
||||
* Detect if O_DIRECT is usable on a device allocation.
|
||||
There are some strange storage stack configurations which wrongly allows
|
||||
to open devices with direct-io but fails on all IO operations later.
|
||||
|
||||
Cryptsetup now tries to read the device first sector to ensure it can use
|
||||
direct-io.
|
||||
|
||||
* Add low-level performance options tuning for dmcrypt (for Linux 4.0 and later).
|
||||
|
||||
Linux kernel 4.0 contains rewritten dmcrypt code which tries to better utilize
|
||||
encryption on parallel CPU cores.
|
||||
|
||||
While tests show that this change increases performance on most configurations,
|
||||
dmcrypt now provides some switches to change its new behavior.
|
||||
|
||||
You can use them (per-device) with these cryptsetup switches:
|
||||
--perf-same_cpu_crypt
|
||||
--perf-submit_from_crypt_cpus
|
||||
|
||||
Please use these only in the case of serious performance problems.
|
||||
Refer to the cryptsetup man page and dm-crypt documentation
|
||||
(for same_cpu_crypt and submit_from_crypt_cpus options).
|
||||
https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
|
||||
|
||||
* Get rid of libfipscheck library.
|
||||
(Note that this option was used only for Red Hat and derived distributions.)
|
||||
With recent FIPS changes we do not need to link to this FIPS monster anymore.
|
||||
Also drop some no longer needed FIPS mode checks.
|
||||
|
||||
* Many fixes and clarifications to man pages.
|
||||
|
||||
* Prevent compiler to optimize-out zeroing of buffers for on-stack variables.
|
||||
|
||||
* Fix a crash if non-GNU strerror_r is used.
|
||||
|
||||
Cryptsetup API NOTE:
|
||||
The direct terminal handling for passphrase entry will be removed from
|
||||
libcryptsetup in next major version (application should handle it itself).
|
||||
|
||||
It means that you have to always either provide password in buffer or set
|
||||
your own password callback function through crypt_set_password_callback().
|
||||
See API documentation (or libcryptsetup.h) for more info.
|
||||
47
docs/v1.6.8-ReleaseNotes
Normal file
47
docs/v1.6.8-ReleaseNotes
Normal file
@@ -0,0 +1,47 @@
|
||||
Cryptsetup 1.6.8 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.7
|
||||
|
||||
* If the null cipher (no encryption) is used, allow only empty password for LUKS.
|
||||
(Previously cryptsetup accepted any password in this case.)
|
||||
|
||||
The null cipher can be used only for testing and it is used temporarily during
|
||||
offline encrypting not yet encrypted device (cryptsetup-reencrypt tool).
|
||||
|
||||
Accepting only empty password prevents situation when someone adds another
|
||||
LUKS device using the same UUID (UUID of existing LUKS device) with faked
|
||||
header containing null cipher.
|
||||
This could force user to use different LUKS device (with no encryption)
|
||||
without noticing.
|
||||
(IOW it prevents situation when attacker intentionally forces
|
||||
user to boot into different system just by LUKS header manipulation.)
|
||||
|
||||
Properly configured systems should have an additional integrity protection
|
||||
in place here (LUKS here provides only confidentiality) but it is better
|
||||
to not allow this situation in the first place.
|
||||
|
||||
(For more info see QubesOS Security Bulletin QSB-019-2015.)
|
||||
|
||||
* Properly support stdin "-" handling for luksAddKey for both new and old
|
||||
keyfile parameters.
|
||||
|
||||
* If encrypted device is file-backed (it uses underlying loop device),
|
||||
cryptsetup resize will try to resize underlying loop device as well.
|
||||
(It can be used to grow up file-backed device in one step.)
|
||||
|
||||
* Cryptsetup now allows to use empty password through stdin pipe.
|
||||
(Intended only for testing in scripts.)
|
||||
|
||||
Cryptsetup API NOTE:
|
||||
|
||||
Direct terminal handling and password calling callback for passphrase
|
||||
entry will be removed from libcryptsetup in next major (2.x) version
|
||||
(application should handle it itself).
|
||||
It means that application have to always provide password in API calls.
|
||||
|
||||
Functions returning last error will be removed in next major version (2.x).
|
||||
These functions did not work properly for early initialization errors
|
||||
and application can implement better function easily using own error callback.
|
||||
|
||||
See comments in libcryptsetup.h for more info about deprecated functions.
|
||||
@@ -39,7 +39,6 @@ libcryptsetup_la_LIBADD = \
|
||||
@UUID_LIBS@ \
|
||||
@DEVMAPPER_LIBS@ \
|
||||
@CRYPTO_LIBS@ \
|
||||
@FIPSCHECK_LIBS@ \
|
||||
$(common_ldadd)
|
||||
|
||||
|
||||
|
||||
@@ -102,4 +102,11 @@ int crypt_storage_decrypt(struct crypt_storage *ctx, uint64_t sector,
|
||||
int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t sector,
|
||||
size_t count, char *buffer);
|
||||
|
||||
/* Memzero helper (memset on stack can be optimized out) */
|
||||
static inline void crypt_backend_memzero(void *s, size_t n)
|
||||
{
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
while(n--) *p++ = 0;
|
||||
}
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_H */
|
||||
|
||||
@@ -187,6 +187,9 @@ static int crypt_cipher_crypt(struct crypt_cipher *ctx,
|
||||
|
||||
/* Set encrypt/decrypt operation */
|
||||
header = CMSG_FIRSTHDR(&msg);
|
||||
if (!header)
|
||||
return -EINVAL;
|
||||
|
||||
header->cmsg_level = SOL_ALG;
|
||||
header->cmsg_type = ALG_SET_OP;
|
||||
header->cmsg_len = CMSG_LEN(sizeof(*type));
|
||||
@@ -214,7 +217,7 @@ static int crypt_cipher_crypt(struct crypt_cipher *ctx,
|
||||
if (len != (ssize_t)length)
|
||||
r = -EIO;
|
||||
bad:
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
@@ -266,7 +266,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -133,7 +133,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
@@ -203,7 +203,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
HMAC_Final(&ctx->md, tmp, &tmp_len);
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/*
|
||||
* Internal IV helper
|
||||
* IV documentation: https://code.google.com/p/cryptsetup/wiki/DMCrypt
|
||||
* IV documentation: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
|
||||
*/
|
||||
struct crypt_sector_iv {
|
||||
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI } type;
|
||||
@@ -55,16 +55,18 @@ static int int_log2(unsigned int x)
|
||||
}
|
||||
|
||||
static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
const char *cipher_name, const char *iv_name,
|
||||
char *key, size_t key_length)
|
||||
const char *cipher_name, const char *mode_name,
|
||||
const char *iv_name, char *key, size_t key_length)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
|
||||
if (ctx->iv_size < 0)
|
||||
return -EINVAL;
|
||||
return -ENOENT;
|
||||
|
||||
if (!iv_name || !strcmp(cipher_name, "cipher_null")) {
|
||||
if (!iv_name ||
|
||||
!strcmp(cipher_name, "cipher_null") ||
|
||||
!strcmp(mode_name, "ecb")) {
|
||||
ctx->type = IV_NONE;
|
||||
ctx->iv_size = 0;
|
||||
return 0;
|
||||
@@ -85,7 +87,10 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
return -EINVAL;
|
||||
|
||||
hash_size = crypt_hash_size(++hash_name);
|
||||
if (hash_size < 0 || (unsigned)hash_size > sizeof(tmp))
|
||||
if (hash_size < 0)
|
||||
return -ENOENT;
|
||||
|
||||
if ((unsigned)hash_size > sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_hash_init(&h, hash_name))
|
||||
@@ -100,13 +105,13 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
r = crypt_hash_final(h, tmp, hash_size);
|
||||
crypt_hash_destroy(h);
|
||||
if (r) {
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&ctx->essiv_cipher, cipher_name, "ecb",
|
||||
tmp, hash_size);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -211,7 +216,7 @@ int crypt_storage_init(struct crypt_storage **ctx,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, cipher_iv, key, key_length);
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
|
||||
@@ -188,7 +188,7 @@ int pkcs5_pbkdf2(const char *hash,
|
||||
|
||||
if (crypt_hmac_init(&hmac, hash, P_hash, hLen))
|
||||
return -EINVAL;
|
||||
memset(P_hash, 0, sizeof(P_hash));
|
||||
crypt_backend_memzero(P_hash, sizeof(P_hash));
|
||||
} else {
|
||||
if (crypt_hmac_init(&hmac, hash, P, Plen))
|
||||
return -EINVAL;
|
||||
@@ -224,9 +224,9 @@ int pkcs5_pbkdf2(const char *hash,
|
||||
rc = 0;
|
||||
out:
|
||||
crypt_hmac_destroy(hmac);
|
||||
memset(U, 0, sizeof(U));
|
||||
memset(T, 0, sizeof(T));
|
||||
memset(tmp, 0, tmplen);
|
||||
crypt_backend_memzero(U, sizeof(U));
|
||||
crypt_backend_memzero(T, sizeof(T));
|
||||
crypt_backend_memzero(tmp, tmplen);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2014, Milan Broz
|
||||
* Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -136,7 +136,7 @@ void crypt_log(struct crypt_device *cd, int level, const char *msg);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Set confirmation callback (yes/no)
|
||||
* Set confirmation callback (yes/no).
|
||||
*
|
||||
* If code need confirmation (like resetting uuid or restoring LUKS header from file)
|
||||
* this function is called. If not defined, everything is confirmed.
|
||||
@@ -156,7 +156,7 @@ void crypt_set_confirm_callback(struct crypt_device *cd,
|
||||
void *usrptr);
|
||||
|
||||
/**
|
||||
* Set password query callback.
|
||||
* Set password query callback. DEPRECATED
|
||||
*
|
||||
* If code need @e _interactive_ query for password, this callback is called.
|
||||
* If not defined, compiled-in default is called (uses terminal input).
|
||||
@@ -176,8 +176,7 @@ void crypt_set_confirm_callback(struct crypt_device *cd,
|
||||
* @note Only zero terminated passwords can be entered this way, for complex
|
||||
* use API functions directly.
|
||||
* @note Maximal length of password is limited to @e length @e - @e 1 (minimal 511 chars)
|
||||
* @note Internal compiled-in terminal input is DEPRECATED and will be removed
|
||||
* in future versions.
|
||||
* @note This function is DEPRECATED and will be removed in future versions.
|
||||
*
|
||||
* @see Callback function is used in these call provided, that certain conditions are met:
|
||||
* @li crypt_keyslot_add_by_passphrase
|
||||
@@ -194,7 +193,7 @@ void crypt_set_password_callback(struct crypt_device *cd,
|
||||
|
||||
/**
|
||||
* Set timeout for interactive password entry using default
|
||||
* password callback
|
||||
* password callback. DEPRECATED
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param timeout_sec timeout in seconds
|
||||
@@ -202,16 +201,18 @@ void crypt_set_password_callback(struct crypt_device *cd,
|
||||
void crypt_set_timeout(struct crypt_device *cd, uint64_t timeout_sec);
|
||||
|
||||
/**
|
||||
* Set number of retries in case password input has been incorrect
|
||||
* Set number of retries in case password input has been incorrect. DEPRECATED.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param tries the number
|
||||
*
|
||||
* @note This function is DEPRECATED and will be removed in future versions.
|
||||
*/
|
||||
void crypt_set_password_retry(struct crypt_device *cd, int tries);
|
||||
|
||||
/**
|
||||
* Set how long should cryptsetup iterate in PBKDF2 function.
|
||||
* Default value heads towards the iterations which takes around 1 second
|
||||
* Default value heads towards the iterations which takes around 1 second.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param iteration_time_ms the time in ms
|
||||
@@ -222,10 +223,12 @@ void crypt_set_iterarion_time(struct crypt_device *cd, uint64_t iteration_time_m
|
||||
|
||||
/**
|
||||
* Set whether passphrase will be verified on input
|
||||
* (user has to input same passphrase twice)
|
||||
* (user has to input same passphrase twice). DEPRECATED
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param password_verify @e 0 = false, @e !0 true
|
||||
*
|
||||
* @note This function is DEPRECATED and will be removed in future versions.
|
||||
*/
|
||||
void crypt_set_password_verify(struct crypt_device *cd, int password_verify);
|
||||
|
||||
@@ -263,7 +266,7 @@ int crypt_set_data_device(struct crypt_device *cd, const char *device);
|
||||
void crypt_set_rng_type(struct crypt_device *cd, int rng_type);
|
||||
|
||||
/**
|
||||
* Get which RNG (random number generator) is used for generating long term key
|
||||
* Get which RNG (random number generator) is used for generating long term key.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @return RNG type on success or negative errno value otherwise.
|
||||
@@ -274,7 +277,7 @@ int crypt_get_rng_type(struct crypt_device *cd);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Helper to lock/unlock memory to avoid swap sensitive data to disk
|
||||
* Helper to lock/unlock memory to avoid swap sensitive data to disk.
|
||||
*
|
||||
* @param cd crypt device handle, can be @e NULL
|
||||
* @param lock 0 to unlock otherwise lock memory
|
||||
@@ -306,7 +309,7 @@ int crypt_memory_lock(struct crypt_device *cd, int lock);
|
||||
#define CRYPT_LOOPAES "LOOPAES"
|
||||
/** dm-verity mode */
|
||||
#define CRYPT_VERITY "VERITY"
|
||||
/** TCRYPT (TrueCrypt-compatible) mode */
|
||||
/** TCRYPT (TrueCrypt-compatible and VeraCrypt-compatible) mode */
|
||||
#define CRYPT_TCRYPT "TCRYPT"
|
||||
|
||||
/**
|
||||
@@ -319,7 +322,7 @@ const char *crypt_get_type(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure used as parameter for PLAIN device type
|
||||
* Structure used as parameter for PLAIN device type.
|
||||
*
|
||||
* @see crypt_format
|
||||
*/
|
||||
@@ -331,7 +334,7 @@ struct crypt_params_plain {
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure used as parameter for LUKS device type
|
||||
* Structure used as parameter for LUKS device type.
|
||||
*
|
||||
* @see crypt_format, crypt_load
|
||||
*
|
||||
@@ -347,7 +350,7 @@ struct crypt_params_luks1 {
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure used as parameter for loop-AES device type
|
||||
* Structure used as parameter for loop-AES device type.
|
||||
*
|
||||
* @see crypt_format
|
||||
*
|
||||
@@ -360,7 +363,7 @@ struct crypt_params_loopaes {
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure used as parameter for dm-verity device type
|
||||
* Structure used as parameter for dm-verity device type.
|
||||
*
|
||||
* @see crypt_format, crypt_load
|
||||
*
|
||||
@@ -388,7 +391,7 @@ struct crypt_params_verity {
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure used as parameter for TCRYPT device type
|
||||
* Structure used as parameter for TCRYPT device type.
|
||||
*
|
||||
* @see crypt_load
|
||||
*
|
||||
@@ -405,7 +408,7 @@ struct crypt_params_tcrypt {
|
||||
uint32_t flags; /**< CRYPT_TCRYPT* flags */
|
||||
};
|
||||
|
||||
/** Include legacy modes ehn scannig for header*/
|
||||
/** Include legacy modes when scanning for header */
|
||||
#define CRYPT_TCRYPT_LEGACY_MODES (1 << 0)
|
||||
/** Try to load hidden header (describing hidden device) */
|
||||
#define CRYPT_TCRYPT_HIDDEN_HEADER (1 << 1)
|
||||
@@ -413,11 +416,16 @@ struct crypt_params_tcrypt {
|
||||
#define CRYPT_TCRYPT_BACKUP_HEADER (1 << 2)
|
||||
/** Device contains encrypted system (with boot loader) */
|
||||
#define CRYPT_TCRYPT_SYSTEM_HEADER (1 << 3)
|
||||
/** Include VeraCrypt modes when scanning for header,
|
||||
* all other TCRYPT flags applies as well.
|
||||
* VeraCrypt device is reported as TCRYPT type.
|
||||
*/
|
||||
#define CRYPT_TCRYPT_VERA_MODES (1 << 4)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Create (format) new crypt device (and possible header on-disk) but not activates it.
|
||||
* Create (format) new crypt device (and possible header on-disk) but do not activate it.
|
||||
*
|
||||
* @pre @e cd contains initialized and not formatted device context (device type must @b not be set)
|
||||
*
|
||||
@@ -447,7 +455,7 @@ int crypt_format(struct crypt_device *cd,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Set new UUID for already existing device
|
||||
* Set new UUID for already existing device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param uuid requested UUID or @e NULL if it should be generated
|
||||
@@ -460,7 +468,7 @@ int crypt_set_uuid(struct crypt_device *cd,
|
||||
const char *uuid);
|
||||
|
||||
/**
|
||||
* Load crypt device parameters from on-disk header
|
||||
* Load crypt device parameters from on-disk header.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param requested_type @link crypt_type @endlink or @e NULL for all known
|
||||
@@ -479,7 +487,7 @@ int crypt_load(struct crypt_device *cd,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Try to repair crypt device on-disk header if invalid
|
||||
* Try to repair crypt device on-disk header if invalid.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param requested_type @link crypt_type @endlink or @e NULL for all known
|
||||
@@ -493,7 +501,7 @@ int crypt_repair(struct crypt_device *cd,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Resize crypt device
|
||||
* Resize crypt device.
|
||||
*
|
||||
* @param cd - crypt device handle
|
||||
* @param name - name of device to resize
|
||||
@@ -506,7 +514,7 @@ int crypt_resize(struct crypt_device *cd,
|
||||
uint64_t new_size);
|
||||
|
||||
/**
|
||||
* Suspends crypt device.
|
||||
* Suspend crypt device.
|
||||
*
|
||||
* @param cd crypt device handle, can be @e NULL
|
||||
* @param name name of device to suspend
|
||||
@@ -520,7 +528,7 @@ int crypt_suspend(struct crypt_device *cd,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Resumes crypt device using passphrase.
|
||||
* Resume crypt device using passphrase.
|
||||
*
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
@@ -542,7 +550,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
|
||||
size_t passphrase_size);
|
||||
|
||||
/**
|
||||
* Resumes crypt device using key file.
|
||||
* Resume crypt device using key file.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to resume
|
||||
@@ -572,7 +580,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
||||
size_t keyfile_size);
|
||||
|
||||
/**
|
||||
* Releases crypt device context and used memory.
|
||||
* Release crypt device context and used memory.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*/
|
||||
@@ -589,7 +597,7 @@ void crypt_free(struct crypt_device *cd);
|
||||
#define CRYPT_ANY_SLOT -1
|
||||
|
||||
/**
|
||||
* Add key slot using provided passphrase
|
||||
* Add key slot using provided passphrase.
|
||||
*
|
||||
* @pre @e cd contains initialized and formatted LUKS device context
|
||||
*
|
||||
@@ -613,7 +621,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
||||
size_t new_passphrase_size);
|
||||
|
||||
/**
|
||||
* Change defined key slot using provided passphrase
|
||||
* Change defined key slot using provided passphrase.
|
||||
*
|
||||
* @pre @e cd contains initialized and formatted LUKS device context
|
||||
*
|
||||
@@ -643,7 +651,7 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
||||
size_t new_passphrase_size);
|
||||
|
||||
/**
|
||||
* Add key slot using provided key file path
|
||||
* Add key slot using provided key file path.
|
||||
*
|
||||
* @pre @e cd contains initialized and formatted LUKS device context
|
||||
*
|
||||
@@ -658,7 +666,8 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
||||
*
|
||||
* @return allocated key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note Note that @e keyfile can be "-" for STDIN
|
||||
* @note Note that @e keyfile can be "-" for STDIN. This special handling is DEPRECATED
|
||||
* and will be removed in next version.
|
||||
*/
|
||||
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -679,7 +688,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
|
||||
size_t new_keyfile_size);
|
||||
|
||||
/**
|
||||
* Add key slot using provided volume key
|
||||
* Add key slot using provided volume key.
|
||||
*
|
||||
* @pre @e cd contains initialized and formatted LUKS device context
|
||||
*
|
||||
@@ -703,7 +712,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
|
||||
size_t passphrase_size);
|
||||
|
||||
/**
|
||||
* Destroy (and disable) key slot
|
||||
* Destroy (and disable) key slot.
|
||||
*
|
||||
* @pre @e cd contains initialized and formatted LUKS device context
|
||||
*
|
||||
@@ -739,6 +748,11 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_PRIVATE (1 << 4)
|
||||
/** corruption detected (verity), output only */
|
||||
#define CRYPT_ACTIVATE_CORRUPTED (1 << 5)
|
||||
/** use same_cpu_crypt option for dm-crypt */
|
||||
#define CRYPT_ACTIVATE_SAME_CPU_CRYPT (1 << 6)
|
||||
/** use submit_from_crypt_cpus for dm-crypt */
|
||||
#define CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS (1 << 7)
|
||||
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -751,7 +765,7 @@ struct crypt_active_device {
|
||||
};
|
||||
|
||||
/**
|
||||
* Receives runtime attributes of active crypt device
|
||||
* Receive runtime attributes of active crypt device.
|
||||
*
|
||||
* @param cd crypt device handle (can be @e NULL)
|
||||
* @param name name of active device
|
||||
@@ -767,7 +781,7 @@ int crypt_get_active_device(struct crypt_device *cd,
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Activate device or check passphrase
|
||||
* Activate device or check passphrase.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create, if @e NULL only check passphrase
|
||||
@@ -789,7 +803,7 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate device or check using key file
|
||||
* Activate device or check using key file.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create, if @e NULL only check keyfile
|
||||
@@ -819,7 +833,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate device using provided volume key
|
||||
* Activate device using provided volume key.
|
||||
*
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
@@ -859,7 +873,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
int crypt_deactivate(struct crypt_device *cd, const char *name);
|
||||
|
||||
/**
|
||||
* Get volume key from of crypt device
|
||||
* Get volume key from crypt device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
|
||||
@@ -882,7 +896,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
size_t passphrase_size);
|
||||
|
||||
/**
|
||||
* Verify that provided volume key is valid for crypt device
|
||||
* Verify that provided volume key is valid for crypt device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param volume_key provided volume key
|
||||
@@ -911,7 +925,7 @@ typedef enum {
|
||||
} crypt_status_info;
|
||||
|
||||
/**
|
||||
* Get status info about device name
|
||||
* Get status info about device name.
|
||||
*
|
||||
* @param cd crypt device handle, can be @e NULL
|
||||
* @param name crypt device name
|
||||
@@ -922,7 +936,7 @@ typedef enum {
|
||||
crypt_status_info crypt_status(struct crypt_device *cd, const char *name);
|
||||
|
||||
/**
|
||||
* Dump text-formatted information about crypt or verity device to log output
|
||||
* Dump text-formatted information about crypt or verity device to log output.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -931,7 +945,7 @@ crypt_status_info crypt_status(struct crypt_device *cd, const char *name);
|
||||
int crypt_dump(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get cipher used in device
|
||||
* Get cipher used in device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -941,7 +955,7 @@ int crypt_dump(struct crypt_device *cd);
|
||||
const char *crypt_get_cipher(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get cipher mode used in device
|
||||
* Get cipher mode used in device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -951,7 +965,7 @@ const char *crypt_get_cipher(struct crypt_device *cd);
|
||||
const char *crypt_get_cipher_mode(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get device UUID
|
||||
* Get device UUID.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -961,7 +975,7 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd);
|
||||
const char *crypt_get_uuid(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get path to underlaying device
|
||||
* Get path to underlaying device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -971,7 +985,7 @@ const char *crypt_get_uuid(struct crypt_device *cd);
|
||||
const char *crypt_get_device_name(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get device offset in sectors where real data starts on underlying device)
|
||||
* Get device offset in sectors where real data starts (on underlying device).
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -981,7 +995,7 @@ const char *crypt_get_device_name(struct crypt_device *cd);
|
||||
uint64_t crypt_get_data_offset(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get IV offset in sectors (skip)
|
||||
* Get IV offset in sectors (skip).
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -991,7 +1005,7 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd);
|
||||
uint64_t crypt_get_iv_offset(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get size (in bytes) of volume key for crypt device
|
||||
* Get size (in bytes) of volume key for crypt device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
@@ -1001,7 +1015,7 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd);
|
||||
int crypt_get_volume_key_size(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get device parameters for VERITY device
|
||||
* Get device parameters for VERITY device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param vp verity device info
|
||||
@@ -1024,7 +1038,7 @@ int crypt_get_verity_info(struct crypt_device *cd,
|
||||
*/
|
||||
|
||||
/**
|
||||
* Informational benchmark for ciphers
|
||||
* Informational benchmark for ciphers.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param cipher (e.g. "aes")
|
||||
@@ -1050,7 +1064,7 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
double *decryption_mbs);
|
||||
|
||||
/**
|
||||
* Informational benchmark for KDF
|
||||
* Informational benchmark for KDF.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param kdf Key derivation function (e.g. "pbkdf2")
|
||||
@@ -1091,7 +1105,7 @@ typedef enum {
|
||||
} crypt_keyslot_info;
|
||||
|
||||
/**
|
||||
* Get information about particular key slot
|
||||
* Get information about particular key slot.
|
||||
*
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
@@ -1114,7 +1128,7 @@ crypt_keyslot_info crypt_keyslot_status(struct crypt_device *cd, int keyslot);
|
||||
int crypt_keyslot_max(const char *type);
|
||||
|
||||
/**
|
||||
* Get keyslot area pointers (relative to metadata device)
|
||||
* Get keyslot area pointers (relative to metadata device).
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot keyslot number
|
||||
@@ -1130,7 +1144,7 @@ int crypt_keyslot_area(struct crypt_device *cd,
|
||||
uint64_t *length);
|
||||
|
||||
/**
|
||||
* Backup header and keyslots to file
|
||||
* Backup header and keyslots to file.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param requested_type @link crypt_type @endlink or @e NULL for all known
|
||||
@@ -1144,7 +1158,7 @@ int crypt_header_backup(struct crypt_device *cd,
|
||||
const char *backup_file);
|
||||
|
||||
/**
|
||||
* Restore header and keyslots from backup file
|
||||
* Restore header and keyslots from backup file.
|
||||
*
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
@@ -1159,14 +1173,14 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
const char *backup_file);
|
||||
|
||||
/**
|
||||
* Receives last reported error
|
||||
* Receive last reported error, DEPRECATED.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param buf buffef for message
|
||||
* @param size size of buffer
|
||||
*
|
||||
* @note Note that this is old API function using global context.
|
||||
* All error messages are reported also through log callback.
|
||||
* @note This function is DEPRECATED and will be removed in future versions.
|
||||
* @note All error messages are reported also through log callback.
|
||||
*/
|
||||
void crypt_last_error(struct crypt_device *cd, char *buf, size_t size);
|
||||
|
||||
@@ -1176,8 +1190,7 @@ void crypt_last_error(struct crypt_device *cd, char *buf, size_t size);
|
||||
* @param buf buffef for message
|
||||
* @param size size of buffer
|
||||
*
|
||||
* @note Note that this is old API function using global context.
|
||||
* All error messages are reported also through log callback.
|
||||
* @note This function is DEPRECATED and will be removed in future versions.
|
||||
*/
|
||||
void crypt_get_error(char *buf, size_t size);
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
* Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -144,6 +144,11 @@ static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
|
||||
if (_dm_satisfies_version(1, 13, crypt_maj, crypt_min))
|
||||
_dm_crypt_flags |= DM_TCW_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 14, crypt_maj, crypt_min)) {
|
||||
_dm_crypt_flags |= DM_SAME_CPU_CRYPT_SUPPORTED;
|
||||
_dm_crypt_flags |= DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Repeat test if dm-crypt is not present */
|
||||
if (crypt_maj > 0)
|
||||
_dm_crypt_checked = 1;
|
||||
@@ -159,16 +164,6 @@ static void _dm_set_verity_compat(const char *dm_version, unsigned verity_maj,
|
||||
verity_maj, verity_min, verity_patch);
|
||||
}
|
||||
|
||||
static void _dm_kernel_info(void)
|
||||
{
|
||||
struct utsname uts;
|
||||
|
||||
if (!uname(&uts))
|
||||
log_dbg("Detected kernel %s %s %s.",
|
||||
uts.sysname, uts.release, uts.machine);
|
||||
|
||||
}
|
||||
|
||||
static int _dm_check_versions(void)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
@@ -179,8 +174,6 @@ static int _dm_check_versions(void)
|
||||
if (_dm_crypt_checked)
|
||||
return 1;
|
||||
|
||||
_dm_kernel_info();
|
||||
|
||||
/* Shut up DM while checking */
|
||||
_quiet_log = 1;
|
||||
|
||||
@@ -305,23 +298,30 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
|
||||
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
|
||||
}
|
||||
|
||||
/* http://code.google.com/p/cryptsetup/wiki/DMCrypt */
|
||||
static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
|
||||
/* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt */
|
||||
static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd, uint32_t flags)
|
||||
{
|
||||
int r, max_size, null_cipher = 0;
|
||||
int r, max_size, null_cipher = 0, num_options = 0;
|
||||
char *params, *hexkey;
|
||||
const char *features = "";
|
||||
char features[256];
|
||||
|
||||
if (!dmd)
|
||||
return NULL;
|
||||
|
||||
if (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
||||
if (dm_flags() & DM_DISCARDS_SUPPORTED) {
|
||||
features = " 1 allow_discards";
|
||||
log_dbg("Discard/TRIM is allowed.");
|
||||
} else
|
||||
log_dbg("Discard/TRIM is not supported by the kernel.");
|
||||
}
|
||||
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
|
||||
num_options++;
|
||||
|
||||
if (num_options)
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
|
||||
(flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
|
||||
(flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "");
|
||||
else
|
||||
*features = '\0';
|
||||
|
||||
if (!strncmp(dmd->u.crypt.cipher, "cipher_null-", 12))
|
||||
null_cipher = 1;
|
||||
@@ -355,7 +355,7 @@ out:
|
||||
return params;
|
||||
}
|
||||
|
||||
/* http://code.google.com/p/cryptsetup/wiki/DMVerity */
|
||||
/* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity */
|
||||
static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
||||
struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
@@ -566,6 +566,9 @@ static int _dm_create_device(const char *name, const char *type,
|
||||
uint32_t cookie = 0;
|
||||
uint16_t udev_flags = 0;
|
||||
|
||||
if (!params)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_PRIVATE)
|
||||
udev_flags = CRYPT_TEMP_UDEV_FLAGS;
|
||||
|
||||
@@ -642,12 +645,14 @@ out_no_removal:
|
||||
if (cookie && _dm_use_udev())
|
||||
(void)_dm_udev_wait(cookie);
|
||||
|
||||
if (params)
|
||||
crypt_safe_free(params);
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
dm_task_update_nodes();
|
||||
|
||||
/* If code just loaded target module, update versions */
|
||||
_dm_check_versions();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -657,7 +662,8 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
int reload)
|
||||
{
|
||||
char *table_params = NULL;
|
||||
int r = -EINVAL;
|
||||
uint32_t dmd_flags;
|
||||
int r;
|
||||
|
||||
if (!type)
|
||||
return -EINVAL;
|
||||
@@ -665,15 +671,34 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
|
||||
dmd_flags = dmd->flags;
|
||||
|
||||
if (dmd->target == DM_CRYPT)
|
||||
table_params = get_dm_crypt_params(dmd);
|
||||
table_params = get_dm_crypt_params(dmd, dmd_flags);
|
||||
else if (dmd->target == DM_VERITY)
|
||||
table_params = get_dm_verity_params(dmd->u.verity.vp, dmd);
|
||||
|
||||
if (table_params)
|
||||
r = _dm_create_device(name, type, dmd->data_device,
|
||||
dmd->flags, dmd->uuid, dmd->size,
|
||||
table_params, reload);
|
||||
r = _dm_create_device(name, type, dmd->data_device, dmd_flags,
|
||||
dmd->uuid, dmd->size, table_params, reload);
|
||||
|
||||
/* If discard not supported try to load without discard */
|
||||
if (!reload && r && dmd->target == DM_CRYPT &&
|
||||
(dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!(dm_flags() & DM_DISCARDS_SUPPORTED)) {
|
||||
log_dbg("Discard/TRIM is not supported, retrying activation.");
|
||||
dmd_flags = dmd_flags & ~CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
crypt_safe_free(table_params);
|
||||
table_params = get_dm_crypt_params(dmd, dmd_flags);
|
||||
r = _dm_create_device(name, type, dmd->data_device, dmd_flags,
|
||||
dmd->uuid, dmd->size, table_params, reload);
|
||||
}
|
||||
|
||||
if (r == -EINVAL &&
|
||||
dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
|
||||
!(dm_flags() & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dmcrypt performance options are not supported.\n"));
|
||||
|
||||
crypt_safe_free(table_params);
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
@@ -860,6 +885,10 @@ static int _dm_query_crypt(uint32_t get_flags,
|
||||
arg = strsep(¶ms, " ");
|
||||
if (!strcasecmp(arg, "allow_discards"))
|
||||
dmd->flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
else if (!strcasecmp(arg, "same_cpu_crypt"))
|
||||
dmd->flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
|
||||
else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
|
||||
dmd->flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
|
||||
else /* unknown option */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct crypt_storage *s;
|
||||
int devfd, bsize, r = 0;
|
||||
int devfd = -1, bsize, r = 0;
|
||||
|
||||
/* Only whole sector writes supported */
|
||||
if (srcLength % SECTOR_SIZE)
|
||||
@@ -164,25 +164,33 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
|
||||
r = crypt_storage_encrypt(s, 0, srcLength / SECTOR_SIZE, src);
|
||||
crypt_storage_destroy(s);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = -EIO;
|
||||
|
||||
/* Write buffer to device */
|
||||
bsize = device_block_size(device);
|
||||
if (bsize <= 0)
|
||||
return -EIO;
|
||||
goto out;
|
||||
|
||||
devfd = open(device_path(device), O_RDWR | O_DIRECT);
|
||||
devfd = device_open(device, O_RDWR);
|
||||
if (devfd == -1)
|
||||
return -EIO;
|
||||
goto out;
|
||||
|
||||
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
||||
write_blockwise(devfd, bsize, src, srcLength) == -1)
|
||||
r = -EIO;
|
||||
goto out;
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
if(devfd != -1)
|
||||
close(devfd);
|
||||
if (r)
|
||||
log_err(ctx, _("IO error while encrypting keyslot.\n"));
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
@@ -194,7 +202,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct crypt_storage *s;
|
||||
int devfd, bsize, r = 0;
|
||||
int devfd = -1, bsize, r = 0;
|
||||
|
||||
/* Only whole sector reads supported */
|
||||
if (dstLength % SECTOR_SIZE)
|
||||
@@ -219,25 +227,20 @@ 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 */
|
||||
bsize = device_block_size(device);
|
||||
if (bsize <= 0) {
|
||||
crypt_storage_destroy(s);
|
||||
return -EIO;
|
||||
}
|
||||
if (bsize <= 0)
|
||||
goto bad;
|
||||
|
||||
devfd = open(device_path(device), O_RDONLY | O_DIRECT);
|
||||
if (devfd == -1) {
|
||||
crypt_storage_destroy(s);
|
||||
return -EIO;
|
||||
}
|
||||
devfd = device_open(device, O_RDONLY);
|
||||
if (devfd == -1)
|
||||
goto bad;
|
||||
|
||||
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
||||
read_blockwise(devfd, bsize, dst, dstLength) == -1) {
|
||||
crypt_storage_destroy(s);
|
||||
close(devfd);
|
||||
return -EIO;
|
||||
}
|
||||
read_blockwise(devfd, bsize, dst, dstLength) == -1)
|
||||
goto bad;
|
||||
|
||||
close(devfd);
|
||||
|
||||
@@ -245,5 +248,13 @@ 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 != -1)
|
||||
close(devfd);
|
||||
|
||||
log_err(ctx, _("IO error while decrypting keyslot.\n"));
|
||||
crypt_storage_destroy(s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
out:
|
||||
if (devfd != -1)
|
||||
close(devfd);
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
@@ -398,7 +398,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
}
|
||||
out:
|
||||
crypt_free_volume_key(vk);
|
||||
memset(&temp_phdr, 0, sizeof(temp_phdr));
|
||||
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -471,6 +471,13 @@ static void LUKS_fix_header_compatible(struct luks_phdr *header)
|
||||
/* Old cryptsetup expects "sha1", gcrypt allows case insensistive names,
|
||||
* so always convert hash to lower case in header */
|
||||
_to_lower(header->hashSpec, LUKS_HASHSPEC_L);
|
||||
|
||||
/* ECB mode does not use IV but dmcrypt silently allows it.
|
||||
* Drop any IV here if ECB is used (that is not secure anyway).*/
|
||||
if (!strncmp(header->cipherMode, "ecb-", 4)) {
|
||||
memset(header->cipherMode, 0, LUKS_CIPHERMODE_L);
|
||||
strcpy(header->cipherMode, "ecb");
|
||||
}
|
||||
}
|
||||
|
||||
int LUKS_read_phdr_backup(const char *backup_file,
|
||||
@@ -618,7 +625,7 @@ static int LUKS_check_cipher(struct luks_phdr *hdr, struct crypt_device *ctx)
|
||||
empty_key, 0, ctx);
|
||||
|
||||
crypt_free_volume_key(empty_key);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
crypt_memzero(buf, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -804,7 +811,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
hdr->keyblock[keyIndex].passwordIterations = at_least((uint32_t)PBKDF2_temp,
|
||||
LUKS_SLOT_ITERATIONS_MIN);
|
||||
|
||||
log_dbg("Key slot %d use %d password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations);
|
||||
log_dbg("Key slot %d use %" PRIu32 " password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations);
|
||||
|
||||
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
if (!derived_key)
|
||||
@@ -939,6 +946,11 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
goto out;
|
||||
|
||||
r = LUKS_verify_volume_key(hdr, vk);
|
||||
|
||||
/* Allow only empty passphrase with null cipher */
|
||||
if (!r && !strcmp(hdr->cipherName, "cipher_null") && passwordLen)
|
||||
r = -EPERM;
|
||||
|
||||
if (!r)
|
||||
log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex);
|
||||
out:
|
||||
|
||||
@@ -162,6 +162,9 @@ int crypt_random_init(struct crypt_device *ctx)
|
||||
if(random_fd == -1)
|
||||
goto fail;
|
||||
|
||||
if (crypt_fips_mode())
|
||||
log_verbose(ctx, _("Running in FIPS mode.\n"));
|
||||
|
||||
random_initialised = 1;
|
||||
return 0;
|
||||
fail:
|
||||
|
||||
85
lib/setup.c
85
lib/setup.c
@@ -25,6 +25,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -99,6 +100,9 @@ struct crypt_device {
|
||||
char error[MAX_ERROR_LENGTH];
|
||||
};
|
||||
|
||||
/* Just to suppress redundant messages about crypto backend */
|
||||
static int _crypto_logged = 0;
|
||||
|
||||
/* Global error */
|
||||
/* FIXME: not thread safe, remove this later */
|
||||
static char global_error[MAX_ERROR_LENGTH] = {0};
|
||||
@@ -188,6 +192,7 @@ struct device *crypt_data_device(struct crypt_device *cd)
|
||||
|
||||
int init_crypto(struct crypt_device *ctx)
|
||||
{
|
||||
struct utsname uts;
|
||||
int r;
|
||||
|
||||
r = crypt_random_init(ctx);
|
||||
@@ -200,7 +205,15 @@ int init_crypto(struct crypt_device *ctx)
|
||||
if (r < 0)
|
||||
log_err(ctx, _("Cannot initialize crypto backend.\n"));
|
||||
|
||||
log_dbg("Crypto backend (%s) initialized.", crypt_backend_version());
|
||||
if (!r && !_crypto_logged) {
|
||||
log_dbg("Crypto backend (%s) initialized in cryptsetup library version %s.",
|
||||
crypt_backend_version(), PACKAGE_VERSION);
|
||||
if (!uname(&uts))
|
||||
log_dbg("Detected kernel %s %s %s.",
|
||||
uts.sysname, uts.release, uts.machine);
|
||||
_crypto_logged = 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -356,6 +369,36 @@ static int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* compares type of active device to provided string (only if there is no explicit type)
|
||||
*/
|
||||
static int crypt_uuid_type_cmp(struct crypt_device *cd, const char *type)
|
||||
{
|
||||
struct crypt_dm_active_device dmd = {};
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
/* Must user header-on-disk if we know type here */
|
||||
if (cd->type || !cd->u.none.active_name)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg("Checking if active device %s without header has UUID type %s.",
|
||||
cd->u.none.active_name, type);
|
||||
|
||||
r = dm_query_device(cd, cd->u.none.active_name, DM_ACTIVE_UUID, &dmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = -ENODEV;
|
||||
len = strlen(type);
|
||||
if (dmd.uuid && strlen(dmd.uuid) > len &&
|
||||
!strncmp(dmd.uuid, type, len) && dmd.uuid[len] == '-')
|
||||
r = 0;
|
||||
|
||||
free(CONST_CAST(void*)dmd.uuid);
|
||||
return r;
|
||||
}
|
||||
|
||||
int PLAIN_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
struct volume_key *vk,
|
||||
@@ -1345,6 +1388,14 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (crypt_loop_device(crypt_get_device_name(cd))) {
|
||||
log_dbg("Trying to resize underlying loop device %s.",
|
||||
crypt_get_device_name(cd));
|
||||
/* Here we always use default size not new_size */
|
||||
if (crypt_loop_resize(crypt_get_device_name(cd)))
|
||||
log_err(NULL, _("Cannot resize loop device.\n"));
|
||||
}
|
||||
|
||||
r = device_block_adjust(cd, dmd.data_device, DEV_OK,
|
||||
dmd.u.crypt.offset, &new_size, &dmd.flags);
|
||||
if (r)
|
||||
@@ -1441,7 +1492,7 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
|
||||
r = LUKS_hdr_restore(backup_file, isLUKS(cd->type) ? &cd->u.luks1.hdr : &hdr, cd);
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1474,7 +1525,7 @@ void crypt_free(struct crypt_device *cd)
|
||||
|
||||
free(cd->type);
|
||||
/* Some structures can contain keys (TCRYPT), wipe it */
|
||||
memset(cd, 0, sizeof(*cd));
|
||||
crypt_memzero(cd, sizeof(*cd));
|
||||
free(cd);
|
||||
}
|
||||
}
|
||||
@@ -1487,7 +1538,14 @@ int crypt_suspend(struct crypt_device *cd,
|
||||
|
||||
log_dbg("Suspending volume %s.", name);
|
||||
|
||||
r = onlyLUKS(cd);
|
||||
if (cd->type) {
|
||||
r = onlyLUKS(cd);
|
||||
} else {
|
||||
r = crypt_uuid_type_cmp(cd, CRYPT_LUKS1);
|
||||
if (r < 0)
|
||||
log_err(cd, _("This operation is supported only for LUKS device.\n"));
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -2382,12 +2440,12 @@ static int _luks_dump(struct crypt_device *cd)
|
||||
int i;
|
||||
|
||||
log_std(cd, "LUKS header information for %s\n\n", mdata_device_path(cd));
|
||||
log_std(cd, "Version: \t%d\n", cd->u.luks1.hdr.version);
|
||||
log_std(cd, "Version: \t%" PRIu16 "\n", cd->u.luks1.hdr.version);
|
||||
log_std(cd, "Cipher name: \t%s\n", cd->u.luks1.hdr.cipherName);
|
||||
log_std(cd, "Cipher mode: \t%s\n", cd->u.luks1.hdr.cipherMode);
|
||||
log_std(cd, "Hash spec: \t%s\n", cd->u.luks1.hdr.hashSpec);
|
||||
log_std(cd, "Payload offset:\t%d\n", cd->u.luks1.hdr.payloadOffset);
|
||||
log_std(cd, "MK bits: \t%d\n", cd->u.luks1.hdr.keyBytes * 8);
|
||||
log_std(cd, "Payload offset:\t%" PRIu32 "\n", cd->u.luks1.hdr.payloadOffset);
|
||||
log_std(cd, "MK bits: \t%" PRIu32 "\n", cd->u.luks1.hdr.keyBytes * 8);
|
||||
log_std(cd, "MK digest: \t");
|
||||
hexprint(cd, cd->u.luks1.hdr.mkDigest, LUKS_DIGESTSIZE, " ");
|
||||
log_std(cd, "\n");
|
||||
@@ -2396,12 +2454,12 @@ static int _luks_dump(struct crypt_device *cd)
|
||||
log_std(cd, "\n \t");
|
||||
hexprint(cd, cd->u.luks1.hdr.mkDigestSalt+LUKS_SALTSIZE/2, LUKS_SALTSIZE/2, " ");
|
||||
log_std(cd, "\n");
|
||||
log_std(cd, "MK iterations: \t%d\n", cd->u.luks1.hdr.mkDigestIterations);
|
||||
log_std(cd, "MK iterations: \t%" PRIu32 "\n", cd->u.luks1.hdr.mkDigestIterations);
|
||||
log_std(cd, "UUID: \t%s\n\n", cd->u.luks1.hdr.uuid);
|
||||
for(i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
if(cd->u.luks1.hdr.keyblock[i].active == LUKS_KEY_ENABLED) {
|
||||
log_std(cd, "Key Slot %d: ENABLED\n",i);
|
||||
log_std(cd, "\tIterations: \t%d\n",
|
||||
log_std(cd, "\tIterations: \t%" PRIu32 "\n",
|
||||
cd->u.luks1.hdr.keyblock[i].passwordIterations);
|
||||
log_std(cd, "\tSalt: \t");
|
||||
hexprint(cd, cd->u.luks1.hdr.keyblock[i].passwordSalt,
|
||||
@@ -2411,9 +2469,9 @@ static int _luks_dump(struct crypt_device *cd)
|
||||
LUKS_SALTSIZE/2, LUKS_SALTSIZE/2, " ");
|
||||
log_std(cd, "\n");
|
||||
|
||||
log_std(cd, "\tKey material offset:\t%d\n",
|
||||
log_std(cd, "\tKey material offset:\t%" PRIu32 "\n",
|
||||
cd->u.luks1.hdr.keyblock[i].keyMaterialOffset);
|
||||
log_std(cd, "\tAF stripes: \t%d\n",
|
||||
log_std(cd, "\tAF stripes: \t%" PRIu32 "\n",
|
||||
cd->u.luks1.hdr.keyblock[i].stripes);
|
||||
}
|
||||
else
|
||||
@@ -2678,8 +2736,3 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) libcryptsetup_ctor(void)
|
||||
{
|
||||
crypt_fips_libcryptsetup_check();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) volume handling
|
||||
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
* Copyright (C) 2012-2015, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -33,16 +33,23 @@
|
||||
/* TCRYPT PBKDF variants */
|
||||
static struct {
|
||||
unsigned int legacy:1;
|
||||
unsigned int veracrypt:1;
|
||||
const char *name;
|
||||
const char *hash;
|
||||
unsigned int iterations;
|
||||
} tcrypt_kdf[] = {
|
||||
{ 0, "pbkdf2", "ripemd160", 2000 },
|
||||
{ 0, "pbkdf2", "ripemd160", 1000 },
|
||||
{ 0, "pbkdf2", "sha512", 1000 },
|
||||
{ 0, "pbkdf2", "whirlpool", 1000 },
|
||||
{ 1, "pbkdf2", "sha1", 2000 },
|
||||
{ 0, NULL, NULL, 0 }
|
||||
{ 0, 0, "pbkdf2", "ripemd160", 2000 },
|
||||
{ 0, 0, "pbkdf2", "ripemd160", 1000 },
|
||||
{ 0, 0, "pbkdf2", "sha512", 1000 },
|
||||
{ 0, 0, "pbkdf2", "whirlpool", 1000 },
|
||||
{ 1, 0, "pbkdf2", "sha1", 2000 },
|
||||
{ 0, 1, "pbkdf2", "sha512", 500000 },
|
||||
{ 0, 1, "pbkdf2", "ripemd160", 655331 },
|
||||
{ 0, 1, "pbkdf2", "ripemd160", 327661 }, // boot only
|
||||
{ 0, 1, "pbkdf2", "whirlpool", 500000 },
|
||||
{ 0, 1, "pbkdf2", "sha256", 500000 }, // VeraCrypt 1.0f
|
||||
{ 0, 1, "pbkdf2", "sha256", 200000 }, // boot only
|
||||
{ 0, 0, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
struct tcrypt_alg {
|
||||
@@ -196,7 +203,7 @@ static int TCRYPT_hdr_from_disk(struct tcrypt_phdr *hdr,
|
||||
|
||||
/* Convert header to cpu format */
|
||||
hdr->d.version = be16_to_cpu(hdr->d.version);
|
||||
hdr->d.version_tc = le16_to_cpu(hdr->d.version_tc);
|
||||
hdr->d.version_tc = be16_to_cpu(hdr->d.version_tc);
|
||||
|
||||
hdr->d.keys_crc32 = be32_to_cpu(hdr->d.keys_crc32);
|
||||
|
||||
@@ -269,8 +276,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
|
||||
}
|
||||
|
||||
crypt_cipher_destroy(cipher);
|
||||
memset(iv, 0, bs);
|
||||
memset(iv_old, 0, bs);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -336,8 +343,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
|
||||
crypt_cipher_destroy(cipher);
|
||||
}
|
||||
|
||||
memset(backend_key, 0, sizeof(backend_key));
|
||||
memset(iv, 0, TCRYPT_HDR_IV_LEN);
|
||||
crypt_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -387,19 +394,19 @@ out:
|
||||
if (cipher[j])
|
||||
crypt_cipher_destroy(cipher[j]);
|
||||
|
||||
memset(iv, 0, bs);
|
||||
memset(iv_old, 0, bs);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
const char *key, int legacy_modes)
|
||||
const char *key, uint32_t flags)
|
||||
{
|
||||
struct tcrypt_phdr hdr2;
|
||||
int i, j, r = -EINVAL;
|
||||
|
||||
for (i = 0; tcrypt_cipher[i].chain_count; i++) {
|
||||
if (!legacy_modes && tcrypt_cipher[i].legacy)
|
||||
if (!(flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_cipher[i].legacy)
|
||||
continue;
|
||||
log_dbg("TCRYPT: trying cipher %s-%s",
|
||||
tcrypt_cipher[i].long_name, tcrypt_cipher[i].mode);
|
||||
@@ -431,10 +438,17 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
r = i;
|
||||
break;
|
||||
}
|
||||
if ((flags & CRYPT_TCRYPT_VERA_MODES) &&
|
||||
!strncmp(hdr2.d.magic, VCRYPT_HDR_MAGIC, TCRYPT_HDR_MAGIC_LEN)) {
|
||||
log_dbg("TCRYPT: Signature magic detected (Veracrypt).");
|
||||
memcpy(&hdr->e, &hdr2.e, TCRYPT_HDR_LEN);
|
||||
r = i;
|
||||
break;
|
||||
}
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
memset(&hdr2, 0, sizeof(hdr2));
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -471,8 +485,8 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
j %= TCRYPT_KEY_POOL_LEN;
|
||||
}
|
||||
|
||||
memset(&crc, 0, sizeof(crc));
|
||||
memset(data, 0, TCRYPT_KEYFILE_LEN);
|
||||
crypt_memzero(&crc, sizeof(crc));
|
||||
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -485,7 +499,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
size_t passphrase_size;
|
||||
char *key;
|
||||
unsigned int i, skipped = 0;
|
||||
int r = -EPERM, legacy_modes;
|
||||
int r = -EPERM;
|
||||
|
||||
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
|
||||
return -ENOMEM;
|
||||
@@ -512,9 +526,10 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
for (i = 0; i < params->passphrase_size; i++)
|
||||
pwd[i] += params->passphrase[i];
|
||||
|
||||
legacy_modes = params->flags & CRYPT_TCRYPT_LEGACY_MODES ? 1 : 0;
|
||||
for (i = 0; tcrypt_kdf[i].name; i++) {
|
||||
if (!legacy_modes && tcrypt_kdf[i].legacy)
|
||||
if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_kdf[i].legacy)
|
||||
continue;
|
||||
if (!(params->flags & CRYPT_TCRYPT_VERA_MODES) && tcrypt_kdf[i].veracrypt)
|
||||
continue;
|
||||
/* Derive header key */
|
||||
log_dbg("TCRYPT: trying KDF: %s-%s-%d.",
|
||||
@@ -533,7 +548,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
break;
|
||||
|
||||
/* Decrypt header */
|
||||
r = TCRYPT_decrypt_hdr(cd, hdr, key, legacy_modes);
|
||||
r = TCRYPT_decrypt_hdr(cd, hdr, key, params->flags);
|
||||
if (r == -ENOENT) {
|
||||
skipped++;
|
||||
r = -EPERM;
|
||||
@@ -553,18 +568,19 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
|
||||
r = TCRYPT_hdr_from_disk(hdr, params, i, r);
|
||||
if (!r) {
|
||||
log_dbg("TCRYPT: Header version: %d, req. %d, sector %d"
|
||||
log_dbg("TCRYPT: Magic: %s, Header version: %d, req. %d, sector %d"
|
||||
", mk_offset %" PRIu64 ", hidden_size %" PRIu64
|
||||
", volume size %" PRIu64, (int)hdr->d.version,
|
||||
(int)hdr->d.version_tc, (int)hdr->d.sector_size,
|
||||
", volume size %" PRIu64, tcrypt_kdf[i].veracrypt ?
|
||||
VCRYPT_HDR_MAGIC : TCRYPT_HDR_MAGIC,
|
||||
(int)hdr->d.version, (int)hdr->d.version_tc, (int)hdr->d.sector_size,
|
||||
hdr->d.mk_offset, hdr->d.hidden_volume_size, hdr->d.volume_size);
|
||||
log_dbg("TCRYPT: Header cipher %s-%s, key size %zu",
|
||||
params->cipher, params->mode, params->key_size);
|
||||
}
|
||||
out:
|
||||
memset(pwd, 0, TCRYPT_KEY_POOL_LEN);
|
||||
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
if (key)
|
||||
memset(key, 0, TCRYPT_HDR_KEY_LEN);
|
||||
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
free(key);
|
||||
return r;
|
||||
}
|
||||
@@ -1026,11 +1042,13 @@ int TCRYPT_dump(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params)
|
||||
{
|
||||
log_std(cd, "TCRYPT header information for %s\n",
|
||||
log_std(cd, "%s header information for %s\n",
|
||||
hdr->d.magic[0] == 'T' ? "TCRYPT" : "VERACRYPT",
|
||||
device_path(crypt_metadata_device(cd)));
|
||||
if (hdr->d.version) {
|
||||
log_std(cd, "Version: \t%d\n", hdr->d.version);
|
||||
log_std(cd, "Driver req.:\t%d\n", hdr->d.version_tc);
|
||||
log_std(cd, "Driver req.:\t%x.%x\n", hdr->d.version_tc >> 8,
|
||||
hdr->d.version_tc & 0xFF);
|
||||
|
||||
log_std(cd, "Sector size:\t%" PRIu32 "\n", hdr->d.sector_size);
|
||||
log_std(cd, "MK offset:\t%" PRIu64 "\n", hdr->d.mk_offset);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define TCRYPT_HDR_LEN 448
|
||||
#define TCRYPT_HDR_KEY_LEN 192
|
||||
#define TCRYPT_HDR_MAGIC "TRUE"
|
||||
#define VCRYPT_HDR_MAGIC "VERA"
|
||||
#define TCRYPT_HDR_MAGIC_LEN 4
|
||||
|
||||
#define TCRYPT_HDR_HIDDEN_OFFSET_OLD -1536
|
||||
|
||||
@@ -81,6 +81,18 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
* Also used in safe allocations for explicit memory wipe.
|
||||
*/
|
||||
void crypt_memzero(void *s, size_t n)
|
||||
{
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
|
||||
while(n--)
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
@@ -94,7 +106,7 @@ void *crypt_safe_alloc(size_t size)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
memset(&alloc->data, 0, size);
|
||||
crypt_memzero(&alloc->data, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
@@ -110,7 +122,7 @@ void crypt_safe_free(void *data)
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
memset(data, 0, alloc->size);
|
||||
crypt_memzero(data, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
@@ -157,7 +169,7 @@ static int untimed_read(int fd, char *pass, size_t maxlen)
|
||||
static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
|
||||
{
|
||||
struct timeval t;
|
||||
fd_set fds;
|
||||
fd_set fds = {}; /* Just to avoid scan-build false report for FD_SET */
|
||||
int failed = -1;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
@@ -176,16 +188,18 @@ static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
|
||||
{
|
||||
struct termios orig, tmp;
|
||||
int failed = -1;
|
||||
int infd = STDIN_FILENO, outfd;
|
||||
int infd, outfd;
|
||||
|
||||
if (maxlen < 1)
|
||||
goto out_err;
|
||||
return failed;
|
||||
|
||||
/* Read and write to /dev/tty if available */
|
||||
if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
|
||||
infd = open("/dev/tty", O_RDWR);
|
||||
if (infd == -1) {
|
||||
infd = STDIN_FILENO;
|
||||
outfd = STDERR_FILENO;
|
||||
}
|
||||
} else
|
||||
outfd = infd;
|
||||
|
||||
if (tcgetattr(infd, &orig))
|
||||
goto out_err;
|
||||
@@ -320,7 +334,7 @@ int crypt_get_key(const char *prompt,
|
||||
struct crypt_device *cd)
|
||||
{
|
||||
int fd, regular_file, read_stdin, char_read, unlimited_read = 0;
|
||||
int r = -EINVAL;
|
||||
int r = -EINVAL, newline;
|
||||
char *pass = NULL;
|
||||
size_t buflen, i, file_read_size;
|
||||
struct stat st;
|
||||
@@ -394,7 +408,7 @@ int crypt_get_key(const char *prompt,
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
for(i = 0; i < keyfile_size_max; i++) {
|
||||
for(i = 0, newline = 0; i < keyfile_size_max; i++) {
|
||||
if(i == buflen) {
|
||||
buflen += 4096;
|
||||
pass = crypt_safe_realloc(pass, buflen);
|
||||
@@ -412,12 +426,17 @@ int crypt_get_key(const char *prompt,
|
||||
}
|
||||
|
||||
/* Stop on newline only if not requested read from keyfile */
|
||||
if(char_read == 0 || (!key_file && pass[i] == '\n'))
|
||||
if (char_read == 0)
|
||||
break;
|
||||
if (!key_file && pass[i] == '\n') {
|
||||
newline = 1;
|
||||
pass[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fail if piped input dies reading nothing */
|
||||
if(!i && !regular_file) {
|
||||
if(!i && !regular_file && !newline) {
|
||||
log_dbg("Nothing read on input.");
|
||||
r = -EPIPE;
|
||||
goto out_err;
|
||||
@@ -471,68 +490,3 @@ ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
*result = bytes;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device size string parsing, suffixes:
|
||||
* s|S - 512 bytes sectors
|
||||
* k |K |m |M |g |G |t |T - 1024 base
|
||||
* kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base
|
||||
* kb |KB |mM |MB |gB |GB |tB |TB - 1000 base
|
||||
*/
|
||||
int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size)
|
||||
{
|
||||
char *endp = NULL;
|
||||
size_t len;
|
||||
uint64_t mult_base, mult, tmp;
|
||||
|
||||
*size = strtoull(s, &endp, 10);
|
||||
if (!isdigit(s[0]) ||
|
||||
(errno == ERANGE && *size == ULLONG_MAX) ||
|
||||
(errno != 0 && *size == 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (!endp || !*endp)
|
||||
return 0;
|
||||
|
||||
len = strlen(endp);
|
||||
/* Allow "B" and "iB" suffixes */
|
||||
if (len > 3 ||
|
||||
(len == 3 && (endp[1] != 'i' || endp[2] != 'B')) ||
|
||||
(len == 2 && endp[1] != 'B'))
|
||||
return -EINVAL;
|
||||
|
||||
if (len == 1 || len == 3)
|
||||
mult_base = 1024;
|
||||
else
|
||||
mult_base = 1000;
|
||||
|
||||
mult = 1;
|
||||
switch (endp[0]) {
|
||||
case 's':
|
||||
case 'S': mult = 512;
|
||||
break;
|
||||
case 't':
|
||||
case 'T': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'g':
|
||||
case 'G': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'm':
|
||||
case 'M': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'k':
|
||||
case 'K': mult *= mult_base;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = *size * mult;
|
||||
if ((tmp / *size) != mult) {
|
||||
log_dbg("Device size overflow.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*size = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ void *crypt_safe_alloc(size_t size);
|
||||
void crypt_safe_free(void *data);
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
void crypt_memzero(void *s, size_t n);
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
|
||||
int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size);
|
||||
|
||||
#endif /* _UTILS_CRYPT_H */
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
* Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -38,20 +38,106 @@ struct device {
|
||||
char *file_path;
|
||||
int loop_fd;
|
||||
|
||||
int o_direct:1;
|
||||
int init_done:1;
|
||||
};
|
||||
|
||||
static int device_ready(const char *device)
|
||||
static int device_block_size_fd(int fd, size_t *min_size)
|
||||
{
|
||||
int devfd, r = 0;
|
||||
struct stat st;
|
||||
int bsize = 0, r = -EINVAL;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (S_ISREG(st.st_mode))
|
||||
r = (int)crypt_getpagesize();
|
||||
else if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
|
||||
r = bsize;
|
||||
else
|
||||
r = -EINVAL;
|
||||
|
||||
if (r < 0 || !min_size)
|
||||
return r;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
/* file can be empty as well */
|
||||
if (st.st_size > bsize)
|
||||
*min_size = bsize;
|
||||
else
|
||||
*min_size = st.st_size;
|
||||
} else {
|
||||
/* block device must have at least one block */
|
||||
*min_size = bsize;
|
||||
}
|
||||
|
||||
return bsize;
|
||||
}
|
||||
|
||||
static int device_read_test(int devfd)
|
||||
{
|
||||
char buffer[512];
|
||||
int blocksize, r = -EIO;
|
||||
size_t minsize = 0;
|
||||
|
||||
blocksize = device_block_size_fd(devfd, &minsize);
|
||||
|
||||
if (blocksize < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (minsize == 0)
|
||||
return 0;
|
||||
|
||||
if (minsize > sizeof(buffer))
|
||||
minsize = sizeof(buffer);
|
||||
|
||||
if (read_blockwise(devfd, blocksize, buffer, minsize) == (ssize_t)minsize)
|
||||
r = 0;
|
||||
|
||||
crypt_memzero(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* The direct-io is always preferred. The header is usually mapped to the same
|
||||
* device and can be accessed when the rest of device is mapped to data device.
|
||||
* Using dirct-io encsures that we do not mess with data in cache.
|
||||
* (But proper alignment should prevent this in the first place.)
|
||||
* The read test is needed to detect broken configurations (seen with remote
|
||||
* block devices) that allow open with direct-io but then fails on read.
|
||||
*/
|
||||
static int device_ready(struct device *device, int check_directio)
|
||||
{
|
||||
int devfd = -1, r = 0;
|
||||
struct stat st;
|
||||
|
||||
log_dbg("Trying to open and read device %s.", device);
|
||||
devfd = open(device, O_RDONLY);
|
||||
device->o_direct = 0;
|
||||
if (check_directio) {
|
||||
log_dbg("Trying to open and read device %s with direct-io.",
|
||||
device_path(device));
|
||||
devfd = open(device_path(device), O_RDONLY | O_DIRECT);
|
||||
if (devfd >= 0) {
|
||||
if (device_read_test(devfd) == 0) {
|
||||
device->o_direct = 1;
|
||||
} else {
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (devfd < 0) {
|
||||
log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device);
|
||||
log_dbg("Trying to open device %s without direct-io.",
|
||||
device_path(device));
|
||||
devfd = open(device_path(device), O_RDONLY);
|
||||
}
|
||||
|
||||
if (devfd < 0) {
|
||||
log_err(NULL, _("Device %s doesn't exist or access denied.\n"),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fstat(devfd, &st) < 0)
|
||||
r = -EINVAL;
|
||||
else if (!S_ISBLK(st.st_mode))
|
||||
@@ -65,12 +151,14 @@ int device_open(struct device *device, int flags)
|
||||
{
|
||||
int devfd;
|
||||
|
||||
devfd = open(device_path(device), flags | O_DIRECT | O_SYNC);
|
||||
if (devfd < 0 && errno == EINVAL) {
|
||||
log_dbg("Trying to open device %s without direct-io.",
|
||||
device_path(device));
|
||||
devfd = open(device_path(device), flags | O_SYNC);
|
||||
}
|
||||
flags |= O_SYNC;
|
||||
if (device->o_direct)
|
||||
flags |= O_DIRECT;
|
||||
|
||||
devfd = open(device_path(device), flags);
|
||||
|
||||
if (devfd < 0)
|
||||
log_dbg("Cannot open device %s.", device_path(device));
|
||||
|
||||
return devfd;
|
||||
}
|
||||
@@ -90,24 +178,24 @@ int device_alloc(struct device **device, const char *path)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dev, 0, sizeof(struct device));
|
||||
dev->path = strdup(path);
|
||||
if (!dev->path) {
|
||||
free(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev->loop_fd = -1;
|
||||
|
||||
r = device_ready(path);
|
||||
r = device_ready(dev, 1);
|
||||
if (!r) {
|
||||
dev->init_done = 1;
|
||||
} else if (r == -ENOTBLK) {
|
||||
/* alloc loop later */
|
||||
} else if (r < 0) {
|
||||
free(dev->path);
|
||||
free(dev);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
|
||||
dev->path = strdup(path);
|
||||
if (!dev->path) {
|
||||
free(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*device = dev;
|
||||
return 0;
|
||||
}
|
||||
@@ -208,27 +296,23 @@ out:
|
||||
|
||||
int device_block_size(struct device *device)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, bsize = 0, r = -EINVAL;
|
||||
int fd, r = -EINVAL;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
if (device->file_path)
|
||||
return (int)crypt_getpagesize();
|
||||
|
||||
fd = open(device->path, O_RDONLY);
|
||||
if(fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
goto out;
|
||||
r = device_block_size_fd(fd, NULL);
|
||||
|
||||
if (S_ISREG(st.st_mode) || device->file_path) {
|
||||
r = (int)crypt_getpagesize();
|
||||
goto out;
|
||||
}
|
||||
if (r <= 0)
|
||||
log_dbg("Cannot get block size for device %s.", device_path(device));
|
||||
|
||||
if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
|
||||
r = bsize;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
@@ -333,7 +417,7 @@ out:
|
||||
|
||||
static int device_internal_prepare(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
char *loop_device;
|
||||
char *loop_device, *file_path = NULL;
|
||||
int r, loop_fd, readonly = 0;
|
||||
|
||||
if (device->init_done)
|
||||
@@ -359,15 +443,19 @@ static int device_internal_prepare(struct crypt_device *cd, struct device *devic
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = device_ready(loop_device);
|
||||
file_path = device->path;
|
||||
device->path = loop_device;
|
||||
|
||||
r = device_ready(device, device->o_direct);
|
||||
if (r < 0) {
|
||||
device->path = file_path;
|
||||
crypt_loop_detach(loop_device);
|
||||
free(loop_device);
|
||||
return r;
|
||||
}
|
||||
|
||||
device->loop_fd = loop_fd;
|
||||
device->file_path = device->path;
|
||||
device->path = loop_device;
|
||||
device->file_path = file_path;
|
||||
device->init_done = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
* Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -40,6 +40,9 @@ struct device;
|
||||
#define DM_DISCARDS_SUPPORTED (1 << 4) /* discards/TRIM option is supported */
|
||||
#define DM_VERITY_SUPPORTED (1 << 5) /* dm-verity target supported */
|
||||
#define DM_TCW_SUPPORTED (1 << 6) /* tcw (TCRYPT CBC with whitening) */
|
||||
#define DM_SAME_CPU_CRYPT_SUPPORTED (1 << 7) /* same_cpu_crypt */
|
||||
#define DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED (1 << 8) /* submit_from_crypt_cpus */
|
||||
|
||||
uint32_t dm_flags(void);
|
||||
|
||||
#define DM_ACTIVE_DEVICE (1 << 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2013, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2015, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -18,37 +18,29 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "nls.h"
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "utils_fips.h"
|
||||
|
||||
#if !ENABLE_FIPS
|
||||
int crypt_fips_mode(void) { return 0; }
|
||||
void crypt_fips_libcryptsetup_check(void) {}
|
||||
#else
|
||||
#include <fipscheck.h>
|
||||
static int kernel_fips_mode(void)
|
||||
{
|
||||
int fd;
|
||||
char buf[1] = "";
|
||||
|
||||
if ((fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY)) >= 0) {
|
||||
while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return (buf[0] == '1') ? 1 : 0;
|
||||
}
|
||||
|
||||
int crypt_fips_mode(void)
|
||||
{
|
||||
return FIPSCHECK_kernel_fips_mode() && !access(FIPS_MODULE_FILE, F_OK);
|
||||
}
|
||||
|
||||
static void crypt_fips_verify(const char *name, const char *function)
|
||||
{
|
||||
if (access(FIPS_MODULE_FILE, F_OK))
|
||||
return;
|
||||
|
||||
if (!FIPSCHECK_verify(name, function)) {
|
||||
fputs(_("FIPS checksum verification failed.\n"), stderr);
|
||||
if (FIPSCHECK_kernel_fips_mode())
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void crypt_fips_libcryptsetup_check(void)
|
||||
{
|
||||
crypt_fips_verify(LIBCRYPTSETUP_VERSION_FIPS, "crypt_init");
|
||||
return kernel_fips_mode() && !access("/etc/system-fips", F_OK);
|
||||
}
|
||||
#endif /* ENABLE_FIPS */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2013, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2015, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -21,9 +21,6 @@
|
||||
#ifndef _UTILS_FIPS_H
|
||||
#define _UTILS_FIPS_H
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
int crypt_fips_mode(void);
|
||||
void crypt_fips_libcryptsetup_check(void);
|
||||
|
||||
#endif /* _UTILS_FIPS_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
* Copyright (C) 2011-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -42,6 +42,10 @@
|
||||
#define LOOP_CTL_GET_FREE 0x4C82
|
||||
#endif
|
||||
|
||||
#ifndef LOOP_SET_CAPACITY
|
||||
#define LOOP_SET_CAPACITY 0x4C07
|
||||
#endif
|
||||
|
||||
static char *crypt_loop_get_device_old(void)
|
||||
{
|
||||
char dev[20];
|
||||
@@ -157,6 +161,21 @@ int crypt_loop_detach(const char *loop)
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_loop_resize(const char *loop)
|
||||
{
|
||||
int loop_fd = -1, r = 1;
|
||||
|
||||
loop_fd = open(loop, O_RDONLY);
|
||||
if (loop_fd < 0)
|
||||
return 1;
|
||||
|
||||
if (!ioctl(loop_fd, LOOP_SET_CAPACITY, 0))
|
||||
r = 0;
|
||||
|
||||
close(loop_fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static char *_ioctl_backing_file(const char *loop)
|
||||
{
|
||||
struct loop_info64 lo64 = {0};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,5 +30,6 @@ int crypt_loop_device(const char *loop);
|
||||
int crypt_loop_attach(const char *loop, const char *file, int offset,
|
||||
int autoclear, int *readonly);
|
||||
int crypt_loop_detach(const char *loop);
|
||||
int crypt_loop_resize(const char *loop);
|
||||
|
||||
#endif /* _UTILS_LOOP_H */
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#define VERITY_SIGNATURE "verity\0\0"
|
||||
|
||||
/* http://code.google.com/p/cryptsetup/wiki/DMVerity#Verity_superblock_format */
|
||||
/* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity#verity-superblock-format */
|
||||
struct verity_sb {
|
||||
uint8_t signature[8]; /* "verity\0\0" */
|
||||
uint32_t version; /* superblock version */
|
||||
|
||||
@@ -35,7 +35,7 @@ struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key)
|
||||
if (key)
|
||||
memcpy(&vk->key, key, keylength);
|
||||
else
|
||||
memset(&vk->key, 0, keylength);
|
||||
crypt_memzero(&vk->key, keylength);
|
||||
|
||||
return vk;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key)
|
||||
void crypt_free_volume_key(struct volume_key *vk)
|
||||
{
|
||||
if (vk) {
|
||||
memset(vk->key, 0, vk->keylength);
|
||||
crypt_memzero(vk->key, vk->keylength);
|
||||
vk->keylength = 0;
|
||||
free(vk);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH CRYPTSETUP-REENCRYPT "8" "December 2013" "cryptsetup-reencrypt" "Maintenance Commands"
|
||||
.TH CRYPTSETUP-REENCRYPT "8" "January 2015" "cryptsetup-reencrypt" "Maintenance Commands"
|
||||
.SH NAME
|
||||
cryptsetup-reencrypt - tool for offline LUKS device re-encryption
|
||||
.SH SYNOPSIS
|
||||
@@ -36,9 +36,15 @@ To start (or continue) re-encryption for <device> use:
|
||||
.PP
|
||||
\fIcryptsetup-reencrypt\fR <device>
|
||||
|
||||
\fB<options>\fR can be [\-\-block-size, \-\-cipher, \-\-hash, \-\-iter-time,
|
||||
\-\-use-random | \-\-use-urandom, \-\-key-file, \-\-key-slot, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-tries, \-\-use-directio, \-\-use-fsync, \-\-write-log]
|
||||
\fB<options>\fR can be [\-\-batch-mode, \-\-block-size, \-\-cipher, \-\-debug,
|
||||
\-\-device-size, \-\-hash, \-\-iter-time, \-\-use-random | \-\-use-urandom,
|
||||
\-\-keep-key, \-\-key-size, \-\-key-file, \-\-key-slot, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-tries, \-\-use-directio, \-\-use-fsync, \-\-verbose, \-\-write-log]
|
||||
|
||||
To encrypt data on (not yet encrypted) device, use \fI\-\-new\fR with combination
|
||||
with \fI\-\-reduce-device-size\fR.
|
||||
|
||||
To remove encryption from device, use \fI\-\-decrypt\fR.
|
||||
|
||||
For detailed description of encryption and key file options see \fIcryptsetup(8)\fR
|
||||
man page.
|
||||
@@ -68,7 +74,7 @@ you can destructively shrink device with \-\-reduce-device-size option.
|
||||
.B "\-\-hash, \-h \fI<hash-spec>\fR"
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key digest.
|
||||
|
||||
NOTE: if this parameter is not specified, default hash algorithm is always used
|
||||
\fBNOTE:\fR if this parameter is not specified, default hash algorithm is always used
|
||||
for new device header.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i \fI<milliseconds>\fR"
|
||||
@@ -83,7 +89,7 @@ Define which kernel random number generator will be used to create the volume ke
|
||||
.B "\-\-key-file, \-d \fIname\fR"
|
||||
Read the passphrase from file.
|
||||
|
||||
WARNING: \-\-key-file option can be used only if there only one active keyslot,
|
||||
\fBWARNING:\fR \-\-key-file option can be used only if there only one active keyslot,
|
||||
or alternatively, also if \-\-key-slot option is specified (then all other keyslots
|
||||
will be disabled in new LUKS device).
|
||||
|
||||
@@ -93,7 +99,7 @@ passphrases.
|
||||
.B "\-\-key-slot, \-S <0-7>"
|
||||
Specify which key slot is used.
|
||||
|
||||
WARNING: All other keyslots will be disabled if this option is used.
|
||||
\fBWARNING:\fR All other keyslots will be disabled if this option is used.
|
||||
.TP
|
||||
.B "\-\-keyfile-offset \fIvalue\fR"
|
||||
Skip \fIvalue\fR bytes at the beginning of the key file.
|
||||
@@ -123,14 +129,14 @@ Instead of real device size, use specified value.
|
||||
It means that only specified area (from the start of the device
|
||||
to the specified size) will be reencrypted.
|
||||
|
||||
WARNING: This is destructive operation.
|
||||
\fBWARNING:\fR This is destructive operation.
|
||||
|
||||
If no unit suffix is specified, the size is in bytes.
|
||||
|
||||
Unit suffix can be S for 512 byte sectors, K/M/G/T (or KiB,MiB,GiB,TiB)
|
||||
for units with 1024 base or KB/MB/GB/TB for 1000 base (SI scale).
|
||||
|
||||
WARNING: This is destructive operation.
|
||||
\fBWARNING:\fR This is destructive operation.
|
||||
.TP
|
||||
.B "\-\-reduce-device-size \fIsize[units]\fR"
|
||||
Enlarge data offset to specified value by shrinking device size.
|
||||
@@ -144,7 +150,7 @@ partition (so last sectors contains no data).
|
||||
|
||||
For units suffix see \-\-device-size parameter description.
|
||||
|
||||
WARNING: This is destructive operation and cannot be reverted.
|
||||
\fBWARNING:\fR This is destructive operation and cannot be reverted.
|
||||
Use with extreme care - shrinked filesystems are usually unrecoverable.
|
||||
|
||||
You cannot shrink device more than by 64 MiB (131072 sectors).
|
||||
@@ -154,17 +160,23 @@ Create new header (encrypt not yet encrypted device).
|
||||
|
||||
This option must be used together with \-\-reduce-device-size.
|
||||
|
||||
WARNING: This is destructive operation and cannot be reverted.
|
||||
\fBWARNING:\fR This is destructive operation and cannot be reverted.
|
||||
.TP
|
||||
.B "\-\-decrypt"
|
||||
Remove encryption (decrypt already encrypted device and remove LUKS header).
|
||||
|
||||
\fBWARNING:\fR This is destructive operation and cannot be reverted.
|
||||
.TP
|
||||
.B "\-\-use-directio"
|
||||
Use direct-io (O_DIRECT) for all read/write data operations.
|
||||
Use direct-io (O_DIRECT) for all read/write data operations related
|
||||
to block device undergoing reencryption.
|
||||
|
||||
Useful if direct-io operations perform better than normal buffered
|
||||
operations (e.g. in virtual environments).
|
||||
.TP
|
||||
.B "\-\-use-fsync"
|
||||
Use fsync call after every written block.
|
||||
Use fsync call after every written block. This applies for reencryption
|
||||
log files as well.
|
||||
.TP
|
||||
.B "\-\-write-log"
|
||||
Update log file after every block write. This can slow down reencryption
|
||||
@@ -201,6 +213,10 @@ fdisk \-u /dev/sdb # move sdb1 partition end + 4096 sectors
|
||||
(or use resize2fs or tool for your filesystem and shrink it)
|
||||
|
||||
cryptsetup-reencrypt /dev/sdb1 \-\-new \-\-reduce-device-size 4096S
|
||||
.TP
|
||||
Remove LUKS encryption completely
|
||||
|
||||
cryptsetup-reencrypt /dev/sdb1 \-\-decrypt
|
||||
|
||||
.SH REPORTING BUGS
|
||||
Report bugs, including ones in the documentation, on
|
||||
@@ -211,11 +227,11 @@ Please attach the output of the failed command with the
|
||||
.SH AUTHORS
|
||||
Cryptsetup-reencrypt was written by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012-2014 Milan Broz
|
||||
Copyright \(co 2012-2015 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012-2013 Red Hat, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH SEE ALSO
|
||||
The project website at \fBhttp://code.google.com/p/cryptsetup/\fR
|
||||
The project website at \fBhttps://gitlab.com/cryptsetup/cryptsetup\fR
|
||||
|
||||
@@ -12,7 +12,7 @@ and can hence offer more features than plain dm-crypt. On the other
|
||||
hand, the header is visible and vulnerable to damage.
|
||||
|
||||
In addition, cryptsetup provides limited support for the use of
|
||||
historic loopaes volumes and for TruerCrypt compatible volumes.
|
||||
historic loopaes volumes and for TrueCrypt compatible volumes.
|
||||
|
||||
.SH PLAIN DM-CRYPT OR LUKS?
|
||||
.PP
|
||||
@@ -160,6 +160,14 @@ Key operations that do not specify a slot affect the first slot
|
||||
that matches the supplied passphrase or the first empty slot if
|
||||
a new passphrase is added.
|
||||
|
||||
The \fB<device>\fR parameter can be also specified by a LUKS UUID in the
|
||||
format UUID=<uuid>. Translation to real device name uses symlinks
|
||||
in /dev/disk/by-uuid directory.
|
||||
|
||||
To specify a detached header, the \fB\-\-header\fR parameter can be used
|
||||
in all LUKS commands and always takes precedence over positional \fB<device>\fR
|
||||
parameter.
|
||||
|
||||
The following are valid LUKS actions:
|
||||
|
||||
\fIluksFormat\fR <device> [<key file>]
|
||||
@@ -196,9 +204,6 @@ successful verification of the supplied passphrase.
|
||||
If the passphrase is not supplied via \-\-key-file, the command
|
||||
prompts for it interactively.
|
||||
|
||||
The <device> parameter can be also specified by LUKS UUID in the
|
||||
format UUID=<uuid>, which uses the symlinks in /dev/disk/by-uuid.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size, \-\-readonly, \-\-test\-passphrase,
|
||||
\-\-allow\-discards, \-\-header, \-\-key-slot, \-\-master\-key\-file].
|
||||
@@ -235,7 +240,7 @@ or read from the file given as positional argument.
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size, \-\-new\-keyfile\-offset,
|
||||
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-master\-key\-file,
|
||||
\-\-iter\-time, \-\-force\-password].
|
||||
\-\-iter\-time, \-\-force\-password, \-\-header].
|
||||
.PP
|
||||
\fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>]
|
||||
.IP
|
||||
@@ -244,7 +249,7 @@ passphrase to be removed can be specified interactively,
|
||||
as positional argument or via \-\-key-file.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size]
|
||||
\-\-keyfile\-size, \-\-header]
|
||||
|
||||
\fBWARNING:\fR If you read the passphrase from stdin
|
||||
(without further argument or with '-' as argument
|
||||
@@ -277,7 +282,7 @@ inaccessible.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size, \-\-new\-keyfile\-offset,
|
||||
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-force\-password].
|
||||
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-force\-password, \-\-header].
|
||||
.PP
|
||||
\fIluksKillSlot\fR <device> <key slot number>
|
||||
.IP
|
||||
@@ -288,7 +293,7 @@ an interactive confirmation when doing so. Removing the last
|
||||
passphrase makes a LUKS container permanently inaccessible.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size].
|
||||
\-\-keyfile\-size, \-\-header].
|
||||
|
||||
\fBWARNING:\fR If you read the passphrase from stdin
|
||||
(without further argument or with '-' as argument
|
||||
@@ -334,7 +339,7 @@ In order to dump the master key, a passphrase has to be supplied,
|
||||
either interactively or via \-\-key\-file.
|
||||
|
||||
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
|
||||
\-\-keyfile\-offset, \-\-keyfile\-size].
|
||||
\-\-keyfile\-offset, \-\-keyfile\-size, \-\-header].
|
||||
|
||||
\fBWARNING:\fR If \-\-dump\-master\-key is used with \-\-key\-file
|
||||
and the argument to \-\-key\-file is '-', no validation question
|
||||
@@ -387,6 +392,14 @@ If the key file is encrypted with GnuPG, then you have to use
|
||||
gpg \-\-decrypt <keyfile> | cryptsetup loopaesOpen \-\-key\-file=\-
|
||||
<device> <name>
|
||||
|
||||
\fBWARNING:\fR The loop-AES extension cannot use direct input of key file
|
||||
on real terminal because the keys are separated by end-of-line and only part
|
||||
of the multi-key file would be read.
|
||||
.br
|
||||
If you need it in script, just use the pipe redirection:
|
||||
.br
|
||||
echo $keyfile | cryptsetup loopaesOpen \-\-key\-file=\- <device> <name>
|
||||
|
||||
Use \fB\-\-keyfile\-size\fR to specify the proper key length if needed.
|
||||
|
||||
Use \fB\-\-offset\fR to specify device offset. Note that the units
|
||||
@@ -406,8 +419,9 @@ size).
|
||||
.PP
|
||||
See also section 7 of the FAQ and \fBhttp://loop-aes.sourceforge.net\fR
|
||||
for more information regarding loop-AES.
|
||||
.SH TCRYPT (TrueCrypt-compatible) EXTENSION
|
||||
cryptsetup supports mapping of TrueCrypt or tcplay encrypted partition
|
||||
.SH TCRYPT (TrueCrypt-compatible and VeraCrypt) EXTENSION
|
||||
cryptsetup supports mapping of TrueCrypt, tcplay or VeraCrypt
|
||||
(with \fB\-\-veracrypt\fR option) encrypted partition
|
||||
using a native Linux kernel API.
|
||||
Header formatting and TCRYPT header change is not supported, cryptsetup
|
||||
never changes TCRYPT header on-device.
|
||||
@@ -425,6 +439,11 @@ Cryptsetup should recognize all header variants, except legacy cipher chains
|
||||
using LRW encryption mode with 64 bits encryption block (namely Blowfish
|
||||
in LRW mode is not recognized, this is limitation of kernel crypto API).
|
||||
|
||||
To recognize VeraCrypt device use \fB\-\-veracrypt\fR option.
|
||||
VeraCrypt is just extension of TrueCrypt header with increased
|
||||
iteration count so unlocking can take quite a lot of time (in comparison
|
||||
with TCRYPT device).
|
||||
|
||||
\fBNOTE:\fR Activation with \fBtcryptOpen\fR is supported only for cipher chains
|
||||
using LRW or XTS encryption modes.
|
||||
|
||||
@@ -795,11 +814,33 @@ because it can make filesystem-level operations visible on
|
||||
the physical device. For example, information leaking
|
||||
filesystem type, used space, etc. may be extractable from
|
||||
the physical device if the discarded blocks can be located
|
||||
later. If in doubt, do no use it.
|
||||
later. If in doubt, do not use it.
|
||||
|
||||
A kernel version of 3.1 or later is needed. For earlier kernels
|
||||
this option is ignored.
|
||||
.TP
|
||||
.B "\-\-perf\-same_cpu_crypt\fR"
|
||||
Perform encryption using the same cpu that IO was submitted on.
|
||||
The default is to use an unbound workqueue so that encryption work
|
||||
is automatically balanced between available CPUs.
|
||||
This option is only relevant for \fIopen\fR action.
|
||||
|
||||
\fBNOTE:\fR This option is available only for low-level dm-crypt
|
||||
performance tuning, use only if you need a change to default dm-crypt
|
||||
behaviour. Needs kernel 4.0 or later.
|
||||
.TP
|
||||
.B "\-\-perf\-submit_from_crypt_cpus\fR"
|
||||
Disable offloading writes to a separate thread after encryption.
|
||||
There are some situations where offloading write bios from the
|
||||
encryption threads to a single thread degrades performance
|
||||
significantly. The default is to offload write bios to the same
|
||||
thread.
|
||||
This option is only relevant for \fIopen\fR action.
|
||||
|
||||
\fBNOTE:\fR This option is available only for low-level dm-crypt
|
||||
performance tuning, use only if you need a change to default dm-crypt
|
||||
behaviour. Needs kernel 4.0 or later.
|
||||
.TP
|
||||
.B "\-\-test\-passphrase\fR"
|
||||
Do not activate device, just verify passphrase.
|
||||
This option is only relevant for \fIopen\fR action (the device
|
||||
@@ -869,12 +910,12 @@ of the used cipher, or the size specified with \-s.
|
||||
\fBFrom stdin\fR: Reading will continue until a newline (or until
|
||||
the maximum input size is reached), with the trailing newline
|
||||
stripped. The maximum input size is defined by the same
|
||||
compiled-in default as for the maximum key file size and can
|
||||
compiled-in default as for the maximum key file size and can
|
||||
be overwritten using \-\-keyfile-size option.
|
||||
|
||||
The data read will be hashed with the default hash
|
||||
or the hash specified with \-\-hash.
|
||||
The has result will be truncated to the key size
|
||||
The hash result will be truncated to the key size
|
||||
of the used cipher, or the size specified with \-s.
|
||||
|
||||
Note that if \-\-key-file=- is used for reading the key
|
||||
@@ -891,8 +932,16 @@ less than the key size.
|
||||
\fBFrom a key file\fR: It will be truncated to the
|
||||
key size of the used cipher or the size given by \-s
|
||||
and directly used as binary key.
|
||||
if the key file is shorter than the key, cryptsetup
|
||||
|
||||
\fBWARNING\fR: The \-\-hash argument is being ignored.
|
||||
The \-\-hash option is usable only for stdin input in plain mode.
|
||||
|
||||
If the key file is shorter than the key, cryptsetup
|
||||
will quit with an error.
|
||||
The maximum input size is defined by the same
|
||||
compiled-in default as for the maximum key file size and can
|
||||
be overwritten using \-\-keyfile-size option.
|
||||
|
||||
|
||||
.SH NOTES ON PASSPHRASE PROCESSING FOR LUKS
|
||||
LUKS uses PBKDF2 to protect against dictionary attacks
|
||||
@@ -1016,22 +1065,22 @@ Copyright \(co 2004 Jana Saout
|
||||
.br
|
||||
Copyright \(co 2004-2006 Clemens Fruhwirth
|
||||
.br
|
||||
Copyright \(co 2009-2012 Red Hat, Inc.
|
||||
Copyright \(co 2009-2015 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2009-2014 Milan Broz
|
||||
Copyright \(co 2009-2015 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012-2014 Arno Wagner
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH SEE ALSO
|
||||
The LUKS website at \fBhttp://code.google.com/p/cryptsetup/\fR
|
||||
The LUKS website at \fBhttps://gitlab.com/cryptsetup/cryptsetup/\fR
|
||||
|
||||
The cryptsetup FAQ, contained in the distribution package and
|
||||
online at
|
||||
\fBhttp://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions\fR
|
||||
\fBhttps://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions\fR
|
||||
|
||||
The cryptsetup mailing list and list archive, see FAQ entry 1.6.
|
||||
|
||||
The LUKS on-disk format specification available at
|
||||
\fBhttp://code.google.com/p/cryptsetup/wiki/Specification\fR
|
||||
\fBhttps://gitlab.com/cryptsetup/cryptsetup/wikis/Specification\fR
|
||||
|
||||
@@ -137,7 +137,7 @@ Copyright \(co 2012-2014 Milan Broz
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH SEE ALSO
|
||||
The project website at \fBhttp://code.google.com/p/cryptsetup/\fR
|
||||
The project website at \fBhttps://gitlab.com/cryptsetup/cryptsetup\fR
|
||||
|
||||
The verity on-disk format specification available at
|
||||
\fBhttp://code.google.com/p/cryptsetup/wiki/DMVerity\fR
|
||||
\fBhttps://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity\fR
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
cs
|
||||
da
|
||||
de
|
||||
es
|
||||
fi
|
||||
@@ -7,6 +8,8 @@ id
|
||||
it
|
||||
nl
|
||||
pl
|
||||
sr
|
||||
sv
|
||||
uk
|
||||
vi
|
||||
zh_CN
|
||||
|
||||
1770
po/zh_CN.po
Normal file
1770
po/zh_CN.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,9 @@
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
/* Python API use char* where const char* should be used... */
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
#define MOD_ERROR_VAL
|
||||
#define MOD_SUCCESS_VAL(val)
|
||||
@@ -43,6 +46,8 @@
|
||||
ob = PyModule_Create(&moduledef);
|
||||
#endif
|
||||
|
||||
MOD_INIT(pycryptsetup);
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
@@ -185,7 +190,7 @@ constructor takes one to five arguments:\n\
|
||||
|
||||
static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"device", "name", "yesDialog", "passwordDialog", "logFunc", NULL};
|
||||
static const char *kwlist[] = {"device", "name", "yesDialog", "passwordDialog", "logFunc", NULL};
|
||||
PyObject *yesDialogCB = NULL,
|
||||
*passwordDialogCB = NULL,
|
||||
*cmdLineLogCB = NULL,
|
||||
@@ -193,7 +198,7 @@ static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwd
|
||||
char *device = NULL, *deviceName = NULL;
|
||||
int r;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", kwlist, &device, &deviceName,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", CONST_CAST(char**)kwlist, &device, &deviceName,
|
||||
&yesDialogCB, &passwordDialogCB, &cmdLineLogCB))
|
||||
return -1;
|
||||
|
||||
@@ -256,14 +261,13 @@ CryptSetup_activate_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_activate(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"name", "passphrase", NULL};
|
||||
static const char *kwlist[] = {"name", "passphrase", NULL};
|
||||
char *name = NULL, *passphrase = NULL;
|
||||
int is;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &name, &passphrase))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", CONST_CAST(char**)kwlist, &name, &passphrase))
|
||||
return NULL;
|
||||
|
||||
|
||||
// FIXME: allow keyfile and \0 in passphrase
|
||||
is = crypt_activate_by_passphrase(self->device, name, CRYPT_ANY_SLOT,
|
||||
passphrase, passphrase ? strlen(passphrase) : 0, 0);
|
||||
@@ -300,10 +304,10 @@ CryptSetup_askyes_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_askyes(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"message", NULL};
|
||||
static const char *kwlist[] = {"message", NULL};
|
||||
PyObject *message = NULL, *result, *arglist;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &message))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", CONST_CAST(char**)kwlist, &message))
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(message);
|
||||
@@ -328,10 +332,10 @@ CryptSetup_log_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_log(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"priority", "message", NULL};
|
||||
static const char *kwlist[] = {"priority", "message", NULL};
|
||||
PyObject *message = NULL, *priority = NULL, *result, *arglist;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &message, &priority))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", CONST_CAST(char**)kwlist, &message, &priority))
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(message);
|
||||
@@ -416,12 +420,12 @@ CryptSetup_luksFormat_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_luksFormat(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"cipher", "cipherMode", "keysize", NULL};
|
||||
static const char *kwlist[] = {"cipher", "cipherMode", "keysize", NULL};
|
||||
char *cipher_mode = NULL, *cipher = NULL;
|
||||
int keysize = 256;
|
||||
PyObject *keysize_object = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", CONST_CAST(char**)kwlist,
|
||||
&cipher, &cipher_mode, &keysize_object))
|
||||
return NULL;
|
||||
|
||||
@@ -455,12 +459,12 @@ CryptSetup_addKeyByPassphrase_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_addKeyByPassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"passphrase", "newPassphrase", "slot", NULL};
|
||||
static const char *kwlist[] = {"passphrase", "newPassphrase", "slot", NULL};
|
||||
char *passphrase = NULL, *newpassphrase = NULL;
|
||||
size_t passphrase_len = 0, newpassphrase_len = 0;
|
||||
int slot = CRYPT_ANY_SLOT;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|i", kwlist, &passphrase, &newpassphrase, &slot))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|i", CONST_CAST(char**)kwlist, &passphrase, &newpassphrase, &slot))
|
||||
return NULL;
|
||||
|
||||
if(passphrase)
|
||||
@@ -483,12 +487,12 @@ CryptSetup_addKeyByVolumeKey_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_addKeyByVolumeKey(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"newPassphrase", "slot", NULL};
|
||||
static const char *kwlist[] = {"newPassphrase", "slot", NULL};
|
||||
char *newpassphrase = NULL;
|
||||
size_t newpassphrase_len = 0;
|
||||
int slot = CRYPT_ANY_SLOT;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &newpassphrase, &slot))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", CONST_CAST(char**)kwlist, &newpassphrase, &slot))
|
||||
return NULL;
|
||||
|
||||
if (newpassphrase)
|
||||
@@ -506,12 +510,12 @@ CryptSetup_removePassphrase_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_removePassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"passphrase", NULL};
|
||||
static const char *kwlist[] = {"passphrase", NULL};
|
||||
char *passphrase = NULL;
|
||||
size_t passphrase_len = 0;
|
||||
int is;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &passphrase))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", CONST_CAST(char**)kwlist, &passphrase))
|
||||
return NULL;
|
||||
|
||||
if (passphrase)
|
||||
@@ -533,10 +537,10 @@ CryptSetup_killSlot_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_killSlot(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"slot", NULL};
|
||||
static const char *kwlist[] = {"slot", NULL};
|
||||
int slot = CRYPT_ANY_SLOT;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &slot))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", CONST_CAST(char**)kwlist, &slot))
|
||||
return NULL;
|
||||
|
||||
switch (crypt_keyslot_status(self->device, slot)) {
|
||||
@@ -579,7 +583,7 @@ CryptSetup_Resume_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"passphrase", NULL};
|
||||
static const char *kwlist[] = {"passphrase", NULL};
|
||||
char* passphrase = NULL;
|
||||
size_t passphrase_len = 0;
|
||||
|
||||
@@ -588,10 +592,9 @@ static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObj
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &passphrase))
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", CONST_CAST(char**)kwlist, &passphrase))
|
||||
return NULL;
|
||||
|
||||
|
||||
if (passphrase)
|
||||
passphrase_len = strlen(passphrase);
|
||||
|
||||
@@ -622,10 +625,10 @@ CryptSetup_debugLevel_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_debugLevel(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"level", NULL};
|
||||
static const char *kwlist[] = {"level", NULL};
|
||||
int level = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &level))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", CONST_CAST(char**)kwlist, &level))
|
||||
return NULL;
|
||||
|
||||
crypt_set_debug_level(level);
|
||||
@@ -641,10 +644,10 @@ CryptSetup_iterationTime_HELP[] =
|
||||
|
||||
static PyObject *CryptSetup_iterationTime(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"time_ms", NULL};
|
||||
static const char *kwlist[] = {"time_ms", NULL};
|
||||
uint64_t time_ms = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "K", kwlist, &time_ms))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "K", CONST_CAST(char**)kwlist, &time_ms))
|
||||
return NULL;
|
||||
|
||||
crypt_set_iteration_time(self->device, time_ms);
|
||||
@@ -653,9 +656,9 @@ static PyObject *CryptSetup_iterationTime(CryptSetupObject* self, PyObject *args
|
||||
}
|
||||
|
||||
static PyMemberDef CryptSetup_members[] = {
|
||||
{"yesDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, yesDialogCB), 0, "confirmation dialog callback"},
|
||||
{"cmdLineLogCB", T_OBJECT_EX, offsetof(CryptSetupObject, cmdLineLogCB), 0, "logging callback"},
|
||||
{"passwordDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, passwordDialogCB), 0, "password dialog callback"},
|
||||
{CONST_CAST(char*)"yesDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, yesDialogCB), 0, CONST_CAST(char*)"confirmation dialog callback"},
|
||||
{CONST_CAST(char*)"cmdLineLogCB", T_OBJECT_EX, offsetof(CryptSetupObject, cmdLineLogCB), 0, CONST_CAST(char*)"logging callback"},
|
||||
{CONST_CAST(char*)"passwordDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, passwordDialogCB), 0, CONST_CAST(char*)"password dialog callback"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -671,7 +674,7 @@ static PyMethodDef CryptSetup_methods[] = {
|
||||
/* cryptsetup info entrypoints */
|
||||
{"luksUUID", (PyCFunction)CryptSetup_luksUUID, METH_NOARGS, CryptSetup_luksUUID_HELP},
|
||||
{"isLuks", (PyCFunction)CryptSetup_isLuks, METH_NOARGS, CryptSetup_isLuks_HELP},
|
||||
{"info", (PyCFunction)CryptSetup_Info, METH_NOARGS, CryptSetup_Info_HELP},
|
||||
{"info", (PyCFunction)CryptSetup_Info, METH_NOARGS, CryptSetup_Info_HELP},
|
||||
{"status", (PyCFunction)CryptSetup_Status, METH_NOARGS, CryptSetup_Status_HELP},
|
||||
|
||||
/* cryptsetup mgmt entrypoints */
|
||||
|
||||
@@ -12,7 +12,6 @@ AM_CPPFLAGS = -include config.h \
|
||||
cryptsetup_SOURCES = \
|
||||
$(top_builddir)/lib/utils_crypt.c \
|
||||
$(top_builddir)/lib/utils_loop.c \
|
||||
$(top_builddir)/lib/utils_fips.c \
|
||||
utils_tools.c \
|
||||
utils_password.c \
|
||||
cryptsetup.c \
|
||||
@@ -21,7 +20,6 @@ cryptsetup_SOURCES = \
|
||||
cryptsetup_LDADD = \
|
||||
$(top_builddir)/lib/libcryptsetup.la \
|
||||
@POPT_LIBS@ \
|
||||
@FIPSCHECK_LIBS@ \
|
||||
@PWQUALITY_LIBS@
|
||||
|
||||
cryptsetup_CFLAGS = $(AM_CFLAGS) -Wall
|
||||
|
||||
222
src/cryptsetup.c
222
src/cryptsetup.c
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2014, Milan Broz
|
||||
* Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2015, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -57,15 +57,26 @@ static int opt_urandom = 0;
|
||||
static int opt_dump_master_key = 0;
|
||||
static int opt_shared = 0;
|
||||
static int opt_allow_discards = 0;
|
||||
static int opt_perf_same_cpu_crypt = 0;
|
||||
static int opt_perf_submit_from_crypt_cpus = 0;
|
||||
static int opt_test_passphrase = 0;
|
||||
static int opt_tcrypt_hidden = 0;
|
||||
static int opt_tcrypt_system = 0;
|
||||
static int opt_tcrypt_backup = 0;
|
||||
static int opt_veracrypt = 0;
|
||||
|
||||
static const char **action_argv;
|
||||
static int action_argc;
|
||||
static const char *null_action_argv[] = {NULL, NULL};
|
||||
|
||||
static const char *uuid_or_device_header(const char **data_device)
|
||||
{
|
||||
if (data_device)
|
||||
*data_device = opt_header_device ? action_argv[0] : NULL;
|
||||
|
||||
return uuid_or_device(opt_header_device ?: action_argv[0]);
|
||||
}
|
||||
|
||||
static int _verify_passphrase(int def)
|
||||
{
|
||||
/* Batch mode switch off verify - if not overrided by -y */
|
||||
@@ -84,6 +95,21 @@ static int _verify_passphrase(int def)
|
||||
return def;
|
||||
}
|
||||
|
||||
static void _set_activation_flags(uint32_t *flags)
|
||||
{
|
||||
if (opt_readonly)
|
||||
*flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (opt_allow_discards)
|
||||
*flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
|
||||
if (opt_perf_same_cpu_crypt)
|
||||
*flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
|
||||
|
||||
if (opt_perf_submit_from_crypt_cpus)
|
||||
*flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
|
||||
}
|
||||
|
||||
static int action_open_plain(void)
|
||||
{
|
||||
struct crypt_device *cd = NULL;
|
||||
@@ -95,22 +121,11 @@ static int action_open_plain(void)
|
||||
.size = opt_size,
|
||||
};
|
||||
char *password = NULL;
|
||||
size_t passwordLen;
|
||||
size_t passwordLen, key_size_max;
|
||||
size_t key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
|
||||
uint32_t activate_flags = 0;
|
||||
int r;
|
||||
|
||||
if (params.hash && !strcmp(params.hash, "plain"))
|
||||
params.hash = NULL;
|
||||
|
||||
/* FIXME: temporary hack */
|
||||
if (opt_key_file && strcmp(opt_key_file, "-"))
|
||||
params.hash = NULL;
|
||||
|
||||
if ((opt_keyfile_offset || opt_keyfile_size) && opt_key_file)
|
||||
log_std(_("Ignoring keyfile offset and size options, keyfile read "
|
||||
"size is always the same as encryption key size.\n"));
|
||||
|
||||
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN),
|
||||
cipher, NULL, cipher_mode);
|
||||
if (r < 0) {
|
||||
@@ -118,6 +133,21 @@ static int action_open_plain(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* FIXME: temporary hack, no hashing for keyfiles in plain mode */
|
||||
if (opt_key_file && !tools_is_stdin(opt_key_file)) {
|
||||
params.hash = NULL;
|
||||
if (!opt_batch_mode && opt_hash)
|
||||
log_std(_("WARNING: The --hash parameter is being ignored "
|
||||
"in plain mode with keyfile specified.\n"));
|
||||
}
|
||||
|
||||
if (params.hash && !strcmp(params.hash, "plain"))
|
||||
params.hash = NULL;
|
||||
|
||||
if (!opt_batch_mode && !params.hash && opt_key_file && !tools_is_stdin(opt_key_file) && opt_keyfile_size)
|
||||
log_std(_("WARNING: The --keyfile-size option is being ignored, "
|
||||
"the read size is the same as the encryption key size.\n"));
|
||||
|
||||
if ((r = crypt_init(&cd, action_argv[0])))
|
||||
goto out;
|
||||
|
||||
@@ -133,28 +163,28 @@ static int action_open_plain(void)
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
if (opt_readonly)
|
||||
activate_flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (opt_shared)
|
||||
activate_flags |= CRYPT_ACTIVATE_SHARED;
|
||||
|
||||
if (opt_allow_discards)
|
||||
activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
_set_activation_flags(&activate_flags);
|
||||
|
||||
if (opt_key_file)
|
||||
/* With hashing, read the whole keyfile */
|
||||
if (!tools_is_stdin(opt_key_file)) {
|
||||
/* If no hash, key is read directly, read size is always key_size
|
||||
* (possible opt_keyfile_size is ignored.
|
||||
* If hash is specified, opt_keyfile_size is applied.
|
||||
* The opt_keyfile_offset is applied always.
|
||||
*/
|
||||
key_size_max = params.hash ? (size_t)opt_keyfile_size : key_size;
|
||||
r = crypt_activate_by_keyfile_offset(cd, action_argv[1],
|
||||
CRYPT_ANY_SLOT, opt_key_file,
|
||||
params.hash ? 0 : key_size, 0,
|
||||
activate_flags);
|
||||
else {
|
||||
CRYPT_ANY_SLOT, opt_key_file, key_size_max,
|
||||
opt_keyfile_offset, activate_flags);
|
||||
} else {
|
||||
key_size_max = (opt_key_file && !params.hash) ? key_size : (size_t)opt_keyfile_size;
|
||||
r = tools_get_key(_("Enter passphrase: "),
|
||||
&password, &passwordLen,
|
||||
opt_keyfile_offset, opt_keyfile_size,
|
||||
NULL, opt_timeout,
|
||||
_verify_passphrase(0), 0,
|
||||
cd);
|
||||
opt_keyfile_offset, key_size_max,
|
||||
opt_key_file, opt_timeout,
|
||||
_verify_passphrase(0), 0, cd);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -185,11 +215,7 @@ static int action_open_loopaes(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (opt_readonly)
|
||||
activate_flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (opt_allow_discards)
|
||||
activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
_set_activation_flags(&activate_flags);
|
||||
|
||||
if ((r = crypt_init(&cd, action_argv[0])))
|
||||
goto out;
|
||||
@@ -259,10 +285,11 @@ static int action_open_tcrypt(void)
|
||||
struct crypt_params_tcrypt params = {
|
||||
.keyfiles = opt_keyfiles,
|
||||
.keyfiles_count = opt_keyfiles_count,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES |
|
||||
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
|
||||
};
|
||||
const char *activated_name;
|
||||
uint32_t flags = 0;
|
||||
uint32_t activate_flags = 0;
|
||||
int r;
|
||||
|
||||
activated_name = opt_test_passphrase ? NULL : action_argv[1];
|
||||
@@ -274,14 +301,10 @@ static int action_open_tcrypt(void)
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
if (opt_readonly)
|
||||
flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (opt_allow_discards)
|
||||
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
_set_activation_flags(&activate_flags);
|
||||
|
||||
if (activated_name)
|
||||
r = crypt_activate_by_volume_key(cd, activated_name, NULL, 0, flags);
|
||||
r = crypt_activate_by_volume_key(cd, activated_name, NULL, 0, activate_flags);
|
||||
out:
|
||||
crypt_free(cd);
|
||||
crypt_safe_free(CONST_CAST(char*)params.passphrase);
|
||||
@@ -336,7 +359,8 @@ static int action_tcryptDump(void)
|
||||
struct crypt_params_tcrypt params = {
|
||||
.keyfiles = opt_keyfiles,
|
||||
.keyfiles_count = opt_keyfiles_count,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES |
|
||||
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
|
||||
};
|
||||
int r;
|
||||
|
||||
@@ -442,8 +466,13 @@ static int action_status(void)
|
||||
log_std(" skipped: %" PRIu64 " sectors\n", cad.iv_offset);
|
||||
log_std(" mode: %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
|
||||
"readonly" : "read/write");
|
||||
if (cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
|
||||
log_std(" flags: discards\n");
|
||||
if (cad.flags & (CRYPT_ACTIVATE_ALLOW_DISCARDS|
|
||||
CRYPT_ACTIVATE_ALLOW_DISCARDS|
|
||||
CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS))
|
||||
log_std(" flags: %s%s%s\n",
|
||||
(cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? "discards " : "",
|
||||
(cad.flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? "same_cpu_crypt " : "",
|
||||
(cad.flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? "submit_from_crypt_cpus" : "");
|
||||
}
|
||||
out:
|
||||
crypt_free(cd);
|
||||
@@ -679,6 +708,10 @@ static int action_luksFormat(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Never call pwquality if using null cipher */
|
||||
if (tools_is_cipher_null(cipher))
|
||||
opt_force_password = 1;
|
||||
|
||||
if ((r = crypt_init(&cd, header_device))) {
|
||||
if (opt_header_device)
|
||||
log_err(_("Cannot use %s as on-disk header.\n"), header_device);
|
||||
@@ -730,16 +763,10 @@ static int action_open_luks(void)
|
||||
struct crypt_device *cd = NULL;
|
||||
const char *data_device, *header_device, *activated_name;
|
||||
char *key = NULL;
|
||||
uint32_t flags = 0;
|
||||
uint32_t activate_flags = 0;
|
||||
int r, keysize;
|
||||
|
||||
if (opt_header_device) {
|
||||
header_device = uuid_or_device(opt_header_device);
|
||||
data_device = action_argv[0];
|
||||
} else {
|
||||
header_device = uuid_or_device(action_argv[0]);
|
||||
data_device = NULL;
|
||||
}
|
||||
header_device = uuid_or_device_header(&data_device);
|
||||
|
||||
activated_name = opt_test_passphrase ? NULL : action_argv[1];
|
||||
|
||||
@@ -766,11 +793,7 @@ static int action_open_luks(void)
|
||||
if (opt_iteration_time)
|
||||
crypt_set_iteration_time(cd, opt_iteration_time);
|
||||
|
||||
if (opt_readonly)
|
||||
flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (opt_allow_discards)
|
||||
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
_set_activation_flags(&activate_flags);
|
||||
|
||||
if (opt_master_key_file) {
|
||||
keysize = crypt_get_volume_key_size(cd);
|
||||
@@ -778,15 +801,15 @@ static int action_open_luks(void)
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = crypt_activate_by_volume_key(cd, activated_name,
|
||||
key, keysize, flags);
|
||||
key, keysize, activate_flags);
|
||||
} else if (opt_key_file) {
|
||||
crypt_set_password_retry(cd, 1);
|
||||
r = crypt_activate_by_keyfile_offset(cd, activated_name,
|
||||
opt_key_slot, opt_key_file, opt_keyfile_size,
|
||||
opt_keyfile_offset, flags);
|
||||
opt_keyfile_offset, activate_flags);
|
||||
} else
|
||||
r = crypt_activate_by_passphrase(cd, activated_name,
|
||||
opt_key_slot, NULL, 0, flags);
|
||||
opt_key_slot, NULL, 0, activate_flags);
|
||||
out:
|
||||
crypt_safe_free(key);
|
||||
crypt_free(cd);
|
||||
@@ -843,7 +866,7 @@ static int action_luksKillSlot(void)
|
||||
struct crypt_device *cd = NULL;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -886,7 +909,7 @@ static int action_luksRemoveKey(void)
|
||||
size_t passwordLen;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -937,7 +960,7 @@ static int action_luksAddKey(void)
|
||||
size_t password_size = 0, password_new_size = 0;
|
||||
struct crypt_device *cd = NULL;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -945,6 +968,10 @@ static int action_luksAddKey(void)
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
||||
goto out;
|
||||
|
||||
/* Never call pwquality if using null cipher */
|
||||
if (tools_is_cipher_null(crypt_get_cipher(cd)))
|
||||
opt_force_password = 1;
|
||||
|
||||
keysize = crypt_get_volume_key_size(cd);
|
||||
/* FIXME: lib cannot properly set verification for new/old passphrase */
|
||||
crypt_set_password_verify(cd, _verify_passphrase(0));
|
||||
@@ -956,16 +983,31 @@ static int action_luksAddKey(void)
|
||||
r = _read_mk(opt_master_key_file, &key, keysize);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
//FIXME: process keyfile arg
|
||||
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
|
||||
key, keysize, NULL, 0);
|
||||
} else if (opt_key_file || opt_new_key_file) {
|
||||
|
||||
r = crypt_volume_key_verify(cd, key, keysize);
|
||||
check_signal(&r);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = tools_get_key(_("Enter new passphrase for key slot: "),
|
||||
&password_new, &password_new_size,
|
||||
opt_new_keyfile_offset, opt_new_keyfile_size,
|
||||
opt_new_key_file, opt_timeout,
|
||||
_verify_passphrase(1), 1, cd);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot, key, keysize,
|
||||
password_new, password_new_size);
|
||||
} else if (opt_key_file && !tools_is_stdin(opt_key_file) &&
|
||||
opt_new_key_file && !tools_is_stdin(opt_new_key_file)) {
|
||||
r = crypt_keyslot_add_by_keyfile_offset(cd, opt_key_slot,
|
||||
opt_key_file, opt_keyfile_size, opt_keyfile_offset,
|
||||
opt_new_key_file, opt_new_keyfile_size, opt_new_keyfile_offset);
|
||||
} else {
|
||||
r = tools_get_key(_("Enter any existing passphrase: "),
|
||||
&password, &password_size, 0, 0, NULL,
|
||||
&password, &password_size,
|
||||
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
|
||||
opt_timeout, _verify_passphrase(0), 0, cd);
|
||||
|
||||
if (r < 0)
|
||||
@@ -979,8 +1021,9 @@ static int action_luksAddKey(void)
|
||||
goto out;
|
||||
|
||||
r = tools_get_key(_("Enter new passphrase for key slot: "),
|
||||
&password_new, &password_new_size, 0, 0, NULL,
|
||||
opt_timeout, _verify_passphrase(1), 1, cd);
|
||||
&password_new, &password_new_size,
|
||||
opt_new_keyfile_offset, opt_new_keyfile_size, opt_new_key_file,
|
||||
opt_timeout, _verify_passphrase(1), opt_new_key_file ? 0 : 1, cd);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -1004,12 +1047,16 @@ static int action_luksChangeKey(void)
|
||||
size_t password_size = 0, password_new_size = 0;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
||||
goto out;
|
||||
|
||||
/* Never call pwquality if using null cipher */
|
||||
if (tools_is_cipher_null(crypt_get_cipher(cd)))
|
||||
opt_force_password = 1;
|
||||
|
||||
if (opt_iteration_time)
|
||||
crypt_set_iteration_time(cd, opt_iteration_time);
|
||||
|
||||
@@ -1055,7 +1102,7 @@ static int action_isLuks(void)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((r = crypt_init(&cd, action_argv[0])))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_log_callback(cd, quiet_log, NULL);
|
||||
@@ -1071,7 +1118,7 @@ static int action_luksUUID(void)
|
||||
const char *existing_uuid = NULL;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init(&cd, action_argv[0])))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -1150,7 +1197,7 @@ static int action_luksDump(void)
|
||||
struct crypt_device *cd = NULL;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
||||
@@ -1170,7 +1217,7 @@ static int action_luksSuspend(void)
|
||||
struct crypt_device *cd = NULL;
|
||||
int r;
|
||||
|
||||
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
|
||||
r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(opt_header_device));
|
||||
if (!r)
|
||||
r = crypt_suspend(cd, action_argv[0]);
|
||||
|
||||
@@ -1183,7 +1230,7 @@ static int action_luksResume(void)
|
||||
struct crypt_device *cd = NULL;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device)))
|
||||
if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(opt_header_device))))
|
||||
goto out;
|
||||
|
||||
crypt_set_timeout(cd, opt_timeout);
|
||||
@@ -1211,7 +1258,7 @@ static int action_luksBackup(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -1232,7 +1279,7 @@ static int action_luksRestore(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((r = crypt_init(&cd, action_argv[0])))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -1279,7 +1326,7 @@ static int action_luksErase(void)
|
||||
char *msg = NULL;
|
||||
int i, r;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
goto out;
|
||||
|
||||
crypt_set_confirm_callback(cd, yesDialog, NULL);
|
||||
@@ -1289,7 +1336,7 @@ static int action_luksErase(void)
|
||||
|
||||
if(asprintf(&msg, _("This operation will erase all keyslots on device %s.\n"
|
||||
"Device will become unusable after this operation."),
|
||||
uuid_or_device(action_argv[0])) == -1) {
|
||||
uuid_or_device_header(NULL)) == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -1472,8 +1519,11 @@ int main(int argc, const char **argv)
|
||||
{ "tcrypt-hidden", '\0', POPT_ARG_NONE, &opt_tcrypt_hidden, 0, N_("Use hidden header (hidden TCRYPT device)."), NULL },
|
||||
{ "tcrypt-system", '\0', POPT_ARG_NONE, &opt_tcrypt_system, 0, N_("Device is system TCRYPT drive (with bootloader)."), NULL },
|
||||
{ "tcrypt-backup", '\0', POPT_ARG_NONE, &opt_tcrypt_backup, 0, N_("Use backup (secondary) TCRYPT header."), NULL },
|
||||
{ "veracrypt", '\0', POPT_ARG_NONE, &opt_veracrypt, 0, N_("Scan also for VeraCrypt compatible device."), NULL },
|
||||
{ "type", 'M', POPT_ARG_STRING, &opt_type, 0, N_("Type of device metadata: luks, plain, loopaes, tcrypt."), NULL },
|
||||
{ "force-password", '\0', POPT_ARG_NONE, &opt_force_password, 0, N_("Disable password quality check (if enabled)."), NULL },
|
||||
{ "perf-same_cpu_crypt",'\0', POPT_ARG_NONE, &opt_perf_same_cpu_crypt, 0, N_("Use dm-crypt same_cpu_crypt performance compatibility option."), NULL },
|
||||
{ "perf-submit_from_crypt_cpus",'\0', POPT_ARG_NONE, &opt_perf_submit_from_crypt_cpus,0,N_("Use dm-crypt submit_from_crypt_cpus performance compatibility option."), NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
poptContext popt_context;
|
||||
@@ -1529,9 +1579,6 @@ int main(int argc, const char **argv)
|
||||
usage(popt_context, EXIT_FAILURE, poptStrerror(r),
|
||||
poptBadOption(popt_context, POPT_BADOPTION_NOALIAS));
|
||||
|
||||
if (crypt_fips_mode())
|
||||
crypt_log(NULL, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
|
||||
|
||||
if (opt_version_mode) {
|
||||
log_std("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
poptFreeContext(popt_context);
|
||||
@@ -1574,6 +1621,8 @@ int main(int argc, const char **argv)
|
||||
} else if (!strcmp(aname, "tcryptOpen")) {
|
||||
aname = "open";
|
||||
opt_type = "tcrypt";
|
||||
} else if (!strcmp(aname, "tcryptDump")) {
|
||||
opt_type = "tcrypt";
|
||||
} else if (!strcmp(aname, "remove") ||
|
||||
!strcmp(aname, "plainClose") ||
|
||||
!strcmp(aname, "luksClose") ||
|
||||
@@ -1689,6 +1738,11 @@ int main(int argc, const char **argv)
|
||||
_("Option --tcrypt-hidden cannot be combined with --allow-discards.\n"),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_veracrypt && strcmp(opt_type, "tcrypt"))
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
_("Option --veracrypt is supported only for TCRYPT device type.\n"),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_debug) {
|
||||
opt_verbose = 1;
|
||||
crypt_set_debug_level(-1);
|
||||
|
||||
@@ -81,6 +81,9 @@ int tools_get_key(const char *prompt,
|
||||
const char *key_file,
|
||||
int timeout, int verify, int pwquality,
|
||||
struct crypt_device *cd);
|
||||
int tools_is_stdin(const char *key_file);
|
||||
int tools_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size);
|
||||
int tools_is_cipher_null(const char *cipher);
|
||||
|
||||
/* Log */
|
||||
#define log_dbg(x...) clogger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* cryptsetup-reencrypt - crypt utility for offline re-encryption
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz All rights reserved.
|
||||
* Copyright (C) 2012-2015, Milan Broz All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -48,6 +48,7 @@ static int opt_key_slot = CRYPT_ANY_SLOT;
|
||||
static int opt_key_size = 0;
|
||||
static int opt_new = 0;
|
||||
static int opt_keep_key = 0;
|
||||
static int opt_decrypt = 0;
|
||||
|
||||
static const char *opt_reduce_size_str = NULL;
|
||||
static uint64_t opt_reduce_size = 0;
|
||||
@@ -62,12 +63,14 @@ struct reenc_ctx {
|
||||
char *device;
|
||||
char *device_uuid;
|
||||
uint64_t device_size; /* overrided by parameter */
|
||||
uint64_t device_size_real;
|
||||
uint64_t device_size_new_real;
|
||||
uint64_t device_size_org_real;
|
||||
uint64_t device_offset;
|
||||
uint64_t device_shift;
|
||||
|
||||
int in_progress:1;
|
||||
enum { FORWARD = 0, BACKWARD = 1 } reencrypt_direction;
|
||||
enum { REENCRYPT = 0, ENCRYPT = 1, DECRYPT = 2 } reencrypt_mode;
|
||||
|
||||
char header_file_org[PATH_MAX];
|
||||
char header_file_new[PATH_MAX];
|
||||
@@ -76,7 +79,7 @@ struct reenc_ctx {
|
||||
char crypt_path_org[PATH_MAX];
|
||||
char crypt_path_new[PATH_MAX];
|
||||
int log_fd;
|
||||
char *log_buf;
|
||||
char log_buf[SECTOR_SIZE];
|
||||
|
||||
struct {
|
||||
char *password;
|
||||
@@ -265,9 +268,9 @@ static int write_log(struct reenc_ctx *rc)
|
||||
|
||||
memset(rc->log_buf, 0, SECTOR_SIZE);
|
||||
snprintf(rc->log_buf, SECTOR_SIZE, "# LUKS reencryption log, DO NOT EDIT OR DELETE.\n"
|
||||
"version = %d\nUUID = %s\ndirection = %d\n"
|
||||
"version = %d\nUUID = %s\ndirection = %d\nmode = %d\n"
|
||||
"offset = %" PRIu64 "\nshift = %" PRIu64 "\n# EOF\n",
|
||||
1, rc->device_uuid, rc->reencrypt_direction,
|
||||
2, rc->device_uuid, rc->reencrypt_direction, rc->reencrypt_mode,
|
||||
rc->device_offset, rc->device_shift);
|
||||
|
||||
if (lseek(rc->log_fd, 0, SEEK_SET) == -1)
|
||||
@@ -293,7 +296,7 @@ static int parse_line_log(struct reenc_ctx *rc, const char *line)
|
||||
return 0;
|
||||
|
||||
if (sscanf(line, "version = %d", &i) == 1) {
|
||||
if (i != 1) {
|
||||
if (i < 1 || i > 2) {
|
||||
log_dbg("Log: Unexpected version = %i", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -311,6 +314,13 @@ static int parse_line_log(struct reenc_ctx *rc, const char *line)
|
||||
} else if (sscanf(line, "shift = %" PRIu64, &u64) == 1) {
|
||||
log_dbg("Log: shift = %" PRIu64, u64);
|
||||
rc->device_shift = u64;
|
||||
} else if (sscanf(line, "mode = %d", &i) == 1) { /* added in v2 */
|
||||
log_dbg("Log: mode = %i", i);
|
||||
rc->reencrypt_mode = i;
|
||||
if (rc->reencrypt_mode != REENCRYPT &&
|
||||
rc->reencrypt_mode != ENCRYPT &&
|
||||
rc->reencrypt_mode != DECRYPT)
|
||||
return -EINVAL;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
@@ -351,13 +361,11 @@ static void close_log(struct reenc_ctx *rc)
|
||||
log_dbg("Closing LUKS reencryption log file %s.", rc->log_file);
|
||||
if (rc->log_fd != -1)
|
||||
close(rc->log_fd);
|
||||
free(rc->log_buf);
|
||||
rc->log_buf = NULL;
|
||||
}
|
||||
|
||||
static int open_log(struct reenc_ctx *rc)
|
||||
{
|
||||
int flags = opt_directio ? O_DIRECT : 0;
|
||||
int flags = opt_fsync ? O_SYNC : 0;
|
||||
|
||||
rc->log_fd = open(rc->log_file, O_RDWR|O_EXCL|O_CREAT|flags, S_IRUSR|S_IWUSR);
|
||||
if (rc->log_fd != -1) {
|
||||
@@ -371,12 +379,6 @@ static int open_log(struct reenc_ctx *rc)
|
||||
if (rc->log_fd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (posix_memalign((void *)&rc->log_buf, alignment(rc->log_fd), SECTOR_SIZE)) {
|
||||
log_err(_("Allocation of aligned memory failed.\n"));
|
||||
close_log(rc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!rc->in_progress && write_log(rc) < 0) {
|
||||
close_log(rc);
|
||||
return -EIO;
|
||||
@@ -389,10 +391,31 @@ static int open_log(struct reenc_ctx *rc)
|
||||
static int activate_luks_headers(struct reenc_ctx *rc)
|
||||
{
|
||||
struct crypt_device *cd = NULL, *cd_new = NULL;
|
||||
const char *pwd_old, *pwd_new, pwd_empty[] = "";
|
||||
size_t pwd_old_len, pwd_new_len;
|
||||
int r;
|
||||
|
||||
log_dbg("Activating LUKS devices from headers.");
|
||||
|
||||
/* Never use real password for empty header processing */
|
||||
if (rc->reencrypt_mode == REENCRYPT) {
|
||||
pwd_old = rc->p[rc->keyslot].password;
|
||||
pwd_old_len = rc->p[rc->keyslot].passwordLen;
|
||||
pwd_new = pwd_old;
|
||||
pwd_new_len = pwd_old_len;
|
||||
} else if (rc->reencrypt_mode == DECRYPT) {
|
||||
pwd_old = rc->p[rc->keyslot].password;
|
||||
pwd_old_len = rc->p[rc->keyslot].passwordLen;
|
||||
pwd_new = pwd_empty;
|
||||
pwd_new_len = 0;
|
||||
} else if (rc->reencrypt_mode == ENCRYPT) {
|
||||
pwd_old = pwd_empty;
|
||||
pwd_old_len = 0;
|
||||
pwd_new = rc->p[rc->keyslot].password;
|
||||
pwd_new_len = rc->p[rc->keyslot].passwordLen;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
if ((r = crypt_init(&cd, rc->header_file_org)) ||
|
||||
(r = crypt_load(cd, CRYPT_LUKS1, NULL)) ||
|
||||
(r = crypt_set_data_device(cd, rc->device)))
|
||||
@@ -400,7 +423,7 @@ static int activate_luks_headers(struct reenc_ctx *rc)
|
||||
|
||||
log_verbose(_("Activating temporary device using old LUKS header.\n"));
|
||||
if ((r = crypt_activate_by_passphrase(cd, rc->header_file_org,
|
||||
opt_key_slot, rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen,
|
||||
opt_key_slot, pwd_old, pwd_old_len,
|
||||
CRYPT_ACTIVATE_READONLY|CRYPT_ACTIVATE_PRIVATE)) < 0)
|
||||
goto out;
|
||||
|
||||
@@ -411,7 +434,7 @@ static int activate_luks_headers(struct reenc_ctx *rc)
|
||||
|
||||
log_verbose(_("Activating temporary device using new LUKS header.\n"));
|
||||
if ((r = crypt_activate_by_passphrase(cd_new, rc->header_file_new,
|
||||
opt_key_slot, rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen,
|
||||
opt_key_slot, pwd_new, pwd_new_len,
|
||||
CRYPT_ACTIVATE_SHARED|CRYPT_ACTIVATE_PRIVATE)) < 0)
|
||||
goto out;
|
||||
r = 0;
|
||||
@@ -481,6 +504,10 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
||||
goto out;
|
||||
log_verbose(_("LUKS header backup of device %s created.\n"), rc->device);
|
||||
|
||||
/* For decrypt, new header will be fake one, so we are done here. */
|
||||
if (rc->reencrypt_mode == DECRYPT)
|
||||
goto out;
|
||||
|
||||
if ((r = create_empty_header(rc->header_file_new, rc->header_file_org,
|
||||
crypt_get_data_offset(cd))))
|
||||
goto out;
|
||||
@@ -533,10 +560,13 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
struct crypt_device *cd_new = NULL;
|
||||
struct crypt_params_luks1 params = {0};
|
||||
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
|
||||
const char *header_file_fake;
|
||||
int r;
|
||||
|
||||
log_dbg("Creating fake (cipher_null) header for original device.");
|
||||
log_dbg("Creating fake (cipher_null) header for %s device.",
|
||||
(rc->reencrypt_mode == DECRYPT) ? "new" : "original");
|
||||
|
||||
header_file_fake = (rc->reencrypt_mode == DECRYPT) ? rc->header_file_new : rc->header_file_org;
|
||||
|
||||
if (!opt_key_size)
|
||||
opt_key_size = DEFAULT_LUKS1_KEYBITS;
|
||||
@@ -549,7 +579,7 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
}
|
||||
}
|
||||
|
||||
r = create_empty_header(rc->header_file_org, NULL, 0);
|
||||
r = create_empty_header(header_file_fake, NULL, MAX_BCK_SECTORS);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -557,7 +587,7 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
params.data_alignment = 0;
|
||||
params.data_device = rc->device;
|
||||
|
||||
r = crypt_init(&cd_new, rc->header_file_org);
|
||||
r = crypt_init(&cd_new, header_file_fake);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -571,6 +601,10 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* The real header is backup header created in backup_luks_headers() */
|
||||
if (rc->reencrypt_mode == DECRYPT)
|
||||
goto out;
|
||||
|
||||
r = create_empty_header(rc->header_file_new, rc->header_file_org, 0);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
@@ -660,6 +694,29 @@ static void print_progress(struct reenc_ctx *rc, uint64_t bytes, int final)
|
||||
final ? "\n" :"");
|
||||
}
|
||||
|
||||
static ssize_t read_buf(int fd, void *buf, size_t count)
|
||||
{
|
||||
size_t read_size = 0;
|
||||
ssize_t s;
|
||||
|
||||
do {
|
||||
/* This expects that partial read is aligned in buffer */
|
||||
s = read(fd, buf, count - read_size);
|
||||
if (s == -1 && errno != EINTR)
|
||||
return s;
|
||||
if (s == 0)
|
||||
return (ssize_t)read_size;
|
||||
if (s > 0) {
|
||||
if (s != (ssize_t)count)
|
||||
log_dbg("Partial read %zd / %zu.", s, count);
|
||||
read_size += (size_t)s;
|
||||
buf = (uint8_t*)buf + s;
|
||||
}
|
||||
} while (read_size != count);
|
||||
|
||||
return (ssize_t)count;
|
||||
}
|
||||
|
||||
static int copy_data_forward(struct reenc_ctx *rc, int fd_old, int fd_new,
|
||||
size_t block_size, void *buf, uint64_t *bytes)
|
||||
{
|
||||
@@ -679,11 +736,11 @@ static int copy_data_forward(struct reenc_ctx *rc, int fd_old, int fd_new,
|
||||
return -EIO;
|
||||
|
||||
while (!quit && rc->device_offset < rc->device_size) {
|
||||
s1 = read(fd_old, buf, block_size);
|
||||
s1 = read_buf(fd_old, buf, block_size);
|
||||
if (s1 < 0 || ((size_t)s1 != block_size &&
|
||||
(rc->device_offset + s1) != rc->device_size)) {
|
||||
log_dbg("Read error, expecting %d, got %d.",
|
||||
(int)block_size, (int)s1);
|
||||
log_dbg("Read error, expecting %zu, got %zd.",
|
||||
block_size, s1);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -693,8 +750,8 @@ static int copy_data_forward(struct reenc_ctx *rc, int fd_old, int fd_new,
|
||||
|
||||
s2 = write(fd_new, buf, s1);
|
||||
if (s2 < 0) {
|
||||
log_dbg("Write error, expecting %d, got %d.",
|
||||
(int)block_size, (int)s2);
|
||||
log_dbg("Write error, expecting %zu, got %zd.",
|
||||
block_size, s2);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -749,17 +806,17 @@ static int copy_data_backward(struct reenc_ctx *rc, int fd_old, int fd_new,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
s1 = read(fd_old, buf, working_block);
|
||||
s1 = read_buf(fd_old, buf, working_block);
|
||||
if (s1 < 0 || (s1 != working_block)) {
|
||||
log_dbg("Read error, expecting %d, got %d.",
|
||||
(int)block_size, (int)s1);
|
||||
log_dbg("Read error, expecting %zu, got %zd.",
|
||||
block_size, s1);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
s2 = write(fd_new, buf, working_block);
|
||||
if (s2 < 0) {
|
||||
log_dbg("Write error, expecting %d, got %d.",
|
||||
(int)block_size, (int)s2);
|
||||
log_dbg("Write error, expecting %zu, got %zd.",
|
||||
block_size, s2);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -779,6 +836,41 @@ static int copy_data_backward(struct reenc_ctx *rc, int fd_old, int fd_new,
|
||||
return quit ? -EAGAIN : 0;
|
||||
}
|
||||
|
||||
static void zero_rest_of_device(int fd, size_t block_size, void *buf,
|
||||
uint64_t *bytes, uint64_t offset)
|
||||
{
|
||||
ssize_t s1, s2;
|
||||
|
||||
log_dbg("Zeroing rest of device.");
|
||||
|
||||
if (lseek64(fd, offset, SEEK_SET) < 0) {
|
||||
log_dbg(_("Cannot seek to device offset.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0, block_size);
|
||||
s1 = block_size;
|
||||
|
||||
while (!quit && *bytes) {
|
||||
if (*bytes < (uint64_t)s1)
|
||||
s1 = *bytes;
|
||||
|
||||
s2 = write(fd, buf, s1);
|
||||
if (s2 < 0) {
|
||||
log_dbg("Write error, expecting %zu, got %zd.",
|
||||
block_size, s2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt_fsync && fsync(fd) < 0) {
|
||||
log_dbg("Write error, fsync.");
|
||||
return;
|
||||
}
|
||||
|
||||
*bytes -= s2;
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_data(struct reenc_ctx *rc)
|
||||
{
|
||||
size_t block_size = opt_bsize * 1024 * 1024;
|
||||
@@ -791,23 +883,32 @@ static int copy_data(struct reenc_ctx *rc)
|
||||
|
||||
fd_old = open(rc->crypt_path_org, O_RDONLY | (opt_directio ? O_DIRECT : 0));
|
||||
if (fd_old == -1) {
|
||||
log_err(_("Cannot open temporary LUKS header file.\n"));
|
||||
log_err(_("Cannot open temporary LUKS device.\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd_new = open(rc->crypt_path_new, O_WRONLY | (opt_directio ? O_DIRECT : 0));
|
||||
if (fd_new == -1) {
|
||||
log_err(_("Cannot open temporary LUKS header file.\n"));
|
||||
log_err(_("Cannot open temporary LUKS device.\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check size */
|
||||
if (ioctl(fd_new, BLKGETSIZE64, &rc->device_size_real) < 0) {
|
||||
if (ioctl(fd_old, BLKGETSIZE64, &rc->device_size_org_real) < 0) {
|
||||
log_err(_("Cannot get device size.\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc->device_size = opt_device_size ?: rc->device_size_real;
|
||||
if (ioctl(fd_new, BLKGETSIZE64, &rc->device_size_new_real) < 0) {
|
||||
log_err(_("Cannot get device size.\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_device_size)
|
||||
rc->device_size = opt_device_size;
|
||||
else if (rc->reencrypt_mode == DECRYPT)
|
||||
rc->device_size = rc->device_size_org_real;
|
||||
else
|
||||
rc->device_size = rc->device_size_new_real;
|
||||
|
||||
if (posix_memalign((void *)&buf, alignment(fd_new), block_size)) {
|
||||
log_err(_("Allocation of aligned memory failed.\n"));
|
||||
@@ -823,9 +924,18 @@ static int copy_data(struct reenc_ctx *rc)
|
||||
else
|
||||
r = copy_data_backward(rc, fd_old, fd_new, block_size, buf, &bytes);
|
||||
|
||||
set_int_block(1);
|
||||
print_progress(rc, bytes, 1);
|
||||
|
||||
/* Zero (wipe) rest of now plain-only device when decrypting.
|
||||
* (To not leave any sign of encryption here.) */
|
||||
if (!r && rc->reencrypt_mode == DECRYPT &&
|
||||
rc->device_size_new_real > rc->device_size_org_real) {
|
||||
bytes = rc->device_size_new_real - rc->device_size_org_real;
|
||||
zero_rest_of_device(fd_new, block_size, buf, &bytes, rc->device_size_org_real);
|
||||
}
|
||||
|
||||
set_int_block(1);
|
||||
|
||||
if (r == -EAGAIN)
|
||||
log_err(_("Interrupted by a signal.\n"));
|
||||
else if (r < 0)
|
||||
@@ -966,7 +1076,7 @@ static int initialize_passphrase(struct reenc_ctx *rc, const char *device)
|
||||
|
||||
log_dbg("Passhrases initialization.");
|
||||
|
||||
if (opt_new && !rc->in_progress) {
|
||||
if (rc->reencrypt_mode == ENCRYPT && !rc->in_progress) {
|
||||
r = init_passphrase1(rc, cd, _("Enter new passphrase: "), opt_key_slot, 0);
|
||||
return r > 0 ? 0 : r;
|
||||
}
|
||||
@@ -986,7 +1096,9 @@ static int initialize_passphrase(struct reenc_ctx *rc, const char *device)
|
||||
|
||||
if (opt_key_file) {
|
||||
r = init_keyfile(rc, cd, opt_key_slot);
|
||||
} else if (rc->in_progress || opt_key_slot != CRYPT_ANY_SLOT) {
|
||||
} else if (rc->in_progress ||
|
||||
opt_key_slot != CRYPT_ANY_SLOT ||
|
||||
rc->reencrypt_mode == DECRYPT) {
|
||||
r = init_passphrase1(rc, cd, msg, opt_key_slot, 1);
|
||||
} else for (i = 0; i < MAX_SLOT; i++) {
|
||||
ki = crypt_keyslot_status(cd, i);
|
||||
@@ -1053,6 +1165,13 @@ static int initialize_context(struct reenc_ctx *rc, const char *device)
|
||||
rc->reencrypt_direction = BACKWARD;
|
||||
rc->device_offset = (uint64_t)~0;
|
||||
}
|
||||
|
||||
if (opt_new)
|
||||
rc->reencrypt_mode = ENCRYPT;
|
||||
else if (opt_decrypt)
|
||||
rc->reencrypt_mode = DECRYPT;
|
||||
else
|
||||
rc->reencrypt_mode = REENCRYPT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1086,7 +1205,7 @@ static void destroy_context(struct reenc_ctx *rc)
|
||||
static int run_reencrypt(const char *device)
|
||||
{
|
||||
int r = -EINVAL;
|
||||
struct reenc_ctx rc = {};
|
||||
static struct reenc_ctx rc = {};
|
||||
|
||||
if (initialize_context(&rc, device))
|
||||
goto out;
|
||||
@@ -1094,14 +1213,23 @@ static int run_reencrypt(const char *device)
|
||||
log_dbg("Running reencryption.");
|
||||
|
||||
if (!rc.in_progress) {
|
||||
if (opt_new) {
|
||||
if ((r = initialize_passphrase(&rc, rc.device)) ||
|
||||
if ((r = initialize_passphrase(&rc, rc.device)))
|
||||
goto out;
|
||||
|
||||
if (rc.reencrypt_mode == ENCRYPT) {
|
||||
/* Create fake header for exising device */
|
||||
if ((r = backup_fake_header(&rc)))
|
||||
goto out;
|
||||
} else {
|
||||
if ((r = backup_luks_headers(&rc)))
|
||||
goto out;
|
||||
/* Create fake header for decrypted device */
|
||||
if (rc.reencrypt_mode == DECRYPT &&
|
||||
(r = backup_fake_header(&rc)))
|
||||
goto out;
|
||||
} else if ((r = initialize_passphrase(&rc, rc.device)) ||
|
||||
(r = backup_luks_headers(&rc)) ||
|
||||
(r = device_check(&rc, MAKE_UNUSABLE)))
|
||||
goto out;
|
||||
goto out;
|
||||
if ((r = device_check(&rc, MAKE_UNUSABLE)))
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if ((r = initialize_passphrase(&rc, rc.header_file_new)))
|
||||
goto out;
|
||||
@@ -1117,7 +1245,9 @@ static int run_reencrypt(const char *device)
|
||||
} else
|
||||
log_dbg("Keeping existing key, skipping data area reencryption.");
|
||||
|
||||
r = restore_luks_header(&rc);
|
||||
// FIXME: fix error path above to not skip this
|
||||
if (rc.reencrypt_mode != DECRYPT)
|
||||
r = restore_luks_header(&rc);
|
||||
out:
|
||||
destroy_context(&rc);
|
||||
return r;
|
||||
@@ -1169,7 +1299,8 @@ int main(int argc, const char **argv)
|
||||
{ "keyfile-size", 'l', POPT_ARG_LONG, &opt_keyfile_size, 0, N_("Limits the read from keyfile"), N_("bytes") },
|
||||
{ "reduce-device-size",'\0', POPT_ARG_STRING, &opt_reduce_size_str, 0, N_("Reduce data device size (move data offset). DANGEROUS!"), N_("bytes") },
|
||||
{ "device-size", '\0', POPT_ARG_STRING, &opt_device_size_str, 0, N_("Use only specified device size (ignore rest of device). DANGEROUS!"), N_("bytes") },
|
||||
{ "new", 'N', POPT_ARG_NONE,&opt_new, 0, N_("Create new header on not encrypted device."), NULL },
|
||||
{ "new", 'N', POPT_ARG_NONE, &opt_new, 0, N_("Create new header on not encrypted device."), NULL },
|
||||
{ "decrypt", '\0', POPT_ARG_NONE, &opt_decrypt, 0, N_("Permanently decrypt device (remove encryption)."), NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
poptContext popt_context;
|
||||
@@ -1241,12 +1372,12 @@ int main(int argc, const char **argv)
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_device_size_str &&
|
||||
crypt_string_to_size(NULL, opt_device_size_str, &opt_device_size))
|
||||
tools_string_to_size(NULL, opt_device_size_str, &opt_device_size))
|
||||
usage(popt_context, EXIT_FAILURE, _("Invalid device size specification."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_reduce_size_str &&
|
||||
crypt_string_to_size(NULL, opt_reduce_size_str, &opt_reduce_size))
|
||||
tools_string_to_size(NULL, opt_reduce_size_str, &opt_reduce_size))
|
||||
usage(popt_context, EXIT_FAILURE, _("Invalid device size specification."),
|
||||
poptGetInvocationName(popt_context));
|
||||
if (opt_reduce_size > 64 * 1024 * 1024)
|
||||
@@ -1264,6 +1395,14 @@ int main(int argc, const char **argv)
|
||||
usage(popt_context, EXIT_FAILURE, _("Option --keep-key can be used only with --hash or --iter-time."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_new && opt_decrypt)
|
||||
usage(popt_context, EXIT_FAILURE, _("Option --new cannot be used together with --decrypt."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_decrypt && (opt_cipher || opt_hash || opt_reduce_size || opt_keep_key || opt_device_size))
|
||||
usage(popt_context, EXIT_FAILURE, _("Option --decrypt is incompatible with specified parameters."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_debug) {
|
||||
opt_verbose = 1;
|
||||
crypt_set_debug_level(-1);
|
||||
|
||||
@@ -65,6 +65,25 @@ static int tools_check_pwquality(const char *password)
|
||||
}
|
||||
#endif /* ENABLE_PWQUALITY */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int tools_get_key(const char *prompt,
|
||||
char **key, size_t *key_size,
|
||||
size_t keyfile_offset, size_t keyfile_size_max,
|
||||
|
||||
@@ -143,6 +143,7 @@ int yesDialog(const char *msg, void *usrptr __attribute__((unused)))
|
||||
if(isatty(STDIN_FILENO) && !opt_batch_mode) {
|
||||
log_std("\nWARNING!\n========\n");
|
||||
log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg);
|
||||
fflush(stdout);
|
||||
if(getline(&answer, &size, stdin) == -1) {
|
||||
r = 0;
|
||||
/* Aborted by signal */
|
||||
@@ -163,7 +164,7 @@ int yesDialog(const char *msg, void *usrptr __attribute__((unused)))
|
||||
|
||||
void show_status(int errcode)
|
||||
{
|
||||
char error[256], *error_;
|
||||
char error[256];
|
||||
|
||||
if(!opt_verbose)
|
||||
return;
|
||||
@@ -175,12 +176,16 @@ void show_status(int errcode)
|
||||
|
||||
crypt_get_error(error, sizeof(error));
|
||||
|
||||
if (!error[0]) {
|
||||
error_ = strerror_r(-errcode, error, sizeof(error));
|
||||
if (error_ != error) {
|
||||
if (*error) {
|
||||
#ifdef STRERROR_R_CHAR_P /* GNU-specific strerror_r */
|
||||
char *error_ = strerror_r(-errcode, error, sizeof(error));
|
||||
if (error_ != error)
|
||||
strncpy(error, error_, sizeof(error));
|
||||
error[sizeof(error) - 1] = '\0';
|
||||
}
|
||||
#else /* POSIX strerror_r variant */
|
||||
if (strerror_r(-errcode, error, sizeof(error)))
|
||||
*error = '\0';
|
||||
#endif
|
||||
error[sizeof(error) - 1] = '\0';
|
||||
}
|
||||
|
||||
log_err(_("Command failed with code %i"), -errcode);
|
||||
@@ -257,3 +262,68 @@ int translate_errno(int r)
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device size string parsing, suffixes:
|
||||
* s|S - 512 bytes sectors
|
||||
* k |K |m |M |g |G |t |T - 1024 base
|
||||
* kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base
|
||||
* kb |KB |mM |MB |gB |GB |tB |TB - 1000 base
|
||||
*/
|
||||
int tools_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size)
|
||||
{
|
||||
char *endp = NULL;
|
||||
size_t len;
|
||||
uint64_t mult_base, mult, tmp;
|
||||
|
||||
*size = strtoull(s, &endp, 10);
|
||||
if (!isdigit(s[0]) ||
|
||||
(errno == ERANGE && *size == ULLONG_MAX) ||
|
||||
(errno != 0 && *size == 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (!endp || !*endp)
|
||||
return 0;
|
||||
|
||||
len = strlen(endp);
|
||||
/* Allow "B" and "iB" suffixes */
|
||||
if (len > 3 ||
|
||||
(len == 3 && (endp[1] != 'i' || endp[2] != 'B')) ||
|
||||
(len == 2 && endp[1] != 'B'))
|
||||
return -EINVAL;
|
||||
|
||||
if (len == 1 || len == 3)
|
||||
mult_base = 1024;
|
||||
else
|
||||
mult_base = 1000;
|
||||
|
||||
mult = 1;
|
||||
switch (endp[0]) {
|
||||
case 's':
|
||||
case 'S': mult = 512;
|
||||
break;
|
||||
case 't':
|
||||
case 'T': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'g':
|
||||
case 'G': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'm':
|
||||
case 'M': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'k':
|
||||
case 'K': mult *= mult_base;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = *size * mult;
|
||||
if ((tmp / *size) != mult) {
|
||||
log_dbg("Device size overflow.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*size = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ TESTS = api-test \
|
||||
mode-test \
|
||||
password-hash-test \
|
||||
tcrypt-compat-test \
|
||||
luks1-compat-test
|
||||
luks1-compat-test \
|
||||
device-test
|
||||
|
||||
if VERITYSETUP
|
||||
TESTS += verity-compat-test
|
||||
@@ -17,7 +18,7 @@ TESTS += reencryption-compat-test
|
||||
endif
|
||||
|
||||
EXTRA_DIST = compatimage.img.bz2 compatv10image.img.bz2 \
|
||||
img_fs_ext4.img.bz2 img_fs_xfs.img.bz2 \
|
||||
img_fs_ext4.img.bz2 img_fs_vfat.img.bz2 img_fs_xfs.img.bz2 \
|
||||
valid_header_file.bz2 \
|
||||
evil_hdr-payload_overwrite.bz2 \
|
||||
evil_hdr-stripes_payload_dmg.bz2 \
|
||||
@@ -30,6 +31,7 @@ EXTRA_DIST = compatimage.img.bz2 compatv10image.img.bz2 \
|
||||
reencryption-compat-test \
|
||||
tcrypt-compat-test \
|
||||
luks1-compat-test \
|
||||
device-test \
|
||||
cryptsetup-valg-supps valg.sh valg-api.sh
|
||||
|
||||
CLEANFILES = cryptsetup-tst* valglog*
|
||||
|
||||
@@ -40,7 +40,7 @@ add_device() {
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
DEV=$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
||||
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."
|
||||
@@ -87,10 +87,10 @@ format_null()
|
||||
{
|
||||
if [ $3 -eq 0 ] ; then
|
||||
echo -n "Formatting using topology info ($1 bits key) [slot 0"
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $DEV -q -i1 -c null -s $1
|
||||
echo | $CRYPTSETUP luksFormat $DEV -q -i1 -c null -s $1
|
||||
else
|
||||
echo -n "Formatting using forced sector alignment $3 ($1 bits key) [slot 0"
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $DEV -q -i1 -c null -s $1 --align-payload=$3
|
||||
echo | $CRYPTSETUP luksFormat $DEV -q -i1 -c null -s $1 --align-payload=$3
|
||||
fi
|
||||
|
||||
POFF=$(get_offsets "Payload offset")
|
||||
@@ -98,7 +98,7 @@ format_null()
|
||||
[ $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 "$PWD1\n$PWD2$j" | $CRYPTSETUP luksAddKey $DEV -q -i1 --key-slot $j -c null $PARAMS
|
||||
echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q -i1 --key-slot $j -c null $PARAMS
|
||||
echo -n $j
|
||||
[ $? -ne 0 ] && fail
|
||||
done
|
||||
|
||||
@@ -975,8 +975,11 @@ static void SuspendDevice(void)
|
||||
suspend_status = crypt_suspend(cd, CDEVICE_1);
|
||||
if (suspend_status == -ENOTSUP) {
|
||||
printf("WARNING: Suspend/Resume not supported, skipping test.\n");
|
||||
goto out;
|
||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||
crypt_free(cd);
|
||||
return;
|
||||
}
|
||||
|
||||
OK_(suspend_status);
|
||||
FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended");
|
||||
|
||||
@@ -990,10 +993,30 @@ static void SuspendDevice(void)
|
||||
FAIL_(crypt_resume_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 1, 0), "wrong key");
|
||||
OK_(crypt_resume_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0));
|
||||
FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended");
|
||||
_remove_keyfiles();
|
||||
out:
|
||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||
crypt_free(cd);
|
||||
|
||||
/* create LUKS device with detached header */
|
||||
OK_(crypt_init(&cd, DEVICE_1));
|
||||
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
|
||||
OK_(crypt_set_data_device(cd, DEVICE_2));
|
||||
OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
|
||||
crypt_free(cd);
|
||||
|
||||
/* Should be able to suspend but not resume if not header specified */
|
||||
OK_(crypt_init_by_name(&cd, CDEVICE_1));
|
||||
OK_(crypt_suspend(cd, CDEVICE_1));
|
||||
FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended");
|
||||
FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)-1), "no header");
|
||||
crypt_free(cd);
|
||||
|
||||
OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DEVICE_1));
|
||||
OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)));
|
||||
|
||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||
crypt_free(cd);
|
||||
|
||||
_remove_keyfiles();
|
||||
}
|
||||
|
||||
static void AddDeviceLuks(void)
|
||||
|
||||
@@ -309,26 +309,43 @@ $CRYPTSETUP -q luksClose $DEV_NAME || fail
|
||||
|
||||
prepare "[17] AddKey volume key, passphrase and keyfile" wipe
|
||||
# masterkey
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat $LOOPDEV --master-key-file /dev/zero --key-slot 3 || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat -i1 $LOOPDEV --master-key-file /dev/zero --key-slot 3 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 3: ENABLED" || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksAddKey $LOOPDEV --master-key-file /dev/zero --key-slot 4 || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksAddKey -i1 $LOOPDEV --master-key-file /dev/zero --key-slot 4 || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 4 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 4: ENABLED" || fail
|
||||
echo $PWD3 | $CRYPTSETUP luksAddKey $LOOPDEV --master-key-file /dev/null --key-slot 5 2>/dev/null && fail
|
||||
echo $PWD3 | $CRYPTSETUP luksAddKey -i1 $LOOPDEV --master-key-file /dev/null --key-slot 5 2>/dev/null && fail
|
||||
$CRYPTSETUP luksAddKey -i1 $LOOPDEV --master-key-file /dev/zero --key-slot 5 $KEY1 || fail
|
||||
$CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 5 -d $KEY1 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: ENABLED" || fail
|
||||
|
||||
# special "-" handling
|
||||
$CRYPTSETUP -q luksFormat -i1 $LOOPDEV $KEY1 --key-slot 3 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey -i1 $LOOPDEV -d $KEY1 - || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase 2>/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV -d - --test-passphrase || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey -i1 $LOOPDEV -d - $KEY2 || fail
|
||||
$CRYPTSETUP luksOpen $LOOPDEV -d $KEY2 --test-passphrase || fail
|
||||
|
||||
# [0]PWD1 [1]PWD2 [2]$KEY1/1 [3]$KEY1 [4]$KEY2
|
||||
$CRYPTSETUP -q luksFormat $LOOPDEV $KEY1 --key-slot 3 || fail
|
||||
$CRYPTSETUP -q luksFormat -i1 $LOOPDEV $KEY1 --key-slot 3 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 3: ENABLED" || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 --key-slot 3 2>/dev/null && fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -i1 -d $KEY1 $KEY2 --key-slot 3 2>/dev/null && fail
|
||||
# keyfile/keyfile
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 --key-slot 4 || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -i1 -d $KEY1 $KEY2 --key-slot 4 || fail
|
||||
$CRYPTSETUP luksOpen $LOOPDEV -d $KEY2 --test-passphrase --key-slot 4 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 4: ENABLED" || fail
|
||||
# passphrase/keyfile
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 --key-slot 0 || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey -i1 $LOOPDEV -d $KEY1 --key-slot 0 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 0: ENABLED" || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 0 || fail
|
||||
# passphrase/passphrase
|
||||
echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey $LOOPDEV --key-slot 1 || fail
|
||||
echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey -i1 $LOOPDEV --key-slot 1 || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 1 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: ENABLED" || fail
|
||||
# keyfile/passphrase
|
||||
echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey $LOOPDEV $KEY1 --key-slot 2 --new-keyfile-size 1 || fail
|
||||
echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey -i1 $LOOPDEV $KEY1 --key-slot 2 --new-keyfile-size 1 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 2: ENABLED" || fail
|
||||
|
||||
prepare "[18] RemoveKey passphrase and keyfile" reuse
|
||||
@@ -358,6 +375,10 @@ $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
|
||||
# Resize underlying loop device as well
|
||||
truncate -s 16M $IMG || fail
|
||||
$CRYPTSETUP -q resize $DEV_NAME || fail
|
||||
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "32765 sectors" || fail
|
||||
$CRYPTSETUP -q remove $DEV_NAME || fail
|
||||
$CRYPTSETUP -q status $DEV_NAME >/dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha1 $LOOPDEV || fail
|
||||
@@ -538,6 +559,10 @@ $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail
|
||||
$CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail
|
||||
$CRYPTSETUP luksClose $DEV_NAME || fail
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey -S 5 _fakedev_ --header $HEADER_IMG $KEY5 || fail
|
||||
$CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "Key Slot 5: ENABLED" || fail
|
||||
$CRYPTSETUP luksKillSlot -q _fakedev_ --header $HEADER_IMG 5 || fail
|
||||
$CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "Key Slot 5: DISABLED" || fail
|
||||
|
||||
prepare "[29] Repair metadata" wipe
|
||||
$CRYPTSETUP -q luksFormat -i1 $LOOPDEV $KEY1 --key-slot 0 || fail
|
||||
|
||||
86
tests/device-test
Executable file
86
tests/device-test
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
|
||||
CRYPTSETUP="../src/cryptsetup"
|
||||
MNT_DIR="./mnt_luks"
|
||||
DEV_NAME="dummy"
|
||||
PWD1="93R4P4pIqAH8"
|
||||
PWD2="mymJeD8ivEhE"
|
||||
|
||||
cleanup() {
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
|
||||
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
|
||||
sleep 2
|
||||
}
|
||||
|
||||
fail()
|
||||
{
|
||||
if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
|
||||
cleanup
|
||||
exit 100
|
||||
}
|
||||
|
||||
skip()
|
||||
{
|
||||
echo "TEST SKIPPED: $1"
|
||||
cleanup
|
||||
exit 0
|
||||
}
|
||||
|
||||
format() # key_bits expected [forced]
|
||||
{
|
||||
dd if=/dev/zero of=$DEV bs=1M count=5 >/dev/null 2>&1
|
||||
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat $DEV -q -i1 -c aes-cbc-essiv:sha256
|
||||
[ $? -ne 0 ] && fail "Format failed."
|
||||
|
||||
# test some operation, just in case
|
||||
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --key-slot 1
|
||||
[ $? -ne 0 ] && fail "Keyslot add failed."
|
||||
|
||||
$CRYPTSETUP -q luksKillSlot $DEV 1
|
||||
[ $? -ne 0 ] && fail "Keyslot removal failed."
|
||||
}
|
||||
|
||||
if [ $(id -u) != 0 ]; then
|
||||
echo "WARNING: You must be root to run this test, test skipped."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
|
||||
|
||||
echo "[1] Using tmpfs for image"
|
||||
DEV="$MNT_DIR/test.img"
|
||||
mount -t tmpfs none $MNT_DIR || skip "Mounting tmpfs not available."
|
||||
format
|
||||
|
||||
echo "[2] Kernel dmcrypt performace options"
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --perf-same_cpu_crypt >/dev/null 2>&1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "TEST SKIPPED: dmcrypt options not available"
|
||||
else
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
# plain
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --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
|
||||
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
|
||||
$CRYPTSETUP status $DEV_NAME | grep -q discards || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
# LUKS
|
||||
echo -e "$PWD1" | $CRYPTSETUP open --type luks1 $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 luks1 $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
|
||||
fi
|
||||
|
||||
cleanup
|
||||
@@ -27,7 +27,7 @@ add_device() {
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
DEV=$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
||||
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
||||
|
||||
DEV="/dev/$DEV"
|
||||
[ -b $DEV ] || fail "Cannot find $DEV."
|
||||
|
||||
BIN
tests/img_fs_vfat.img.bz2
Normal file
BIN
tests/img_fs_vfat.img.bz2
Normal file
Binary file not shown.
@@ -49,6 +49,8 @@ function test_required()
|
||||
test_one aes-xts 256
|
||||
test_one twofish-xts 256
|
||||
test_one serpent-xts 256
|
||||
test_one aes-cbc 256
|
||||
test_one aes-lrw 256
|
||||
}
|
||||
|
||||
export LANG=C
|
||||
@@ -64,7 +66,15 @@ test_required
|
||||
echo "ACTIVATION FS UUID CHECK"
|
||||
for file in $(ls $TST_DIR/luks1_*) ; do
|
||||
echo -n " $file"
|
||||
$CRYPTSETUP luksOpen -d $TST_DIR/$KEYFILE $file $MAP 2>/dev/null || fail
|
||||
$CRYPTSETUP luksOpen -d $TST_DIR/$KEYFILE $file $MAP 2>/dev/null
|
||||
ret=$?
|
||||
# ignore missing whirlpool (pwd failed is exit code 2)
|
||||
[ $ret -eq 1 ] && (echo $file | grep -q -e "whirlpool") && echo " [N/A]" && continue
|
||||
# ignore flawed whirlpool (pwd failed is exit code 2)
|
||||
[ $ret -eq 2 ] && (echo $file | grep -q -e "whirlpool") && \
|
||||
($CRYPTSETUP luksDump $file --debug | grep -q -e "flawed whirlpool") && \
|
||||
echo " [IGNORED (flawed Whirlpool library)]" && continue
|
||||
[ $ret -ne 0 ] && fail
|
||||
$CRYPTSETUP status $MAP >/dev/null || fail
|
||||
$CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail
|
||||
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
|
||||
|
||||
Binary file not shown.
@@ -6,6 +6,7 @@ CRYPTSETUP=../src/cryptsetup
|
||||
DEV_NAME=dmc_test
|
||||
HEADER_IMG=mode-test.img
|
||||
PASSWORD=3xrododenron
|
||||
PASSWORD1=$PASSWORD
|
||||
|
||||
# cipher-chainmode-ivopts:ivmode
|
||||
CIPHERS="aes twofish serpent"
|
||||
@@ -134,10 +135,12 @@ dmcrypt aes aes-cbc-plain
|
||||
dmcrypt aes-plain aes-cbc-plain
|
||||
|
||||
# empty cipher
|
||||
PASSWORD=""
|
||||
dmcrypt null cipher_null-ecb
|
||||
dmcrypt cipher_null cipher_null-cbc-plain
|
||||
dmcrypt cipher_null-ecb
|
||||
|
||||
PASSWORD=$PASSWORD1
|
||||
# codebook doesn't support IV at all
|
||||
for cipher in $CIPHERS ; do
|
||||
dmcrypt "$cipher-ecb"
|
||||
|
||||
@@ -26,13 +26,14 @@ function fail()
|
||||
cleanup 2
|
||||
}
|
||||
|
||||
crypt_key() # hash keysize pwd/file name outkey [limit]
|
||||
crypt_key() # hash keysize pwd/file name outkey [limit] [offset]
|
||||
{
|
||||
DEV2=$DEV_NAME"_x"
|
||||
LIMIT=""
|
||||
MODE=aes-cbc-essiv:sha256
|
||||
[ $2 -gt 256 ] && MODE=aes-xts-plain
|
||||
[ -n "$6" ] && LIMIT="-l $6"
|
||||
[ -n "$7" ] && LIMIT="$LIMIT --keyfile-offset $7"
|
||||
|
||||
echo -n "HASH: $1 KSIZE: $2 / $3"
|
||||
case "$3" in
|
||||
@@ -52,8 +53,12 @@ crypt_key() # hash keysize pwd/file name outkey [limit]
|
||||
cat $4 | $CRYPTSETUP create -c $MODE -h $1 -s $2 $LIMIT $DEV2 /dev/mapper/$DEV_NAME 2>/dev/null
|
||||
ret=$?
|
||||
;;
|
||||
cat-)
|
||||
cat $4 | $CRYPTSETUP create -c $MODE -h $1 -s $2 $LIMIT $DEV2 -d - /dev/mapper/$DEV_NAME 2>/dev/null
|
||||
ret=$?
|
||||
;;
|
||||
file)
|
||||
$CRYPTSETUP create -c $MODE -d $4 -h $1 -s $2 $DEV2 /dev/mapper/$DEV_NAME 2>/dev/null
|
||||
$CRYPTSETUP create -q -c $MODE -d $4 -h $1 -s $2 $DEV2 /dev/mapper/$DEV_NAME 2>/dev/null
|
||||
ret=$?
|
||||
;;
|
||||
failpwd)
|
||||
@@ -126,6 +131,7 @@ echo -n -e "0123456789abcdef\n\x01\x00\x03\xff\xff\r\xff\xff\n\r" \
|
||||
"2352j3rkjhadcfasc823rqaw7e1 3dq sdq3d 2dkjqw3h2=====" >$KEY_FILE
|
||||
KEY_FILE_HEX="303132333435363738396162636465660a010003ffff0dffff0a0d20323335326a33726b6a686164636661736338323372716177376531203364712073647133"
|
||||
|
||||
# ignore hash if keyfile is specified
|
||||
crypt_key ripemd160 256 file $KEY_FILE ${KEY_FILE_HEX:0:64}
|
||||
crypt_key sha256 256 file $KEY_FILE ${KEY_FILE_HEX:0:64}
|
||||
crypt_key sha256 128 file $KEY_FILE ${KEY_FILE_HEX:0:32}
|
||||
@@ -134,8 +140,22 @@ crypt_key sha256 512 file $KEY_FILE $KEY_FILE_HEX
|
||||
# stdin can be limited
|
||||
crypt_key plain 128 cat /dev/zero 00000000000000000000000000000000 16
|
||||
crypt_key plain 128 cat /dev/zero 00000000000000000000000000000000 17
|
||||
|
||||
# read key only up to \n
|
||||
crypt_key plain 128 cat $KEY_FILE ${KEY_FILE_HEX:0:28}0000 14
|
||||
|
||||
# read full key, ignore keyfile length
|
||||
crypt_key plain 128 cat- $KEY_FILE ${KEY_FILE_HEX:0:32}
|
||||
crypt_key plain 128 cat- $KEY_FILE ${KEY_FILE_HEX:0:32} 14
|
||||
|
||||
# but do not ignore hash if keysgfile is "-"
|
||||
crypt_key sha256 128 cat- $KEY_FILE f3b827c8a6f159ad8c8ed5bd5ab3f8c5
|
||||
crypt_key sha256 128 cat- $KEY_FILE f3b827c8a6f159ad8c8ed5bd5ab3f8c5 0
|
||||
crypt_key sha256 128 cat- $KEY_FILE f3b827c8a6f159ad8c8ed5bd5ab3f8c5 80
|
||||
crypt_key sha256 128 cat- $KEY_FILE a82c9227cc54c7475620ce85ba1fca1e 14
|
||||
crypt_key sha256 128 cat- $KEY_FILE 7df3f4a41a33805596be85c781cac3b4 14 2
|
||||
crypt_key sha256 128 cat- $KEY_FILE ebbe65a178e886ddbb778e0a5538db72 40 40
|
||||
|
||||
# limiting plain (no hash)
|
||||
crypt_key plain 256 pwd "xxxxxxxx" 7878787878787878000000000000000000000000000000000000000000000000
|
||||
crypt_key plain:2 256 pwd "xxxxxxxx" 7878000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -12,6 +12,8 @@ PWD1="93R4P4pIqAH8"
|
||||
PWD2="1cND4319812f"
|
||||
PWD3="1-9Qu5Ejfnqv"
|
||||
|
||||
MNT_DIR=./mnt_luks
|
||||
START_DIR=$(pwd)
|
||||
|
||||
function del_scsi_device()
|
||||
{
|
||||
@@ -25,6 +27,8 @@ function remove_mapping()
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
|
||||
[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
|
||||
rm -f $IMG $ORIG_IMG $KEY1 >/dev/null 2>&1
|
||||
umount $MNT_DIR > /dev/null 2>&1
|
||||
rmdir $MNT_DIR > /dev/null 2>&1
|
||||
LOOPDEV1=""
|
||||
del_scsi_device
|
||||
}
|
||||
@@ -33,6 +37,7 @@ function fail()
|
||||
{
|
||||
[ -n "$1" ] && echo "$1"
|
||||
echo "FAILED"
|
||||
cd $START_DIR
|
||||
remove_mapping
|
||||
exit 2
|
||||
}
|
||||
@@ -74,6 +79,7 @@ function wipe() # $1 pass
|
||||
{
|
||||
open_crypt $1
|
||||
wipe_dev /dev/mapper/$DEV_NAME
|
||||
udevadm settle >/dev/null 2>&1
|
||||
$CRYPTSETUP luksClose $DEV_NAME || fail
|
||||
}
|
||||
|
||||
@@ -161,17 +167,50 @@ function simple_scsi_reenc()
|
||||
$CRYPTSETUP luksClose $DEV_NAME || fail
|
||||
}
|
||||
|
||||
function mount_and_test() {
|
||||
test -d $MNT_DIR || mkdir -p $MNT_DIR
|
||||
mount $@ $MNT_DIR 2>/dev/null || {
|
||||
echo -n "failed to mount [SKIP]"
|
||||
return 0
|
||||
}
|
||||
rm $MNT_DIR/* 2>/dev/null
|
||||
cd $MNT_DIR
|
||||
echo $PWD2 | $START_DIR/$REENC $LOOPDEV1 -q --use-fsync --use-directio --write-log || return 1
|
||||
cd $START_DIR
|
||||
umount $MNT_DIR
|
||||
echo -n [OK]
|
||||
}
|
||||
|
||||
function test_logging_tmpfs() {
|
||||
echo -n "[tmpfs]"
|
||||
mount_and_test -t tmpfs none -o size=$[25*1024*1024] || return 1
|
||||
echo
|
||||
}
|
||||
|
||||
function test_logging() {
|
||||
echo -n "$1:"
|
||||
for img in $(ls img_fs*img.bz2) ; do
|
||||
wipefs -a $SCSI_DEV > /dev/null
|
||||
echo -n "[${img%.img.bz2}]"
|
||||
bzip2 -d -c $img | dd of=$SCSI_DEV >/dev/null 2>&1
|
||||
mount_and_test $SCSI_DEV || return 1
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
|
||||
[ ! -x "$REENC" ] && skip "Cannot find $REENC, test skipped."
|
||||
which wipefs >/dev/null || skip "Cannot find wipefs, test skipped."
|
||||
|
||||
# REENCRYPTION tests
|
||||
|
||||
HASH1=b69dae56a14d1a8314ed40664c4033ea0a550eea2673e04df42a66ac6b9faf2c
|
||||
HASH2=d85ef2a08aeac2812a648deb875485a6e3848fc3d43ce4aa380937f08199f86b
|
||||
HASH3=e4e5749032a5163c45125eccf3e8598ba5ed840df442c97e1d5ad4ad84359605
|
||||
HASH4=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74
|
||||
|
||||
echo "[1] Reencryption"
|
||||
prepare 8192
|
||||
prepare 8192
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat -s 128 -c aes-cbc-plain -i 1 --align-payload 4096 $LOOPDEV1 || fail
|
||||
wipe $PWD1
|
||||
check_hash $PWD1 $HASH1
|
||||
@@ -266,5 +305,24 @@ check_hash $PWD1 $HASH1
|
||||
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --iter-time 1
|
||||
check_hash $PWD1 $HASH1
|
||||
|
||||
echo "[9] Test log I/Os on various underlaying block devices"
|
||||
prepare 8192
|
||||
echo $PWD2 | $CRYPTSETUP -q luksFormat -i 1 $LOOPDEV1 || fail
|
||||
add_scsi_device sector_size=512 dev_size_mb=25
|
||||
test_logging "[512 sector]" || fail
|
||||
add_scsi_device sector_size=4096 dev_size_mb=25
|
||||
test_logging "[4096 sector]" || fail
|
||||
add_scsi_device sector_size=512 dev_size_mb=25 physblk_exp=3
|
||||
test_logging "[4096/512 sector]" || fail
|
||||
test_logging_tmpfs || fail
|
||||
|
||||
echo "[10] Removal of encryption"
|
||||
prepare 8192
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat -i 1 $LOOPDEV1 || fail
|
||||
wipe $PWD1
|
||||
check_hash $PWD1 $HASH1
|
||||
echo $PWD1 | $REENC $LOOPDEV1 -q --decrypt
|
||||
check_hash_dev $LOOPDEV1 $HASH4
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
@@ -70,23 +70,23 @@ export LANG=C
|
||||
[ ! -d $TST_DIR ] && tar xjf tcrypt-images.tar.bz2
|
||||
|
||||
echo "HEADER CHECK"
|
||||
for file in $(ls $TST_DIR/tc_*) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*) ; do
|
||||
echo -n " $file"
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump $file >/dev/null || fail
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $file >/dev/null || fail
|
||||
echo " [OK]"
|
||||
done
|
||||
|
||||
echo "HEADER CHECK (HIDDEN)"
|
||||
for file in $(ls $TST_DIR/tc_*-hidden) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do
|
||||
echo -n " $file (hidden)"
|
||||
echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptDump --tcrypt-hidden $file >/dev/null || fail
|
||||
echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptDump --tcrypt-hidden --veracrypt $file >/dev/null || fail
|
||||
echo " [OK]"
|
||||
done
|
||||
|
||||
echo "HEADER KEYFILES CHECK"
|
||||
for file in $(ls $TST_DIR/tck_*) ; do
|
||||
for file in $(ls $TST_DIR/[tv]ck_*) ; do
|
||||
echo -n " $file"
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump -d $TST_DIR/keyfile1 -d $TST_DIR/keyfile2 $file >/dev/null || fail
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt -d $TST_DIR/keyfile1 -d $TST_DIR/keyfile2 $file >/dev/null || fail
|
||||
echo " [OK]"
|
||||
done
|
||||
|
||||
@@ -97,10 +97,13 @@ if [ $(id -u) != 0 ]; then
|
||||
fi
|
||||
|
||||
echo "ACTIVATION FS UUID CHECK"
|
||||
for file in $(ls $TST_DIR/tc_*) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*) ; do
|
||||
echo -n " $file"
|
||||
out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen -r $file $MAP 2>/dev/null)
|
||||
[ $? -ne 0 ] && ( echo "$out" | grep -q -v "TCRYPT legacy mode" ) && echo " [N/A]" && continue
|
||||
out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen --veracrypt -r $file $MAP 2>&1)
|
||||
ret=$?
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue
|
||||
[ $ret -ne 0 ] && fail
|
||||
$CRYPTSETUP status $MAP >/dev/null || fail
|
||||
$CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail
|
||||
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
|
||||
@@ -110,10 +113,13 @@ for file in $(ls $TST_DIR/tc_*) ; do
|
||||
done
|
||||
|
||||
echo "ACTIVATION FS UUID (HIDDEN) CHECK"
|
||||
for file in $(ls $TST_DIR/tc_*-hidden) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do
|
||||
echo -n " $file"
|
||||
out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen -r $file $MAP --tcrypt-hidden 2>/dev/null)
|
||||
[ $? -ne 0 ] && ( echo "$out" | grep -q -v "TCRYPT legacy mode" ) && echo " [N/A]" && continue
|
||||
out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen --veracrypt -r $file $MAP --tcrypt-hidden 2>&1)
|
||||
ret=$?
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue
|
||||
[ $ret -ne 0 ] && fail
|
||||
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
|
||||
$CRYPTSETUP remove $MAP || fail
|
||||
[ "$UUID" != "CAFE-BABE" ] && fail "UUID check failed."
|
||||
|
||||
Binary file not shown.
@@ -9,7 +9,7 @@ IMG_HASH=verity-hash
|
||||
|
||||
function remove_mapping()
|
||||
{
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
|
||||
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1
|
||||
[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
|
||||
rm -f $IMG $IMG_HASH $DEV_OUT >/dev/null 2>&1
|
||||
LOOPDEV1=""
|
||||
@@ -102,7 +102,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
|
||||
dmsetup status $DEV_NAME | grep "verity V" >/dev/null || fail
|
||||
echo -n "[in-kernel verify]"
|
||||
|
||||
$VERITYSETUP remove $DEV_NAME || fail
|
||||
$VERITYSETUP remove $DEV_NAME >/dev/null 2>&1 || fail
|
||||
|
||||
case $fail in
|
||||
data)
|
||||
@@ -126,7 +126,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
|
||||
dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null
|
||||
dmsetup status $DEV_NAME | grep "verity V" >/dev/null && \
|
||||
fail "in-kernel check for $TXT corruption"
|
||||
$VERITYSETUP remove $DEV_NAME || fail "deactivation"
|
||||
$VERITYSETUP remove $DEV_NAME >/dev/null 2>&1 || fail "deactivation"
|
||||
echo "[$TXT corruption]"
|
||||
done
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user