Compare commits

...

94 Commits

Author SHA1 Message Date
Milan Broz
7ae863e380 Prepare version 1.6.8. 2015-09-08 12:53:48 +02:00
Milan Broz
f238e8c075 Add 1.6.8 release notes. 2015-09-08 12:26:54 +02:00
Milan Broz
7d9a14fd24 Fix some signed/unsigned compiler warnings. 2015-09-08 08:12:07 +02:00
Milan Broz
2f964d95d8 Fix benign warning in clang analysis output. 2015-09-08 07:54:03 +02:00
Milan Broz
00f419e5ea Add zh_CN.po. 2015-09-05 13:07:05 +02:00
Milan Broz
cc698dcde3 Update es.po. 2015-08-31 10:08:36 +02:00
Milan Broz
edced6cfed Update nl.po. 2015-08-30 12:58:33 +02:00
Milan Broz
4fb11976d2 Update po files. 2015-08-28 12:59:59 +02:00
Milan Broz
68ba5b2b36 Update fr.po. 2015-08-27 16:22:13 +02:00
Milan Broz
65fa22ff23 Override password quality check if used cipher is cipher_null. 2015-08-27 16:21:07 +02:00
Milan Broz
c25d81d2a1 Update po files. 2015-08-27 07:53:13 +02:00
Milan Broz
57d16a7a55 Fix misleading error messages in reencrypt. 2015-08-26 16:15:11 +02:00
Milan Broz
def397d0c8 Update libcryptsetup.h comments. 2015-08-26 16:10:10 +02:00
Milan Broz
7843415243 Move string_to_size to userspace tools. 2015-08-26 12:42:25 +02:00
Milan Broz
5a8b045bdd Properly support stdin "-" handling for luksAddKey. 2015-08-26 12:41:20 +02:00
Milan Broz
ab62f45d57 Use stdin and "-" file check wrapper. 2015-08-26 10:54:33 +02:00
Milan Broz
e521edd6ca Print cryptsetup library version in crypto init. 2015-08-26 10:42:47 +02:00
Milan Broz
3a0293a299 Do not link FIPS helper to cryptsetup anymore.
Just print info about FIPS mode in RNG init.
2015-08-26 10:36:49 +02:00
Milan Broz
8a4db1ad7b Ingore Whirlpool test instead of failing. 2015-08-26 10:35:38 +02:00
Milan Broz
1aba9ab444 Cryptsetup resize will try resize also underlying device.
If encrypted device is file-backed, resize should try to resize
underlying loop device as well.
2015-08-19 14:16:42 +02:00
Milan Broz
dfa2755aba If the null cipher is used, allow only empty password for LUKS.
The cipher_null is no-encryption, it can be used for testing
or temporarily when encrypting device (cryptsetup-reencrypt).

Accepting only empty password prevents situation when you replace
a LUKS header on an unlocking device with the faked header using
null cipher (and the same UUID).
Here a system could think that the device was properly unlocked
(with any entered password) and will try to use this unencrypted
partition instead.
(IOW it prevents situation when attacker intentionaly forces
an user to boot into dirrerent 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 not allow this situation in the first place.
(Despite the fact that once you allow physical tampering of your system
it cannot be properly secured anymore.)
2015-07-02 08:21:19 +02:00
Milan Broz
6e82bdd9a5 Do not use real password when unlocking "fake" header on reecryption.
If reencrypt removes encryption (or adds encryption to not yet encrypted system)
there is a temporary header using null (none) cipher.
We do not need to pass through password when unlocking these devices.
2015-07-02 08:18:44 +02:00
Milan Broz
0dc245401f Allow to enter empty password through stdin pipe.
Also always use empty passsword when using null cipher in tests.
2015-07-02 08:18:12 +02:00
Milan Broz
a57f1b1b64 Silence repeated device removal in verity test. 2015-07-02 08:13:42 +02:00
Milan Broz
1a50fee1d0 Update po files. 2015-04-19 09:55:13 +02:00
Milan Broz
046e0e5280 Update README.md. 2015-03-23 21:20:56 +01:00
Milan Broz
656b55cd4b Set devel version. 2015-03-23 20:41:33 +01:00
Milan Broz
8d7af433d8 Update po files. 2015-03-23 20:40:04 +01:00
Milan Broz
dc3de39eb7 Include prototype for stat(). 2015-03-23 20:38:14 +01:00
Milan Broz
3d403a7bd0 Bump libcryptsetup version. 2015-03-23 18:22:16 +01:00
Milan Broz
91f6296699 Prepare version 1.6.7. 2015-03-23 17:49:06 +01:00
Milan Broz
bd94eb36b3 Update po files. 2015-03-20 13:32:42 +01:00
Milan Broz
1a19329b18 Use silent rules in autoconf. 2015-03-20 13:32:13 +01:00
Milan Broz
78a43c053a Update po files. 2015-03-19 12:35:09 +01:00
Milan Broz
d7d76e72f7 Update URLs (->gitlab.com).
The code.google is going to be abandoned.
Thank you you for all the fish.
2015-03-19 11:23:16 +01:00
Milan Broz
dd0dcc05df Fix typo in URL. 2015-03-19 11:05:28 +01:00
Milan Broz
3be8731fef Add notes about releases. 2015-03-19 11:03:14 +01:00
Milan Broz
86d0ff1a2b Add README.md for project page info. 2015-03-19 10:43:40 +01:00
Milan Broz
3adfe80601 Test device read only once for O_DIRECT.
Also do not report error for disappeared device (it is reported later on real access).
2015-03-19 09:39:36 +01:00
Milan Broz
0bc437d92c Detect if O_DIRECT is usable on device allocation.
Try to read the first sector of a device when allocating
device context.

Should fix issue#247.
2015-03-18 15:01:53 +01:00
Milan Broz
6b10f30eb9 Reorder algorithms for VeraCrypt modes. 2015-02-27 10:12:54 +01:00
Milan Broz
fedd5bc969 Update de.po. 2015-02-26 08:08:16 +01:00
Milan Broz
8aee4f95fb Clarify using of VeraCrypt modes in libcryptsetup.h. 2015-02-25 10:55:24 +01:00
Milan Broz
1f2d8de95f Support VeraCrypt devices (TrueCrypt extension).
Add CRYPT_TCRYPT_VERA_MODES libcryptswtup flag and
--veracrypt option.

Fixes issue#245.
2015-02-24 22:04:15 +01:00
Milan Broz
dced269426 Update kernel version in man page. 2015-02-23 10:19:02 +01:00
Milan Broz
b834a59eaf Fix typo in man page.
Fixes issue#244.
2015-02-20 16:57:20 +01:00
Milan Broz
4f7b413638 Add low-level performance options for dmcrypt tuning.
The patch adds the two options
  --perf-same_cpu_crypt
  --perf-submit_from_crypt_cpus
that set the same named options inside dmcrypt
(available in Linux kernel 3.20 and later).
2015-02-20 16:46:34 +01:00
Milan Broz
e4355c2973 Wait for udev scan before removing device in reencrypt test. 2015-02-20 13:02:27 +01:00
Milan Broz
31a4d552a2 Support keyfile offset and keyfile size option even for plain volumes.
For historic reasons, in the plain mode the hashing is not used
if keyfile is used (with exception of --key-file=-).

Print warning if the parameters are ignored.

For other cases, uses keyfile offset, keyfile size and hash
as psecified on commandline.

Partially fixes issue#243
2015-02-20 12:55:21 +01:00
Milan Broz
6d51e8ab69 Support permanent device decryption using cryptsetup-reencrypt --decrypt. 2015-01-27 14:20:34 +01:00
Milan Broz
8157e47ad4 Support keyfile for luksAddKey if the master key is specified.
If AddKey was called with master key argument, the code always asked
for a passphrase ignoring the keyfile argument.

Now it is properly processed as the same as if no master key is specified.
2015-01-26 14:42:46 +01:00
Milan Broz
62b0138dad Allow to use --header option in all LUKS commands.
The --header always takes precedence over positional device argument.

Also allow specify UUID= for luksSuspend and luksResume if used with
detached header.
2015-01-26 13:31:37 +01:00
Milan Broz
c13a8003fa Mention that loop-AES extension cannot use real terminal for key file input.
Based on issue#242.
2015-01-15 16:03:54 +01:00
Milan Broz
979aec773e Fix activation using (UNSECURE) ECB mode.
Apparently there are some people using ECB.

This mode by design do not use any IV, unfortunately
kernel dmcrypt allows to specify them (but userspace crypto api don't).

Let support activation as it was in previous version.

Should fix issue#238.
2015-01-15 13:21:42 +01:00
Milan Broz
b789b011a2 Fix some compiler warnings introduced recently. 2015-01-15 12:27:34 +01:00
Colin Misare
ea8864badf printing unsigned fields as unsigned 2015-01-15 11:14:42 +01:00
Milan Broz
49335b600f Allow luksSuspend without explicitly specify detached header.
If LUKS device was configured to use detached header, suspend operation
required --header option. For now it is enough that active device in-kernel
UUID type is set properly.

FIxes issue#229.
2015-01-15 10:40:17 +01:00
Milan Broz
7245af59d3 Get rid of libfipscheck library.
With recent RHEL changes we need only check /sys file
and do not need to link to this FIPS monster.
2015-01-12 21:56:44 +01:00
Milan Broz
f7b61b2617 Prevent compiler to optiize-out memset for on-stack variables.
Also see
https://cryptocoding.net/index.php/Coding_rules#Prevent_compiler_interference_with_security-critical_operations

The used code is inspired by the code in Blake2 implementation.
2015-01-11 20:26:45 +01:00
Ondrej Kozina
dc40b91cdf libcryptsetup: drop FIPS power on self test
- cryptsetup library is not required to be FIPS certified anymore
  due to fact gcrypt PBKDF2 algorithm can be used instead of
  cryptsetup internal one.

- check in library constructor is no longer needed and therefore
  removed.

- all other checks regarding MK extraction or random generator
  restrictions remain the same
2015-01-10 21:09:17 +01:00
Milan Broz
eccf347568 Flush stdout when expecting user input on stdin. 2015-01-10 20:36:49 +01:00
Milan Broz
e24a72f84c Fix crash if non-GNU strerror_r is used.
The strerror_r call exists in POSIX and GNU variant,
if POSIX variant is used (like in musl libc replacement)
we cannot rely on char* pointer.

Fixes issue#237.
2015-01-10 20:33:42 +01:00
Milan Broz
2c70c057d6 Fix typo in man page. 2014-11-02 18:18:36 +01:00
Milan Broz
f16f37233f Fix partial reads and handle EINTR in reencryption code.
The partial read usually happens only on IO error,
so reencrypt at least part what is read properly.

For EINTR code must restart read completely.

Fixes issue#226.
2014-10-04 15:39:38 +02:00
Ondrej Kozina
3cffadb508 fix possible close of unrelated fd on error path
- infd var is uninitialised on error path in case where
  maxlen is less than 1
2014-10-01 20:10:23 +02:00
Ondrej Kozina
ce30d5f1fd add vfat test image 2014-09-23 21:31:18 +02:00
Ondrej Kozina
6e0f0408a0 reencrypt-compat-test: test log I/Os on various fs 2014-09-23 21:31:10 +02:00
Ondrej Kozina
3d6bcae84c reencrypt: use fsync instead of O_DIRECT flag
O_DIRECT operations directed towards filesystem are problematic:
There's no sane way how to detect specific filesystem requirements
for such operations.

This patch is replacing O_DIRECT flag with O_SYNC flag for all
open() calls related to reencrypt log. The O_SYNC flag is used
when --use-fsync option is detected.

Man page is modified accordingly.
2014-09-23 18:47:02 +02:00
Milan Broz
b8beedb621 Fix typo in man page. 2014-08-30 10:37:49 +02:00
Milan Broz
fd5c2a5000 Update po files. 2014-08-22 12:43:10 +02:00
Milan Broz
69bc154fca Update po files. 2014-08-18 20:49:11 +02:00
Milan Broz
387041ccf2 Set devel version. 2014-08-16 12:24:25 +02:00
Milan Broz
64d6b339a0 Prepare version 1.6.6. 2014-08-16 11:15:46 +02:00
Milan Broz
4f5f1b78c4 Update po files. 2014-08-16 11:00:18 +02:00
Milan Broz
3e886ecf57 Update po files. 2014-08-13 17:50:00 +02:00
Milan Broz
210ea612b3 Avoid compilation warnings in Python wrapper.
All these are Python interface misconceptions,
the strings (or string arrays) in parameters should be const
parameters.

To avoid gcc confusing warnings just explicitly re-cast them.
2014-08-10 16:09:32 +02:00
Milan Broz
3350ff017f Do not allocate big context on stack for cryptsetup-reencrypt. 2014-08-10 16:09:01 +02:00
Milan Broz
7b42254975 Workaround for scan-build false positive.
Also tidy code to be more readable.
2014-08-10 16:07:47 +02:00
Milan Broz
e84b1ed7c0 Fix scan-build warning (null use).
Probably false positive but defensive approach is better here.
2014-08-10 16:06:21 +02:00
Milan Broz
f3f1bfd73a Update po files. 2014-08-09 15:14:38 +02:00
Milan Broz
89f795d7b4 Fix keyslot device access for devices not supporting O_DIRECT. 2014-08-08 14:49:38 +02:00
Milan Broz
c36a7968f4 Add test for tmpfs / O_DIRECT etc. 2014-08-08 14:09:37 +02:00
Milan Broz
3762c8b76e Report crypto lib version only once (and add kernel version). 2014-07-27 20:39:06 +02:00
Milan Broz
872becdbbd Handle also missing support for tcrypt test in kernel properly. 2014-07-27 19:39:53 +02:00
Milan Broz
c9694437d2 Fix tcrypt test for unsupported combinations. 2014-07-27 18:40:21 +02:00
Milan Broz
64ad90f73c Ignore wrong parameters fail in LUKS images tests if whirlpool hash is used. 2014-07-27 17:02:51 +02:00
Milan Broz
166d23a813 Fix tests for GNU grep syntax. 2014-07-27 16:31:46 +02:00
Milan Broz
59fdf2a6bb Properly allow activation of discard even if dm_crypt module is not yet loaded.
The dm_flags() call cannot be used if dmcrypt module is not present.

Better try to activate volume with dicard flags and if it is not possible,
try to activate device without the discard flag.
2014-07-24 22:11:58 +02:00
Milan Broz
3640eaa726 Re-check flags after DM device creations. 2014-07-24 11:52:58 +02:00
Milan Broz
2250d5f71f Move safe table params wipe into function which allocates it. 2014-07-24 11:37:24 +02:00
Milan Broz
d9678325a2 Update LUKS1 test images. 2014-07-12 21:16:19 +02:00
Milan Broz
dc8c47d936 Fallback to old temporary device mapping method if hash is not supported. 2014-07-12 20:30:24 +02:00
Milan Broz
5b7100ff87 Update po files. 2014-07-10 19:06:11 +02:00
Milan Broz
4afa592160 Set devel version. 2014-06-29 14:36:10 +02:00
73 changed files with 10918 additions and 4090 deletions

11
FAQ
View File

@@ -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
View File

@@ -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
View File

@@ -0,0 +1,75 @@
![LUKS logo](https://gitlab.com/cryptsetup/cryptsetup/wikis/luks-logo.png)
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
View File

@@ -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).

View File

@@ -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],

View File

@@ -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
View 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
View 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
View 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.

View File

@@ -39,7 +39,6 @@ libcryptsetup_la_LIBADD = \
@UUID_LIBS@ \
@DEVMAPPER_LIBS@ \
@CRYPTO_LIBS@ \
@FIPSCHECK_LIBS@ \
$(common_ldadd)

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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(&params, " ");
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;
}

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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:

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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};

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,4 +1,5 @@
cs
da
de
es
fi
@@ -7,6 +8,8 @@ id
it
nl
pl
sr
sv
uk
vi
zh_CN

709
po/cs.po

File diff suppressed because it is too large Load Diff

1775
po/da.po Normal file

File diff suppressed because it is too large Load Diff

925
po/de.po

File diff suppressed because it is too large Load Diff

709
po/es.po

File diff suppressed because it is too large Load Diff

711
po/fi.po

File diff suppressed because it is too large Load Diff

730
po/fr.po

File diff suppressed because it is too large Load Diff

740
po/it.po

File diff suppressed because it is too large Load Diff

744
po/nl.po

File diff suppressed because it is too large Load Diff

704
po/pl.po

File diff suppressed because it is too large Load Diff

1777
po/sr.po Normal file

File diff suppressed because it is too large Load Diff

707
po/uk.po

File diff suppressed because it is too large Load Diff

754
po/vi.po

File diff suppressed because it is too large Load Diff

1770
po/zh_CN.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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*

View File

@@ -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

View File

@@ -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)

View File

@@ -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
View 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

View File

@@ -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

Binary file not shown.

View File

@@ -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.

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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