Compare commits

...

119 Commits

Author SHA1 Message Date
Milan Broz
2e97d8f8e8 Prepare version 1.6.4. 2014-02-27 14:36:13 +01:00
Milan Broz
7effba0f71 Fix return codes from LUKS_set_key. 2014-02-27 14:19:01 +01:00
Milan Broz
2ad69eba90 Verify new passphrase by default in luksChangeKey and luksAddKey. 2014-02-27 13:26:05 +01:00
Milan Broz
4d218e4cbd Update de.po. 2014-02-24 21:57:04 +01:00
Milan Broz
a0346a09ce Update download directory. 2014-02-21 21:44:29 +01:00
Milan Broz
f6e85be3ed Update pl.po. 2014-02-21 21:42:22 +01:00
Milan Broz
04e921846f Update po files. 2014-02-19 19:53:40 +01:00
Milan Broz
e37f3728d7 Add 1.6.4 Release notes. 2014-02-16 10:45:08 +01:00
Milan Broz
2062ece2ab Some new items for TODO list. 2014-02-16 10:15:13 +01:00
Milan Broz
a5fa6f1015 Remove trailing spaces from man pages. 2014-02-16 10:05:39 +01:00
wagner
9bdd5bf4fe clarified hash use for -h and -c in the man-page. 2014-02-13 06:54:58 +01:00
Milan Broz
110ce5607e Update fi.po. 2014-02-08 19:08:26 +01:00
Milan Broz
78f938b0e9 Add old cryptsetup udev rules (for archive reasons).
Do not install these until you know what are you doing.
2014-02-05 17:22:07 +01:00
Milan Broz
ad2f50316f Fix memory leak in Nettle crypto backend. 2014-02-05 17:17:55 +01:00
Milan Broz
cf534f3759 Implement erase command. 2014-02-05 17:17:12 +01:00
Milan Broz
75c105f853 Do not retry to test gcrypt whirlpool bug. 2014-01-21 20:55:21 +01:00
Milan Broz
680eb76e45 Add internal shortcut for flawed whirlpool hash in gcrypt. 2014-01-19 20:31:48 +01:00
Milan Broz
e364041b40 Add --keep-key to cryptsetup-reencrypt.
This allows change of LUKS header hash (and iteration count) without
the need to reencrypt the whole data area.
2014-01-19 15:29:12 +01:00
wagner
de37457a75 sync with Wiki-Version 2014-01-18 20:39:09 +01:00
Milan Broz
057db3b3b3 Do not use gcrypt KDF in 1.6.0, it is slow.
I hope 1.6.1 will have patch included (already in devel).
2014-01-18 13:09:51 +01:00
Milan Broz
461011ad2a Add test for flawed Whirlpool hash to gcrypt backend.
Will be used later, for now add info to debug.
Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
2014-01-18 13:05:56 +01:00
Milan Broz
aa7346bb36 Allow to use --disable-gcrypt-pbkdf2.
Unfortunately gcrypt PBKDF2 in libgcrypt 1.6.0 is very slow.
Until patch is accepted, let's allow switch back to internal kdf
implementation.

Fixes Issue#199, also see
https://bugzilla.redhat.com/show_bug.cgi?id=1051733
2014-01-15 20:06:12 +01:00
Milan Broz
5206543902 Fix api test keyfile write. 2014-01-12 13:39:15 +01:00
Milan Broz
7f93a49cc3 Support --tries option even for TCRYPT devices in cryptsetup. 2014-01-12 11:37:21 +01:00
Milan Broz
bec86e3d5a Support discard option even for TCRYPT devices. 2014-01-11 22:13:37 +01:00
Axel Lin
3ba95a822f Link against -lrt for clock_gettime
Fix undefined reference to `clock_gettime' error.
This is required since commit f3e398afc5 "Rewrite cipher benchmark loop.".

Below is the build error report:
http://autobuild.buildroot.net/results/9ca/9cad1cf49ee6b5c58d8260ee33beef2e6c1ada4d/build-end.log

Signed-off-by: Axel Lin <axel.lin@ingics.com>
2014-01-01 21:13:09 +01:00
Milan Broz
486ec44c3e Fix previous commit (do not print warning even for wrong passphrase). 2014-01-01 21:11:12 +01:00
Milan Broz
8dc4877697 Fix error message when some algoritmhs are not available.
Fixes http://www.saout.de/pipermail/dm-crypt/2013-December/003721.html
2013-12-29 09:56:23 +01:00
Milan Broz
7415c5858d Count system time in PBKDF2 benchmark if kernel return no self usage info.
This is kind of workaround for Issue#192...
2013-12-22 10:12:36 +01:00
Milan Broz
8e5411f468 Set devel version. 2013-12-14 11:23:10 +01:00
Milan Broz
3bf40bb8dd Add 1.6.3 ChangeLog. 2013-12-13 21:33:53 +01:00
Milan Broz
79956a4d47 Fix skip/offset option description in man page. 2013-12-11 23:22:03 +01:00
Milan Broz
2d755335de Fix previous commit. 2013-12-08 18:15:00 +01:00
Milan Broz
d7762c09dd Add new test images to automake file list. 2013-12-08 18:02:58 +01:00
Milan Broz
957201e758 Fix reencryption tool to work with 4k devices.
See https://bugzilla.redhat.com/show_bug.cgi?id=1029032#c7

Thanks to Ondra Kozina to figure this out.
2013-12-08 17:50:25 +01:00
Milan Broz
004dc271a4 Fix wrong block size if used on 4k block fs through loop device.
Always use page size if running through loop device.
2013-12-08 16:09:25 +01:00
Milan Broz
a9b24ccc82 Remove obsoleted warning. 2013-12-08 00:04:32 +01:00
Milan Broz
c57071a43a Fix TCRYPT system encryption mapping for multiple partitions.
Since this commit, one can use partition directly as device parameter.

Should fix Issue#183 and Issue#188.
2013-12-07 23:58:56 +01:00
Milan Broz
df27f04f61 Update po files. 2013-12-01 10:58:05 +01:00
Milan Broz
f3e398afc5 Rewrite cipher benchmark loop.
Using getrusage seems toi give not adequate precision,
so use clock_gettime and try to scale buffer size a bit
on high performance systems.

If it still fail, return ERANGE error instead calculating
completely unreliable numbers.

Should fix Issue#186.
2013-12-01 10:55:35 +01:00
Milan Broz
65877efe8b Update po files. 2013-11-25 21:26:33 +01:00
Milan Broz
96acd87f0b Update po files. 2013-11-24 17:47:14 +01:00
Milan Broz
fcb35d4e73 Prepare version 1.6.3.
For updating po files (translators).
2013-11-24 12:47:24 +01:00
Ondrej Kozina
0d47e5eb76 Enable reencryption tests using last keyslot 2013-11-21 19:48:17 +01:00
Ondrej Kozina
f30bbbffe7 Fix minimal size expectations failure for backup header file
- backup header file must be page size aligned
- fix for https://bugzilla.redhat.com/show_bug.cgi?id=1030288
- add regression test to api-tests
2013-11-21 19:48:12 +01:00
Ondrej Kozina
6b88461553 modify fips detection also in api-test 2013-11-21 19:48:03 +01:00
Milan Broz
700b558fb6 Fix api test to use proper key size.
LUKS format now reuires correct kernel parameters always,
so validation test must use different but still correct key size.
2013-11-20 22:20:15 +01:00
Milan Broz
58b5be440f Fix initialization of unknown used device.
dm_query can return open count, this should be processed
as success (and properly fail later ;-)
2013-11-19 20:57:23 +01:00
Milan Broz
626801f7df Unify LUKS type check.
Warn if device type is not set (incompatible activation
either by manual dmsetup or other tools).
2013-11-19 20:50:36 +01:00
Ondrej Kozina
77a345d4cb Add tests to reencryption-compat-test
- test --keyslot modification (commit: 5736b0a114)
- test reecryption w/o adding --keyslot option
- use variable instead of static string ("key1" -> KEY1)
- comment one failing test (https://bugzilla.redhat.com/show_bug.cgi?id=1030288)

[gmayland: removed some tests & added -i 1 to save test time]
2013-11-17 21:01:19 +01:00
Dave Reisner
18901fd501 libdevmapper: correctly compare major and minor versions
Previously, this code could incorrectly identify a version of crypt or
dm due to the way it compared versions. For example, if a feature was
gated on crypt version 1.5, it would disable the feature for crypt
version 2.2.
2013-11-14 08:32:02 +01:00
Milan Broz
5b86cb5cc2 Enable TCW dmcrypt version check (patch should be in kernel 3.13). 2013-11-10 22:20:30 +01:00
Milan Broz
ce23225e46 Check if provided cipher and mode is usable before writing LUKS header to disk.
If user provided unusable cipher-mode string, LUKS header was written and
keyslot creation failed later.

Better check early (by creating fake dmcrypt device) if cipher is usable
and fail early (without writing LUKS header to device).

Fixes Issue#176
2013-11-10 22:11:00 +01:00
Milan Broz
09c229fe6c Support limitation for "plain" hash (no hash).
This can be used for mapping problematic cryptosystems which
wipes some key (losetup sometimes set last byte to zero).
2013-11-10 19:31:02 +01:00
Milan Broz
db56125708 Fix hash limiting if parameter is not a number.
If hash lenght specification was not a number, the whole key was set
to zero instead of command failure.

Resolves
https://bugzilla.redhat.com/show_bug.cgi?id=1028362
2013-11-10 19:08:01 +01:00
Ondrej Kozina
5736b0a114 unify --key-slot behavior in cryptsetup_reencrypt
- cryptsetup-reencrypt: unify --key-slot behavior
  across the utility and enable the option even
  without --key-file.

[FIXME: add tests and man page revision]
2013-11-10 18:29:11 +01:00
Ondrej Kozina
a21c0503f8 make FIPS checks compliant with new guidance
(gmazyland: Simplified this NIST nonsense, should be still exactly
equivalent to former patch)
2013-11-10 18:10:39 +01:00
Ondrej Kozina
e52d5f3d98 90reencrypt fixes:
- add loop module to initramfs image
- modprobe loop before reencrypt start
- add rd.luks.reencrypt_keyslot=
- add conflict with dracut crypt module
- drop to emergency_shell after reencryption
2013-11-10 17:38:11 +01:00
Milan Broz
0e96b9d010 Update es.po. 2013-11-10 17:34:39 +01:00
Milan Broz
dcba8c28f2 Update es.po. 2013-10-29 20:37:03 +01:00
Milan Broz
da93a3320b Add commandline option --tcrypt-backup to access TCRYPT backup header. 2013-10-29 20:35:07 +01:00
Milan Broz
53607a0274 Add CBC TCRYPT VFAT id test images and run it by default. 2013-10-26 22:48:05 +02:00
Milan Broz
67d19f3570 Add es.po. 2013-10-26 18:54:12 +02:00
Milan Broz
54c1f71bd3 Detect presence of TCW mode support in kernel dmcrypt. 2013-10-20 13:20:22 +02:00
Milan Broz
a7e2809466 Properly calculate key sizes (inluding IV seed and whitening) for TCRYPT.
Also prepare code for possible activation through dmcrypt for some
CBC container variants.
2013-10-20 13:07:24 +02:00
Milan Broz
3f66e9fe4b Fix error path for DM UUID wrong format. 2013-10-20 13:06:16 +02:00
wagner
f547d0fac3 sunc with wiki version 2013-09-12 17:50:22 +02:00
Milan Broz
cdf272315e Update nl.po. 2013-08-12 08:15:29 +02:00
Milan Broz
31303718da Fix static compilation with OpenSSL.
Resolves issue#172, see
https://bugs.gentoo.org/show_bug.cgi?id=472692
2013-08-08 18:57:45 +02:00
Milan Broz
4192bdd731 Update pl.po. 2013-08-04 20:42:32 +02:00
Milan Broz
c18aa03552 Devel version switch. 2013-08-04 19:45:37 +02:00
Milan Broz
b2283f045a Version 1.6.2. 2013-08-04 19:01:55 +02:00
wagner
8e3863aa20 sync with wiki version 2013-08-02 23:53:22 +02:00
Milan Broz
79899badd0 Update fr.po. 2013-07-31 21:20:14 +02:00
Milan Broz
691b7a63f2 Update po files. 2013-07-30 07:45:12 +02:00
Milan Broz
154731306b Add 1.6.2 release notes.
Remove some TCRYPT comments from man page (FAQ is better for this).
2013-07-27 22:59:40 +02:00
Milan Broz
d67548adfe Fails if more device arguments are present for isLuks.
Fixes
http://code.google.com/p/cryptsetup/issues/detail?id=165
2013-07-27 12:43:48 +02:00
Milan Broz
cfeaaa02fc Fix sscanf cipher string and avoid warning wih -fsanitize=address.
Code need to count terminating zero.
2013-07-23 22:07:13 +02:00
Milan Broz
c5270f85d3 Update de.po. 2013-07-14 11:49:28 +02:00
wagner
45931a890d fixed all items in issue 164
Escaped dashes in options, e.g. \-\-iter-time => \-\-iter\-time
to prevent word-breaks at inner dashes.
2013-07-04 01:03:07 +02:00
wagner
1a5c169c06 Expanded more on protection of hidden TrueCrypt volumes and
its problems.
2013-07-02 03:23:49 +02:00
wagner
d8fbf43022 Added comment that a hidden volume is unprotected against changes
in its outer volume and hence the outer volume should not be mounted.
2013-07-02 03:00:02 +02:00
Milan Broz
3be96efe0b Map TCRYPT system encryption through partition.
Kernel doesn't allow mapping through whle device if some
other partition an the device is used.

So first try to find partition device which match
system encryption (== TCRYPT partition system encryption)
and use that.
2013-06-30 10:46:21 +02:00
Milan Broz
99a2486b09 Simplify sysfs helpers. 2013-06-30 09:05:43 +02:00
Milan Broz
c3c65ee864 Use internally common uint64 parsing for sysfs values. 2013-06-29 13:06:04 +02:00
Milan Broz
db0f5f8d22 Add kernel version to DM debug output. 2013-06-29 11:28:33 +02:00
Milan Broz
8b162ca258 Fix default modes in man page. 2013-06-28 20:39:54 +02:00
Mikulas Patocka
4f990d5a74 dm-verity: Fix a boundary condition that caused failure for certain device sizes
On Fri, 28 Jun 2013, Mikulas Patocka wrote:

Fix a boundary condition that caused failure for certain device sizes

The problem is reported at
http://code.google.com/p/cryptsetup/issues/detail?id=160

This is the userspace fix.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com
2013-06-28 17:05:45 +02:00
Cristian Rodríguez
1349efa34d Fix buildsytem to always include config.h.
- config.h must always be the first file to be included
- Use AM_CFLAGS and AM_LDFLAGS consistently and properly.

(Modified to disable build without largefile support etc
by Milan Broz <gmazyland@gmail.com>)
2013-06-23 17:14:33 +02:00
Milan Broz
cf99ecb5a9 Force use serial-tests.
Unfortunately, automake did not provided compatible way,
so if anyone need to use old automake, one line change
in is needed.
2013-06-23 16:16:43 +02:00
Milan Broz
0d818d0a92 Copy file in automake, never make symlinks. 2013-06-23 15:37:27 +02:00
Milan Broz
42b0ab437a Print a warning if system encryption is used and device is a partition.
System encryption hav metadata in space located ouside of
partition itself.

Ideally the check should be automatic but for virtualized systems
(where a partition could be "whole device" for another sustem this
can be dangerous.
2013-06-23 15:26:45 +02:00
Milan Broz
a36de633d5 Fix mapping of TCRYPT system encryption for more partitions.
If TCRYPT system encryption uses only partition (not the whole device)
some other partitions could be in use and we have to use
more relaxed check to allow device activation.
2013-06-23 15:24:01 +02:00
Cristian Rodríguez
8a43d49b89 build: test byteswap.h and endian.h for bitops.h
Otherwise the fallback code will be used.
2013-06-03 21:35:56 +02:00
Milan Broz
ae9c9cf369 Disallow explicit small payload offset for detached header.
LUKS detached header has some limitations, one of them
is that you cannot run some explicit check for data offsets
without providing also data device.

Because luksDump and all key handle commands takes only
metadata device (LUKS heaer device), it not easy to properly
support data payload offset validation.

So if detached header is present for luksFormat, code now
allows data payload 0 (IOW whole data device is used)
and explicit offset larger than header+keyslots
(the same as the header is on data device - so some space is wasted).

N.B. with detached header the option --align-payload is used
directly without any round up caculations.

Fixes Issue#155.
2013-05-11 10:59:02 +02:00
wagner
db44c27674 sync with Wiki 2013-04-25 00:08:42 +02:00
Milan Broz
efa2c7b08b Update nl.po. 2013-04-07 09:33:23 +02:00
wagner
a9441043bc sync with wiki version 2013-04-05 11:24:44 +02:00
Milan Broz
aaf0cfa3c1 Set devel version. 2013-03-31 11:59:54 +02:00
Milan Broz
2a2444b961 Fix gcc signed/unsigned warning for key length.
And always use unsigned int declaration.
2013-03-31 11:24:26 +02:00
Milan Broz
2526ec92bd Update vi.po. 2013-03-26 21:19:03 +01:00
Milan Broz
9bddc52601 Update po files. 2013-03-24 23:36:26 +01:00
Milan Broz
1b96e93f91 Add 1.6.1 release notes. 2013-03-24 10:02:19 +01:00
Milan Broz
6127b6959f Update copyright year on changed files. 2013-03-24 09:05:33 +01:00
Milan Broz
330007beb2 Fix loop-AES keyfile parsing.
Loop-AES keyfile should be text keyfile,
properly check that keys are terminated and of the same length.

Fixes issue#153.
2013-03-23 18:10:46 +01:00
wagner
cbfd48d949 Fixed the buit instruction
Improved example
2013-03-23 16:00:58 +01:00
Milan Broz
f64064fe71 Fix deactivation of device when failed underlying node disappeared
If underlying device disappears (failed drive, removed flash drive etc)
cryptsetup cannot report LUKS parameters (header no longer available).

Fix return code of init_by name in this situation (crypt
context is NULL).

Report visible error if deactivation fails and device is still busy.

Fixes issue#149.
2013-03-17 20:54:04 +01:00
Milan Broz
f2521889c2 Deactivate whole device TCRYPT tree if context is NULL
API (unfortunately) supports NULL argument for crypt_deactivate,
with new chained TCRYPT devices it must deactivate all
chained devices as well.

Fixes issue#147.
2013-03-17 19:20:42 +01:00
Milan Broz
642d41970d Update nl.po. 2013-03-17 17:34:41 +01:00
Milan Broz
acd069fd27 Update de.po. 2013-03-10 16:09:00 +01:00
Milan Broz
c810b0514e Return EPERM instead EINVAL for too long TCRYPT passphrase. 2013-02-15 09:52:22 +01:00
Milan Broz
e600024908 Fix passphrase pool overflow for TCRYPT device id passphrase > pool size.
TCRYPT format limits passphrase length to max. 64 characters so simply error in this case.
2013-02-14 14:37:50 +01:00
Milan Broz
fd5b88449a Make passphrase prompts more consistent.
Also see http://code.google.com/p/cryptsetup/issues/detail?id=145
2013-02-11 14:53:49 +01:00
John Spencer
433758e4cb Fix missing headers
2 header inclusions were missing, one for PATH_MAX (limits.h) and one
for FD_ZERO, FD_SET, ... (sys/select.h)

on glibc, those headers are erroneusly (namespace pollution) pulled in
through other headers, so the author didnt notice.

Signed-Off-By: John Spencer <maillist-cryptsetup@barfooze.de>
2013-02-01 08:39:12 +01:00
wagner
5b8f762ab2 sync with wiki 2013-02-01 05:35:36 +01:00
Milan Broz
72db6e4de2 Do not support user uuid for plain & loopaes devices.
This function was not documented.
So now crypt_get_uuid() returns only on-disk UUID.
2013-01-22 16:20:09 +01:00
Milan Broz
2780ccdd62 Properly cleanup on interrupt in api-test. 2013-01-16 15:28:12 +01:00
Milan Broz
fdcabdfd28 Support test run in kernel FIPS mode. 2013-01-15 14:53:19 +01:00
Milan Broz
40b876f550 Set devel version. 2013-01-14 12:49:04 +01:00
78 changed files with 9623 additions and 5217 deletions

404
FAQ
View File

@@ -64,6 +64,13 @@ A. Contributors
installers after a complete backup of all LUKS containers has been
made.
UBUNTU INSTALLER: In particular the Ubuntu installer seems to be
quite willing to kill LUKS containers in several different ways.
Those responsible at Ubuntu seem not to care very much (it is very
easy to recognize a LUKS container), so treat the process of
installing Ubuntu as a severe hazard to any LUKS container you may
have.
NO WARNING ON NON-INTERACTIVE FORMAT: If you feed cryptsetup from
STDIN (e.g. via GnuPG) on LUKS format, it does not give you the
warning that you are about to format (and e.g. will lose any
@@ -104,8 +111,11 @@ A. Contributors
This issue has been acknowledged by the Ubuntu dev team, see here:
http://launchpad.net/bugs/420080
Update 7/2012: I am unsure whether this has been fixed by now, best
be careful.
Update 4/2013: I am still unsure whether this has been fixed by
now, best be careful. They also seem to have added even more LUKS
killer functionality to the Ubuntu installer. I can only strongly
recommended to not install Ubuntu on a system with existing LUKS
containers without complete backups.
* 1.4 My LUKS-device is broken! Help!
@@ -136,13 +146,17 @@ A. Contributors
* 1.5 Who wrote this?
Current FAQ maintainer is Arno Wagner <arno@wagner.name>. Other
contributors are listed at the end. If you want to contribute, send
your article, including a descriptive headline, to the maintainer,
or the dm-crypt mailing list with something like "FAQ ..." in the
subject. You can also send more raw information and have me write
the section. Please note that by contributing to this FAQ, you
accept the license described below.
Current FAQ maintainer is Arno Wagner <arno@wagner.name>. If you
want to send me encrypted email, my current PGP key is DSA key
CB5D9718, fingerprint 12D6 C03B 1B30 33BB 13CF B774 E35C 5FA1 CB5D
9718.
Other contributors are listed at the end. If you want to contribute,
send your article, including a descriptive headline, to the
maintainer, or the dm-crypt mailing list with something like "FAQ
..." in the subject. You can also send more raw information and
have me write the section. Please note that by contributing to this
FAQ, you accept the license described below.
This work is under the "Attribution-Share Alike 3.0 Unported"
license, which means distribution is unlimited, you may create
@@ -157,14 +171,14 @@ A. Contributors
least problems.
* 1.5 Where is the project website?
* 1.6 Where is the project website?
There is the project website at http://code.google.com/p/cryptsetup/
Please do not post questions there, nobody will read them. Use
the mailing-list instead.
* 1.6 Is there a mailing-list?
* 1.7 Is there a mailing-list?
Instructions on how to subscribe to the mailing-list are at on the
project website. People are generally helpful and friendly on the
@@ -184,7 +198,7 @@ A. Contributors
http://dir.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt
* 1.7 Unsubscribe from the mailing-list
* 1.8 Unsubscribe from the mailing-list
Send mail to dm-crypt-unsubscribe@saout.de from the subscribed
account. You will get an email with instructions.
@@ -259,6 +273,25 @@ A. Contributors
Just follow the on-screen instructions.
Note: Passphrase iteration is determined by cryptsetup depending on
CPU power. On a slow device, this may be lower than you want. I
recently benchmarked this on a Raspberry Pi and it came out at
about 1/15 of the iteration count for a typical PC. If security is
paramount, you may want to increase the time spent in iteration, at
the cost of a slower unlock later. For the Raspberry Pi, using
cryptsetup luksFormat -i 15000 <target device>
gives you an iteration count and security level equal to an average
PC for passphrase iteration and master-key iteration. If in doubt,
check the iteration counts with
cryptsetup luksDump <target device>
and adjust the iteration count accordingly by creating the container
again with a different iteration time (the number after '-i' is the
iteration time in milicesonds) until your requirements are met.
05) Map the container. Here it will be mapped to /dev/mapper/c1:
cryptsetup luksOpen <target device> c1
@@ -289,7 +322,63 @@ A. Contributors
easy to make, but will compromise your security.
* 2.2 What is the difference between "plain" and LUKS format?
* 2.2 How do I set up encrypted swap?
As things that are confidential can end up in swap (keys,
passphrases, etc. are usually protected against being swapped to
disk, but other things may not be), it may be advisable to do
something about the issue. One option is to run without swap, which
generally works well in a desktop-context. It may cause problems
in a server-setting or under special circumstances. The solution to
that is to encrypt swap with a random key at boot-time.
NOTE: This is for Debian, and should work for Debian-derived
distributions. For others you may have to write your own startup
script or use other mechanisms.
01) Add the swap partition to /etc/crypttab. A line like the following
should do it:
swap /dev/<partition> /dev/urandom swap,noearly
Warning: While Debian refuses to overwrite partitions with a
filesystem or RAID signature on it, if your disk IDs may change
(adding or removing disks, failure of disk during boot, etc.), you
may want to take additional precautions. Yes, this means that your
kernel device names like sda, sdb, ... can change between reboots!
This is not a concern if you have only one disk. One possibility is
to make sure the partition number is not present on additional
disks or also swap there. Another is to encapsulate the swap
partition (by making it a 1-disk RAID1 or by using LVM), so that it
gets a persistent identifier. Specifying it directly by UUID does
not work, unfortunately, as the UUID is part of the swap signature
and that is not visible from the outside due to the encryption and
in addition changes on each reboot with this setup.
Note: Use /dev/random if you are paranoid or in a potential
low-entropy situation (embedded system, etc.). This may cause the
operation to take a long time during boot. If you are in a "no
entropy" situation, you cannot encrypt swap securely. In this
situation you should find some entropy, also because nothing else
using crypto will be secure, like ssh, ssl or GnuPG.
Note: The "noearly" option makes sure things like LVM, RAID, etc.
are running. As swap is non-critical for boot, it is fine to start
it late.
02) Add the swap partition to /etc/fstab. A line like the following
should do it:
/dev/mapper/swap none swap sw 0 0
That is it. Reboot or start it manually to activate encrypted swap.
Manual start would look like this:
/etc/init.d/crypdisks start
swapon /dev/mapper/swap
* 2.3 What is the difference between "plain" and LUKS format?
First, unless you happen to understand the cryptographic background
well, you should use LUKS. It does protect the user from a lot of
@@ -309,13 +398,24 @@ A. Contributors
Side-note: That has limited value against the authorities. In
civilized countries, they cannot force you to give up a crypto-key
anyways. In the US, the UK and dictatorships around the world,
they can force you to give up the keys (using imprisonment or worse
to pressure you), and in the worst case, they only need a
nebulous "suspicion" about the presence of encrypted data. My
advice is to either be ready to give up the keys or to not have
anyways. In quite a few countries around the world, they can force
you to give up the keys (using imprisonment or worse to pressure
you, sometimes without due process), and in the worst case, they
only need a nebulous "suspicion" about the presence of encrypted
data. Sometimes this applies to everybody, sometimes only when you
are suspected of having "illicit data" (definition subject to
change) and sometimes specifically when crossing a border. Note
that this is going on in countries like the US and the UK, to
different degrees and sometimes with courts restricting what the
authorities can actually demand.
My advice is to either be ready to give up the keys or to not have
encrypted data when traveling to those countries, especially when
crossing the borders.
crossing the borders. The latter also means not having any
high-entropy (random) data areas on your disk, unless you can
explain them and demonstrate that explanation. Hence doing a
zero-wipe of all free space, including unused space, may be a good
idea.
Disadvantages are that you do not have all the nice features that
the LUKS metadata offers, like multiple passphrases that can be
@@ -343,7 +443,7 @@ A. Contributors
non-default XTS mode).
* 2.3 Can I encrypt an already existing, non-empty partition to use
* 2.4 Can I encrypt an already existing, non-empty partition to use
LUKS?
There is no converter, and it is not really needed. The way to do
@@ -358,7 +458,7 @@ A. Contributors
to be in a filesystem.
* 2.4 How do I use LUKS with a loop-device?
* 2.5 How do I use LUKS with a loop-device?
This can be very handy for experiments. Setup is just the same as
with any block device. If you want, for example, to use a 100MiB
@@ -372,7 +472,7 @@ A. Contributors
To unmap the file when done, use "losetup -d /dev/loop0".
* 2.5 When I add a new key-slot to LUKS, it asks for a passphrase but
* 2.6 When I add a new key-slot to LUKS, it asks for a passphrase but
then complains about there not being a key-slot with that
passphrase?
@@ -384,7 +484,7 @@ A. Contributors
new key-slot.
* 2.6 Encryption on top of RAID or the other way round?
* 2.7 Encryption on top of RAID or the other way round?
Unless you have special needs, place encryption between RAID and
filesystem, i.e. encryption on top of RAID. You can do it the other
@@ -393,16 +493,39 @@ A. Contributors
not work anymore. Therefore it is better to encrypt the RAID
device, e.g. /dev/dm0 .
This means that the typical layering looks like this:
* 2.7 How do I read a dm-crypt key from file?
Filesystem <- top
|
Encryption
|
RAID
|
Raw partitions
|
Raw disks <- bottom
The big advantage is that you can manage the RAID container just
like any RAID container, it does not care that what is in it is
encrypted.
Note that the file will still be hashed first, just like keyboard
input. Use the --key-file option, like this:
* 2.8 How do I read a dm-crypt key from file?
Use the --key-file option, like this:
cryptsetup create --key-file keyfile e1 /dev/loop0
This will read the binary key from file, i.e. no hashing or
transformation will be applied to the keyfile before its bits are
used as key. Extra bits (beyond the length of the key) at the end
are ignored. Note that if you read from STDIN, the data will still
be hashed, just as a key read interactively from the terminal. See
the man-page sections "NOTES ON PASSPHRASE PROCESSING..." for more
detail.
* 2.8 How do I read a LUKS slot key from file?
* 2.9 How do I read a LUKS slot key from file?
What you really do here is to read a passphrase from file, just as
you would with manual entry of a passphrase for a key-slot. You can
@@ -428,7 +551,7 @@ A. Contributors
cryptsetup luksOpen --key-file keyfile /dev/loop0 e1
* 2.9 How do I read the LUKS master key from file?
* 2.10 How do I read the LUKS master key from file?
The question you should ask yourself first is why you would want to
do this. The only legitimate reason I can think of is if you want
@@ -439,7 +562,7 @@ A. Contributors
do this here.
* 2.10 What are the security requirements for a key read from file?
* 2.11 What are the security requirements for a key read from file?
A file-stored key or passphrase has the same security requirements
as one entered interactively, however you can use random bytes and
@@ -451,7 +574,7 @@ A. Contributors
head -c 256 /dev/random > keyfile
* 2.11 If I map a journaled file system using dm-crypt/LUKS, does it
* 2.12 If I map a journaled file system using dm-crypt/LUKS, does it
still provide its usual transactional guarantees?
Yes, it does, unless a very old kernel is used. The required flags
@@ -479,7 +602,7 @@ A. Contributors
should improve further and eventually the problem should go away.
* 2.12 Can I use LUKS or cryptsetup with a more secure (external)
* 2.13 Can I use LUKS or cryptsetup with a more secure (external)
medium for key storage, e.g. TPM or a smartcard?
Yes, see the answers on using a file-supplied key. You do have to
@@ -488,8 +611,12 @@ A. Contributors
own tool that in turn gets the key from the more secure key
storage.
For TPM support, you may want to have a look at tpm-luks at
https://github.com/shpedoikal/tpm-luks. Note that tpm-luks is not
related to the cryptsetup project.
* 2.13 Can I resize a dm-crypt or LUKS partition?
* 2.14 Can I resize a dm-crypt or LUKS partition?
Yes, you can, as neither dm-crypt nor LUKS stores partition size.
Whether you should is a different question. Personally I recommend
@@ -509,6 +636,59 @@ A. Contributors
for that.
* 2.15 How do I Benchmark the Ciphers, Hashes and Modes?
Since version 1.60 cryptsetup supports the "benchmark" command.
Simply run as root:
cryptsetup benchmark
It will output first iterations/second for the key-derivation
function PBKDF2 parameterized with different hash-functions, and
then the raw encryption speed of ciphers with different modes and
key-sizes. You can get more than the default benchmarks, see the
man-page for the relevant parameters. Note that XTS mode takes two
keys, hence the listed key sizes are double that for other modes
and half of it is the cipher key, the other half is the XTS key.
* 2.16 How do I Verify I have an Authentic cryptsetup Source Package?
Current maintainer is Milan Broz and he signs the release packages
with his PGP key. The key he currently uses is the "RSA key ID
D93E98FC", fingerprint 2A29 1824 3FDE 4664 8D06 86F9 D9B0 577B
D93E 98FC. While I have every confidence this really is his key and
that he is who he claims to be, don't depend on it if your life is
at stake. For that matter, if your life is at stake, don't depend
on me being who I claim to be either.
That said, as cryptsetup is under good version control, a malicious
change should be noticed sooner or later, but it may take a while.
Also, the attacker model makes compromising the sources in a
non-obvious way pretty hard. Sure, you could put the master-key
somewhere on disk, but that is rather obvious as soon as somebody
looks as there would be data in an empty LUKS container in a place
it should not be. Doing this in a more nefarious way, for example
hiding the master-key in the salts, would need a look at the
sources to be discovered, but I think that somebody would find that
sooner or later as well.
That said, this discussion is really a lot more complicated and
longer as an FAQ can sustain. If in doubt, ask on the mailing list.
* 2.17 Is there a concern with 4k Sectors?
Not from dm-crypt itself. Encryption will be done in 512B blocks,
but if the partition and filesystem are aligned correctly and the
filesystem uses multiples of 4kiB as block size, the dm-crypt layer
will just process 8 x 512B = 4096B at a time with negligible
overhead. LUKS does place data at an offset, which is 2MiB per
default and will not break alignment. See also Item 6.12 of this
FAQ for more details. Note that if your partition or filesystem is
misaligned, dm-crypt can make the effect worse though.
3. Common Problems
@@ -617,7 +797,38 @@ A. Contributors
diagnosing and (if still possible) repairing this.
* 4.2 Can a bad RAM module cause problems?
* 4.2 I cannot unlock my LUKS container! What could be the problem?
First, make sure you have a correct passphrase. Then make sure you
have the correct key-map and correct keyboard. And then make sure
you have the correct character set and encoding, see also
"PASSPHRASE CHARACTER SET" under Section 1.2.
If you are sure you are entering the passphrase right, there is the
possibility that the respective key-slot has been damaged. There
is no way to recover a damaged key-slot, except from a header
backup (see Section 6). For security reasons, there is also no
checksum in the key-slots that could tell you whether a key-slot has
been damaged. The only checksum present allows recognition of a
correct passphrase, but that only works if the passphrase is
correct and the respective key-slot is intact.
In order to find out whether a key-slot is damaged one has to look
for "non-random looking" data in it. There is a tool that
automatizes this in the cryptsetup distribution from version 1.6.0
onwards. It is located in misc/keyslot_checker/. Instructions how
to use and how to interpret results are in the README file. Note
that this tool requires a libcryptsetup from cryptsetup 1.6.0 or
later (which means libcryptsetup.so.4.5.0 or later). If the tool
complains about missing functions in libcryptsetup, you likely
have an earlier version from your distribution still installed. You
can either point the symbolic link(s) from libcryptsetup.so.4 to
the new version manually, or you can uninstall the distribution
version of cryptsetup and re-install that from cryptsetup >= 1.6.0
again to fix this.
* 4.3 Can a bad RAM module cause problems?
LUKS and dm-crypt can give the RAM quite a workout, especially when
combined with software RAID. In particular the combination RAID5 +
@@ -659,7 +870,7 @@ A. Contributors
did a verify.
* 4.3 How do I test RAM?
* 4.4 How do I test RAM?
First you should know that overclocking often makes memory
problems worse. So if you overclock (which I strongly recommend
@@ -733,8 +944,8 @@ A. Contributors
is easier than it actually is is fine. An attacker may still have
vastly higher cost than estimated here.
LUKS uses SHA1 for hasing per default. The claim in the reference is
63 billion tries/second for SHA1. We will leave aside the check
LUKS uses SHA1 for hashing per default. The claim in the reference
is 63 billion tries/second for SHA1. We will leave aside the check
whether a try actually decrypts a key-slot. Now, the machine has 25
GPUs, which I will estimate at an overall lifetime cost of USD/EUR
1000 each, and an useful lifetime of 2 years. (This is on the low
@@ -1181,7 +1392,9 @@ A. Contributors
XTS mode is potentially even more secure than cbc-essiv (but only if
cbc-essiv is insecure in your scenario). It is a NIST standard and
used, e.g. in Truecrypt. At the moment, if you want to use it, you
used, e.g. in Truecrypt. From version 1.6.0 of cryptsetup onwards,
aes-xts-plain64 is the default for LUKS. If you want to use it
with a cryptsetup before version 1.6.0 or with plain dm-crypt, you
have to specify it manually as "aes-xts-plain", i.e.
cryptsetup -c aes-xts-plain luksFormat <device>
@@ -1272,7 +1485,7 @@ A. Contributors
foot, you can figure out how to do it yourself.
* 5.19 What about SSDs or Flash Drives?
* 5.19 What about SSDs, Flash and Hybrid Drives?
The problem is that you cannot reliably erase parts of these
devices, mainly due to wear-leveling and possibly defect
@@ -1286,7 +1499,7 @@ A. Contributors
done in some fashion so that larger writes do not cause a lot of
small internal updates.
The thing is that the mappings between outside-adressable sectors
The thing is that the mappings between outside-addressable sectors
and inside sectors is arbitrary (and the vendors are not talking).
Also the discarded sectors are not necessarily erased immediately.
They may linger a long time.
@@ -1315,28 +1528,107 @@ A. Contributors
If you trust the device vendor (you probably should not...) you can
try an ATA "secure erase" command for SSDs. That does not work for
USB keys though. And if it finishes after a few seconds, it was
possibly faked by the SSD.
USB keys though and may or may not be secure for a hybrid drive. If
it finishes on an SSD after a few seconds, it was possibly faked.
Unfortunately, for hybrid drives that indicator does not work, as
the drive may well take the time to truly erase the magnetic part,
but only mark the SSD/Flash part as erased while data is still in
there.
If you can do without password management and are fine with doing
physical destruction for permenently deleting data (allways after
physical destruction for permanently deleting data (always after
one or several full overwrites!), you can use plain dm-crypt or
LUKS.
If you want or need the original LUKS security features to work,
If you want or need all the original LUKS security features to work,
you can use a detached LUKS header and put that on a conventional,
magnetic disk. That leaves potentially old encrypted data in the
pools on the disk, but otherwise you get LUKS with the same
security as on a magnetic disk.
If you are concerned about your laptop being stolen, you are likely
fine using LUKS on an SSD. An attacker would need to have access
to an old passphrase (and the key-slot for this old passphrase
would actually need to still be somewhere in the SSD) for your
data to be at risk. So unless you pasted your old passphrase all
over the Internet or the attacker has knowledge of it from some
other source and does a targetted laptop theft to get at your
data, you should be fine.
fine using LUKS on an SSD or hybrid drive. An attacker would need
to have access to an old passphrase (and the key-slot for this old
passphrase would actually need to still be somewhere in the SSD)
for your data to be at risk. So unless you pasted your old
passphrase all over the Internet or the attacker has knowledge of
it from some other source and does a targeted laptop theft to get
at your data, you should be fine.
* 5.20 LUKS is broken! It uses SHA-1!
No, it is not. SHA-1 is (academically) broken for finding
collisions, but not for using it in a key-derivation function. And
that collision vulnerability is for non-iterated use only. And you
need the hash-value in verbatim.
This basically means that if you already have a slot-key, and you
have set the PBKDF2 iteration count to 1 (it is > 10'000 normally),
you could (maybe) derive a different passphrase that gives you the
the same slot-key. But if you have the slot-key, you can already
unlock the key-slot and get the master key, breaking everything. So
basically, this SHA-1 vulnerability allows you to open a LUKS
container with high effort when you already have it open.
The real problem here is people that do not understand crypto and
claim things are broken just because some mechanism is used that
has been broken for a specific different use. The way the mechanism
is used matters very much. A hash that is broken for one use can be
completely secure for other uses and here it is.
* 5.21 Why is there no "Nuke-Option"?
A "Nuke-Option" or "Kill-switch" is a password that when entered
upon unlocking instead wipes the header and all passwords. So when
somebody forces you to enter your password, you can destroy the
data instead.
While this sounds attractive at first glance, it does not make sense
once a real security analysis is done. One problem is that you have
to have some kind of HSM (Hardware Security Module) in order to
implement it securely. In the movies, a HSM starts to smoke and
melt once the Nuke-Option has been activated. In reality, it just
wipes some battery-backed RAM cells. A proper HSM costs something
like 20'000...100'000 EUR/USD and there a Nuke-Option may make some
sense. BTW, a chipcard or a TPM is not a HSM, although some
vendors are promoting that myth.
Now, a proper HSMs will have a wipe option but not a Nuke-Option,
i.e. you can explicitly wipe the HSM, but by a different process
than unlocking it takes. Why is that? Simple: If somebody can force
you to reveal passwords, then they can also do bad things to you if
you do not or if you enter a nuke password instead. Think locking
you up for a few years for "destroying evidence" or for far longer
and without trial for being a "terrorist suspect". No HSM maker
will want to expose its customers to that risk.
Now think of the typical LUKS application scenario, i.e. disk
encryption. Usually the ones forcing you to hand over your password
will have access to the disk as well, and, if they have any real
suspicion, they will mirror your disk before entering anything
supplied by you. This neatly negates any Nuke-Option. If they have
no suspicion (just harassing people that cross some border for
example), the Nuke-Option would work, but see above about likely
negative consequences and remember that a Nuke-Option may not work
reliably on SSD and hybrid drives anyways.
Hence my advice is to never take data that you do not want to reveal
into any such situation in the first place. There is no need to
transfer data on physical carriers today. The Internet makes it
quite possible to transfer data between arbitrary places and modern
encryption makes it secure. If you do it right, nobody will even be
able to identify source or destination. (How to do that is out of
scope of this document. It does require advanced skills in this age
of pervasive surveillance.)
Hence, LUKS has not kill option because it would do much more harm
than good.
Still, if you have a good use-case (i.e. non-abstract real-world
situation) where a Nuke-Option would actually be beneficial, please
let me know.
6. Backup and Data Recovery
@@ -1617,7 +1909,7 @@ http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
change the password, you basically have to create a second
encrypted device with the new passphrase and copy your data over.
On the plus side, if you accidentally overwrite any part of a
dm-crypt device, the damage will be limited to the are you
dm-crypt device, the damage will be limited to the area you
overwrote.
@@ -1889,6 +2181,16 @@ http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
not be used anymore as well. My advice would be to drop SLED 10.
* 8.3 Gcrypt after 1.5.3 breaks Whirlpool
It is the other way round: In gcrypt 1.5.3 and before Whirlpool is
broken and it was fixed in the next version. If you selected
whirlpool as hash on creation of a LUKS container, it does not work
anymore with the fixed library. Currently, the only work-around is
to decrypt with the old version. This also shows one risk of using
rarely used settings.
9. References and Further Reading

2
README
View File

@@ -18,7 +18,7 @@ MAILING LIST:
DOWNLOAD:
http://code.google.com/p/cryptsetup/downloads/
https://www.kernel.org/pub/linux/utils/cryptsetup/
SOURCE CODE:

12
TODO
View File

@@ -4,5 +4,13 @@ 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?).
- Crypt benchmark cannot ttest ECB mode.
- Log doesn't work yet in early binary start (FIPS message).
- Crypt benchmark cannot test ECB mode.
- crypto backend should initialise itself only once (debug log)
- Some crypt backends are inefective fo PBKDF2 (missing fast key reset)
Add optimisation to internal PBKDF2 (hash HMAC key in advance).
- Kernel backend doesn't allow PBKDF2 key size > 20480 bytes
(should be fixed with optimisation above).
- Add test vectors to internal PBKDF2 code.
- Add support for Nettle PBKDF2.
- Extend existing LUKS header to use another KDF? (https://password-hashing.net/)
- Fix all crazy automake warnings (or switch to Cmake).

View File

@@ -78,7 +78,7 @@ autopoint --force $AP_OPTS
libtoolize --force --copy
aclocal -I m4 $AL_OPTS
autoheader $AH_OPTS
automake --add-missing --gnu $AM_OPTS
automake --add-missing --copy --gnu $AM_OPTS
autoconf $AC_OPTS
if test x$NOCONFIGURE = x; then

View File

@@ -1,17 +1,24 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[1.6.0])
AC_INIT([cryptsetup],[1.6.4])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=9:0:5
dnl library file name for FIPS selfcheck
LIBCRYPTSETUP_VERSION_FIPS="libcryptsetup.so.4"
FIPS_MODULE_FILE="/etc/system-fips"
AC_CONFIG_SRCDIR(src/cryptsetup.c)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h:config.h.in])
AM_INIT_AUTOMAKE(dist-bzip2)
# We do not want to run test in parallel. Really.
# http://lists.gnu.org/archive/html/automake/2013-01/msg00060.html
# For old automake use this
#AM_INIT_AUTOMAKE(dist-bzip2)
AM_INIT_AUTOMAKE([dist-bzip2 1.12 serial-tests])
if test "x$prefix" = "xNONE"; then
sysconfdir=/etc
@@ -32,7 +39,7 @@ PKG_PROG_PKG_CONFIG
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
ctype.h unistd.h locale.h)
ctype.h unistd.h locale.h byteswap.h endian.h)
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
@@ -42,13 +49,18 @@ AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR([You need the uuid library.])])
AC_SUBST(UUID_LIBS, $LIBS)
LIBS=$saved_LIBS
AC_CHECK_FUNCS([posix_memalign])
AC_SEARCH_LIBS([clock_gettime],[rt posix4])
AC_CHECK_FUNCS([posix_memalign clock_gettime])
if test "x$enable_largefile" = "xno" ; then
AC_MSG_ERROR([Building with --disable-largefile is not supported, it can cause data corruption.])
fi
AC_C_CONST
AC_C_BIGENDIAN
AC_TYPE_OFF_T
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
AC_PROG_GCC_TRADITIONAL
dnl ==========================================================================
@@ -74,6 +86,8 @@ 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.])
@@ -118,8 +132,12 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
fi
dnl Check if we can use gcrypt PBKDF2 (1.6.0 supports empty password)
AC_ARG_ENABLE([gcrypt-pbkdf2], AS_HELP_STRING([--enable-gcrypt-pbkdf2],[force enable internal gcrypt PBKDF2]),
[use_internal_pbkdf2=0],
[AM_PATH_LIBGCRYPT([1.6.0], [use_internal_pbkdf2=0], [use_internal_pbkdf2=1])])
if test "x$enableval" = "xyes"; then
[use_internal_pbkdf2=0]
else
[use_internal_pbkdf2=1]
fi,
[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.])])
if test x$enable_static_cryptsetup = xyes; then
@@ -149,8 +167,8 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
if test x$enable_static_cryptsetup = xyes; then
saved_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES([OPENSSL], [openssl])
CRYPTO_STATIC_LIBS=$OPENSSL_LIBS
PKG_CHECK_MODULES([OPENSSL_STATIC], [openssl])
CRYPTO_STATIC_LIBS=$OPENSSL_STATIC_LIBS
PKG_CONFIG=$saved_PKG_CONFIG
fi
NO_FIPS([])
@@ -337,6 +355,7 @@ 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],

32
docs/v1.6.1-ReleaseNotes Normal file
View File

@@ -0,0 +1,32 @@
Cryptsetup 1.6.1 Release Notes
==============================
Changes since version 1.6.0
* Fix loop-AES keyfile parsing.
Loop-AES keyfile should be text keyfile, reject keyfiles which
are not properly terminated.
* Fix passphrase pool overflow for too long TCRYPT passphrase.
(Maximal TCRYPT passphrase length is 64 characters.)
* Return EPERM (translated to exit code 2) for too long TCRYPT passphrase.
* Fix deactivation of device when failed underlying node disappeared.
* Fix API deactivate call for TCRYPT format and NULL context parameter.
* Improve keyslot checker example documentation.
* Report error message if deactivation fails and device is still busy.
* Make passphrase prompts more consistent (and remove "LUKS" form prompt).
* Fix some missing headers (compilation failed with alternative libc).
* Remove not functional API UUID support for plain & loopaes devices.
(not persistent activation UUID).
* Properly cleanup devices on interrupt in api-test.
* Support all tests run if kernel is in FIPS mode.

25
docs/v1.6.2-ReleaseNotes Normal file
View File

@@ -0,0 +1,25 @@
Cryptsetup 1.6.2 Release Notes
==============================
Changes since version 1.6.1
* Print error and fail if more device arguments are present for isLuks command.
* Fix cipher specification string parsing (found by gcc -fsanitize=address option).
* Try to map TCRYPT system encryption through partition
(allows to activate mapping when other partition on the same device is mounted).
* Print a warning if system encryption is used and device is a partition.
(TCRYPT system encryption uses whole device argument.)
* Disallow explicit small payload offset for LUKS detached header.
LUKS detached header only allows data payload 0 (whole data device is used)
or explicit offset larger than header + keyslots size.
* Fix boundary condition for verity device that caused failure for certain device sizes.
* Various fixes to documentation, including update FAQ, default modes
and TCRYPT description.
* Workaround for some recent changes in automake (serial-tests).

50
docs/v1.6.3-ReleaseNotes Normal file
View File

@@ -0,0 +1,50 @@
Cryptsetup 1.6.3 Release Notes
==============================
Changes since version 1.6.2
* Fix cryptsetup reencryption tool to work properly
with devices using 4kB sectors.
* Always use page size if running through loop device,
this fixes failures for external LUKS header and
filesystem requiring 4kB block size.
* Fix TCRYPT system encryption mapping for multiple partitions.
Since this commit, one can use partition directly as device parameter.
If you need to activate such partition from image in file,
please first use map partitioned loop device (losetup -P)
on image.
(Cryptsetup require partition offsets visible in kernel sysfs
in this mode.)
* Support activation of old TrueCrypt containers using CBC mode
and whitening (created in TrueCrypt version < 4.1).
This requires Linux kernel 3.13 or later.
(Containers with cascade CBC ciphers are not supported.)
* Properly display keys in dump --dump-master-key command
for TrueCrypt CBC containers.
* Rewrite cipher benchmark loop which was unreliable
on very fast machines.
* Add warning if LUKS device was activated using non-cryptsetup
library which did not set UUID properly (e.g. cryptmount).
(Some commands, like luksSuspend, are not available then.)
* Support length limitation also for plain (no hash) length.
This can be used for mapping problematic cryptosystems which
wipes some key (losetup sometimes set last 32 byte to zero,
which can be now configured as --hash plain:31 parameter).
* Fix hash limit if parameter is not a number.
(The whole key was set to zero instead of command failure.)
* Unify --key-slot behavior in cryptsetup_reencrypt tool.
* Update dracut example scripts for system reencryption on first boot.
* Add command line option --tcrypt-backup to access TCRYPT backup header.
* Fix static compilation with OpenSSL.

57
docs/v1.6.4-ReleaseNotes Normal file
View File

@@ -0,0 +1,57 @@
Cryptsetup 1.6.4 Release Notes
==============================
Changes since version 1.6.3
* Implement new erase (with alias luksErase) command.
The erase cryptsetup command can be used to permanently erase
all keyslots and make the LUKS container inaccessible.
(The only way to unlock such device is to use LUKS header backup
created before erase command was used.)
You do not need to provide any password for this operation.
This operation is irreversible.
* Add internal "whirlpool_gcryptbug hash" for accessing flawed
Whirlpool hash in gcrypt (requires gcrypt 1.6.1 or above).
The gcrypt version of Whirlpool hash algorithm was flawed in some
situations.
This means that if you used Whirlpool in LUKS header and upgraded
to new gcrypt library your LUKS container become inaccessible.
Please refer to cryptsetup FAQ for detail how to fix this situation.
* Allow to use --disable-gcrypt-pbkdf2 during configuration
to force use internal PBKDF2 code.
* Require gcrypt 1.6.1 for imported implementation of PBKDF2
(PBKDF2 in gcrypt 1.6.0 is too slow).
* Add --keep-key to cryptsetup-reencrypt.
This allows change of LUKS header hash (and iteration count) without
the need to reencrypt the whole data area.
(Reencryption of LUKS header only without master key change.)
* By default verify new passphrase in luksChangeKey and luksAddKey
commands (if input is from terminal).
* Fix memory leak in Nettle crypto backend.
* Support --tries option even for TCRYPT devices in cryptsetup.
* Support --allow-discards option even for TCRYPT devices.
(Note that this could destroy hidden volume and it is not suggested
by original TrueCrypt security model.)
* Link against -lrt for clock_gettime to fix undefined reference
to clock_gettime error (introduced in 1.6.2).
* Fix misleading error message when some algorithms are not available.
* Count system time in PBKDF2 benchmark if kernel returns no self usage info.
(Workaround to broken getrusage() syscall with some hypervisors.)

View File

@@ -5,7 +5,7 @@ moduledir = $(libdir)/cryptsetup
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libcryptsetup.pc
AM_CPPFLAGS = \
AM_CPPFLAGS = -include config.h \
-I$(top_srcdir) \
-I$(top_srcdir)/lib/crypto_backend \
-I$(top_srcdir)/lib/luks1 \
@@ -16,10 +16,7 @@ AM_CPPFLAGS = \
-DLIBDIR=\""$(libdir)"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DVERSION=\""$(VERSION)"\" \
-D_GNU_SOURCE \
-D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64
-DVERSION=\""$(VERSION)"\"
lib_LTLIBRARIES = libcryptsetup.la
@@ -32,11 +29,11 @@ common_ldadd = \
libcryptsetup_la_DEPENDENCIES = $(common_ldadd) libcryptsetup.sym
libcryptsetup_la_LDFLAGS = \
libcryptsetup_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
-Wl,--version-script=$(top_srcdir)/lib/libcryptsetup.sym \
-version-info @LIBCRYPTSETUP_VERSION_INFO@
libcryptsetup_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
libcryptsetup_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
libcryptsetup_la_LIBADD = \
@UUID_LIBS@ \

View File

@@ -21,7 +21,7 @@
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "libcryptsetup.h"
@@ -83,7 +83,11 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
/* hash[:hash_length] */
if ((s = strchr(hash_name_buf, ':'))) {
*s = '\0';
hash_size = atoi(++s);
s++;
if (!*s || sscanf(s, "%zd", &hash_size) != 1) {
log_dbg("Hash length is not a number");
return -EINVAL;
}
if (hash_size > key_size) {
log_dbg("Hash length %zd > key length %zd",
hash_size, key_size);
@@ -95,7 +99,16 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
pad_size = 0;
}
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
/* No hash, copy passphrase directly */
if (!strcmp(hash_name_buf, "plain")) {
if (passphrase_size < hash_size) {
log_dbg("Too short plain passphrase.");
return -EINVAL;
}
memcpy(key, passphrase, hash_size);
r = 0;
} else
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
if (r == 0 && pad_size)
memset(key + hash_size, 0, pad_size);

View File

@@ -2,7 +2,7 @@ moduledir = $(libdir)/cryptsetup
noinst_LTLIBRARIES = libcrypto_backend.la
libcrypto_backend_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
libcrypto_backend_la_CFLAGS = $(AM_CFLAGS) -Wall @CRYPTO_CFLAGS@
libcrypto_backend_la_SOURCES = crypto_backend.h \
crypto_cipher_kernel.c pbkdf_check.c crc32.c
@@ -27,4 +27,4 @@ if CRYPTO_INTERNAL_PBKDF2
libcrypto_backend_la_SOURCES += pbkdf2_generic.c
endif
AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/lib
AM_CPPFLAGS = -include config.h -I$(top_srcdir)/lib

View File

@@ -23,7 +23,6 @@
#include <stdint.h>
#include <string.h>
#include "config.h"
struct crypt_device;
struct crypt_hash;

View File

@@ -28,6 +28,7 @@
static int crypto_backend_initialised = 0;
static int crypto_backend_secmem = 1;
static int crypto_backend_whirlpool_bug = -1;
static char version[64];
struct crypt_hash {
@@ -42,6 +43,44 @@ struct crypt_hmac {
int hash_len;
};
/*
* Test for wrong Whirlpool variant,
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
*/
static void crypt_hash_test_whirlpool_bug(void)
{
struct crypt_hash *h;
char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
int r;
if (crypto_backend_whirlpool_bug >= 0)
return;
crypto_backend_whirlpool_bug = 0;
if (crypt_hash_init(&h, "whirlpool"))
return;
/* One shot */
if ((r = crypt_hash_write(h, &buf[0], 2)) ||
(r = crypt_hash_final(h, hash_out1, 64))) {
crypt_hash_destroy(h);
return;
}
/* Split buf (crypt_hash_final resets hash state) */
if ((r = crypt_hash_write(h, &buf[0], 1)) ||
(r = crypt_hash_write(h, &buf[1], 1)) ||
(r = crypt_hash_final(h, hash_out2, 64))) {
crypt_hash_destroy(h);
return;
}
crypt_hash_destroy(h);
if (memcmp(hash_out1, hash_out2, 64))
crypto_backend_whirlpool_bug = 1;
}
int crypt_backend_init(struct crypt_device *ctx)
{
if (crypto_backend_initialised)
@@ -70,10 +109,15 @@ int crypt_backend_init(struct crypt_device *ctx)
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
}
snprintf(version, 64, "gcrypt %s%s",
gcry_check_version(NULL),
crypto_backend_secmem ? "" : ", secmem disabled");
crypto_backend_initialised = 1;
crypt_hash_test_whirlpool_bug();
snprintf(version, 64, "gcrypt %s%s%s",
gcry_check_version(NULL),
crypto_backend_secmem ? "" : ", secmem disabled",
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : ""
);
return 0;
}
@@ -87,6 +131,23 @@ uint32_t crypt_backend_flags(void)
return 0;
}
static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
{
const char *hash_name = name;
/* "whirlpool_gcryptbug" is out shortcut to flawed whirlpool
* in libgcrypt < 1.6.0 */
if (name && !strcasecmp(name, "whirlpool_gcryptbug")) {
#if GCRYPT_VERSION_NUMBER >= 0x010601
if (flags)
*flags |= GCRY_MD_FLAG_BUGEMU1;
#endif
hash_name = "whirlpool";
}
return hash_name;
}
/* HASH */
int crypt_hash_size(const char *name)
{
@@ -94,7 +155,7 @@ int crypt_hash_size(const char *name)
assert(crypto_backend_initialised);
hash_id = gcry_md_map_name(name);
hash_id = gcry_md_map_name(crypt_hash_compat_name(name, NULL));
if (!hash_id)
return -EINVAL;
@@ -104,6 +165,7 @@ int crypt_hash_size(const char *name)
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
{
struct crypt_hash *h;
unsigned int flags = 0;
assert(crypto_backend_initialised);
@@ -111,13 +173,13 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
if (!h)
return -ENOMEM;
h->hash_id = gcry_md_map_name(name);
h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
if (!h->hash_id) {
free(h);
return -EINVAL;
}
if (gcry_md_open(&h->hd, h->hash_id, 0)) {
if (gcry_md_open(&h->hd, h->hash_id, flags)) {
free(h);
return -EINVAL;
}
@@ -173,6 +235,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
const void *buffer, size_t length)
{
struct crypt_hmac *h;
unsigned int flags = GCRY_MD_FLAG_HMAC;
assert(crypto_backend_initialised);
@@ -180,13 +243,13 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
if (!h)
return -ENOMEM;
h->hash_id = gcry_md_map_name(name);
h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
if (!h->hash_id) {
free(h);
return -EINVAL;
}
if (gcry_md_open(&h->hd, h->hash_id, GCRY_MD_FLAG_HMAC)) {
if (gcry_md_open(&h->hd, h->hash_id, flags)) {
free(h);
return -EINVAL;
}
@@ -261,15 +324,17 @@ int crypt_pbkdf(const char *kdf, const char *hash,
char *key, size_t key_length,
unsigned int iterations)
{
const char *hash_name = crypt_hash_compat_name(hash, NULL);
#if USE_INTERNAL_PBKDF2
if (!kdf || strncmp(kdf, "pbkdf2", 6))
return -EINVAL;
return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
return pkcs5_pbkdf2(hash_name, password, password_length, salt, salt_length,
iterations, key_length, key);
#else /* USE_INTERNAL_PBKDF2 */
int hash_id = gcry_md_map_name(hash);
int hash_id = gcry_md_map_name(hash_name);
int kdf_id;
if (!hash_id)

View File

@@ -265,8 +265,8 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
int crypt_hmac_destroy(struct crypt_hmac *ctx)
{
memset(ctx->key, 0, ctx->key_length);
memset(ctx, 0, sizeof(*ctx));
free(ctx->key);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
return 0;
}

View File

@@ -25,12 +25,24 @@
static long time_ms(struct rusage *start, struct rusage *end)
{
int count_kernel_time = 0;
long ms;
if (crypt_backend_flags() & CRYPT_BACKEND_KERNEL)
count_kernel_time = 1;
/*
* FIXME: if there is no self usage info, count system time.
* This seem like getrusage() bug in some hypervisors...
*/
if (!end->ru_utime.tv_sec && !start->ru_utime.tv_sec &&
!end->ru_utime.tv_usec && !start->ru_utime.tv_usec)
count_kernel_time = 1;
ms = (end->ru_utime.tv_sec - start->ru_utime.tv_sec) * 1000;
ms += (end->ru_utime.tv_usec - start->ru_utime.tv_usec) / 1000;
if (crypt_backend_flags() & CRYPT_BACKEND_KERNEL) {
if (count_kernel_time) {
ms += (end->ru_stime.tv_sec - start->ru_stime.tv_sec) * 1000;
ms += (end->ru_stime.tv_usec - start->ru_stime.tv_usec) / 1000;
}

View File

@@ -24,10 +24,6 @@
#ifndef INTERNAL_H
#define INTERNAL_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
@@ -96,7 +92,11 @@ struct device *crypt_data_device(struct crypt_device *cd);
int crypt_confirm(struct crypt_device *cd, const char *msg);
char *crypt_lookup_dev(const char *dev_id);
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
int crypt_dev_is_rotational(int major, int minor);
int crypt_dev_is_partition(const char *dev_path);
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size);
char *crypt_get_base_device(const char *dev_path);
uint64_t crypt_dev_partition_offset(const char *dev_path);
ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count);
ssize_t read_blockwise(int fd, int bsize, void *_buf, size_t count);

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004, Christophe Saout <christophe@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-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -393,7 +393,7 @@ struct crypt_params_verity {
*/
struct crypt_params_tcrypt {
const char *passphrase; /**< passphrase to unlock header (input only) */
size_t passphrase_size; /**< passphrase size (input only) */
size_t passphrase_size; /**< passphrase size (input only, max length is 64) */
const char **keyfiles; /**< keyfile paths to unlock header (input only) */
unsigned int keyfiles_count;/**< keyfiles count (input only) */
const char *hash_name; /**< hash function for PBKDF */
@@ -1019,6 +1019,9 @@ int crypt_get_verity_info(struct crypt_device *cd,
* @param decryption_mbs measured decryption speed in MiB/s
*
* @return @e 0 on success or negative errno value otherwise.
*
* @note If encryption_buffer_size is too small and encryption time
* cannot be properly measured, -ERANGE is returned.
*/
int crypt_benchmark(struct crypt_device *cd,
const char *cipher,

View File

@@ -28,6 +28,7 @@
#include <fcntl.h>
#include <linux/fs.h>
#include <uuid/uuid.h>
#include <sys/utsname.h>
#include "internal.h"
@@ -99,6 +100,18 @@ static void set_dm_error(int level,
static int _dm_simple(int task, const char *name, int udev_wait);
static int _dm_satisfies_version(unsigned target_maj, unsigned target_min,
unsigned actual_maj, unsigned actual_min)
{
if (actual_maj > target_maj)
return 1;
if (actual_maj == target_maj && actual_min >= target_min)
return 1;
return 0;
}
static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
unsigned crypt_min, unsigned crypt_patch)
{
@@ -110,24 +123,27 @@ static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
log_dbg("Detected dm-crypt version %i.%i.%i, dm-ioctl version %u.%u.%u.",
crypt_maj, crypt_min, crypt_patch, dm_maj, dm_min, dm_patch);
if (crypt_maj >= 1 && crypt_min >= 2)
if (_dm_satisfies_version(1, 2, crypt_maj, crypt_min))
_dm_crypt_flags |= DM_KEY_WIPE_SUPPORTED;
else
log_dbg("Suspend and resume disabled, no wipe key support.");
if (crypt_maj >= 1 && crypt_min >= 10)
if (_dm_satisfies_version(1, 10, crypt_maj, crypt_min))
_dm_crypt_flags |= DM_LMK_SUPPORTED;
if (dm_maj >= 4 && dm_min >= 20)
if (_dm_satisfies_version(4, 20, dm_maj, dm_min))
_dm_crypt_flags |= DM_SECURE_SUPPORTED;
/* not perfect, 2.6.33 supports with 1.7.0 */
if (crypt_maj >= 1 && crypt_min >= 8)
if (_dm_satisfies_version(1, 8, crypt_maj, crypt_min))
_dm_crypt_flags |= DM_PLAIN64_SUPPORTED;
if (crypt_maj >= 1 && crypt_min >= 11)
if (_dm_satisfies_version(1, 11, crypt_maj, crypt_min))
_dm_crypt_flags |= DM_DISCARDS_SUPPORTED;
if (_dm_satisfies_version(1, 13, crypt_maj, crypt_min))
_dm_crypt_flags |= DM_TCW_SUPPORTED;
/* Repeat test if dm-crypt is not present */
if (crypt_maj > 0)
_dm_crypt_checked = 1;
@@ -143,6 +159,16 @@ 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;
@@ -153,6 +179,8 @@ static int _dm_check_versions(void)
if (_dm_crypt_checked)
return 1;
_dm_kernel_info();
/* Shut up DM while checking */
_quiet_log = 1;
@@ -493,14 +521,19 @@ int dm_remove_device(struct crypt_device *cd, const char *name,
* CRYPT-LUKS1-00000000000000000000000000000000-name
* CRYPT-TEMP-name
*/
static void dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen)
static int dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen)
{
char *ptr, uuid2[UUID_LEN] = {0};
uuid_t uu;
unsigned i = 0;
/* Remove '-' chars */
if (uuid && !uuid_parse(uuid, uu)) {
if (uuid) {
if (uuid_parse(uuid, uu) < 0) {
log_dbg("Requested UUID %s has invalid format.", uuid);
return 0;
}
for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
if (uuid[i] != '-') {
*ptr = uuid[i];
@@ -516,6 +549,8 @@ static void dm_prepare_uuid(const char *name, const char *type, const char *uuid
log_dbg("DM-UUID is %s", buf);
if (i >= buflen)
log_err(NULL, _("DM-UUID for device %s was truncated.\n"), name);
return 1;
}
static int _dm_create_device(const char *name, const char *type,
@@ -542,7 +577,8 @@ static int _dm_create_device(const char *name, const char *type,
if (!dm_task_set_name(dmt, name))
goto out_no_removal;
} else {
dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
if (!dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid)))
goto out_no_removal;
if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
goto out_no_removal;

View File

@@ -2,15 +2,13 @@ moduledir = $(libdir)/cryptsetup
noinst_LTLIBRARIES = libloopaes.la
libloopaes_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
libloopaes_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
libloopaes_la_SOURCES = \
loopaes.c \
loopaes.h
AM_CPPFLAGS = -D_GNU_SOURCE \
-D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64 \
AM_CPPFLAGS = -include config.h \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/lib/crypto_backend

View File

@@ -2,7 +2,7 @@
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2012, Milan Broz
* Copyright (C) 2011-2013, Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -75,16 +75,16 @@ static int hash_keys(struct crypt_device *cd,
const char *hash_override,
const char **input_keys,
unsigned int keys_count,
unsigned int key_len_output)
unsigned int key_len_output,
unsigned int key_len_input)
{
const char *hash_name;
char tweak, *key_ptr;
unsigned i, key_len_input;
unsigned int i;
int r;
hash_name = hash_override ?: get_hash(key_len_output);
tweak = get_tweak(keys_count);
key_len_input = strlen(input_keys[0]);
if (!keys_count || !key_len_output || !hash_name || !key_len_input) {
log_err(cd, _("Key processing error (using hash %s).\n"),
@@ -134,7 +134,8 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
size_t buffer_len)
{
const char *keys[LOOPAES_KEYS_MAX];
unsigned i, key_index, key_len, offset;
unsigned int key_lengths[LOOPAES_KEYS_MAX];
unsigned int i, key_index, key_len, offset;
log_dbg("Parsing loop-AES keyfile of size %d.", buffer_len);
@@ -154,33 +155,45 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
offset = 0;
key_index = 0;
key_lengths[0] = 0;
while (offset < buffer_len && key_index < LOOPAES_KEYS_MAX) {
keys[key_index++] = &buffer[offset];
while (offset < buffer_len && buffer[offset])
keys[key_index] = &buffer[offset];
key_lengths[key_index] = 0;;
while (offset < buffer_len && buffer[offset]) {
offset++;
key_lengths[key_index]++;
}
if (offset == buffer_len) {
log_dbg("Unterminated key #%d in keyfile.", key_index);
log_err(cd, _("Incompatible loop-AES keyfile detected.\n"));
return -EINVAL;
}
while (offset < buffer_len && !buffer[offset])
offset++;
key_index++;
}
/* All keys must be the same length */
key_len = key_index ? strlen(keys[0]) : 0;
key_len = key_lengths[0];
for (i = 0; i < key_index; i++)
if (key_len != strlen(keys[i])) {
if (!key_lengths[i] || (key_lengths[i] != key_len)) {
log_dbg("Unexpected length %d of key #%d (should be %d).",
strlen(keys[i]), i, key_len);
key_lengths[i], i, key_len);
key_len = 0;
break;
}
log_dbg("Keyfile: %d keys of length %d.", key_index, key_len);
if (offset != buffer_len || key_len == 0 ||
(key_index != 1 && key_index !=64 && key_index != 65)) {
log_err(cd, _("Incompatible loop-AES keyfile detected.\n"));
return -EINVAL;
}
log_dbg("Keyfile: %d keys of length %d.", key_index, key_len);
*keys_count = key_index;
return hash_keys(cd, vk, hash, keys, key_index, crypt_get_volume_key_size(cd));
return hash_keys(cd, vk, hash, keys, key_index,
crypt_get_volume_key_size(cd), key_len);
}
int LOOPAES_activate(struct crypt_device *cd,
@@ -195,7 +208,6 @@ int LOOPAES_activate(struct crypt_device *cd,
int r;
struct crypt_dm_active_device dmd = {
.target = DM_CRYPT,
.uuid = crypt_get_uuid(cd),
.size = 0,
.flags = flags,
.data_device = crypt_data_device(cd),

View File

@@ -2,7 +2,7 @@
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2012, Milan Broz
* Copyright (C) 2011-2013, Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#define _LOOPAES_H
#include <unistd.h>
#include "config.h"
struct crypt_device;
struct volume_key;

View File

@@ -2,7 +2,7 @@ moduledir = $(libdir)/cryptsetup
noinst_LTLIBRARIES = libluks1.la
libluks1_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
libluks1_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
libluks1_la_SOURCES = \
af.c \
@@ -11,9 +11,7 @@ libluks1_la_SOURCES = \
af.h \
luks.h
AM_CPPFLAGS = -D_GNU_SOURCE \
-D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64 \
AM_CPPFLAGS = -include config.h \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/lib/crypto_backend

View File

@@ -3,6 +3,7 @@
*
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2013, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -153,6 +154,7 @@ int LUKS_hdr_backup(
{
struct device *device = crypt_metadata_device(ctx);
int r = 0, devfd = -1;
ssize_t hdr_size;
ssize_t buffer_size;
char *buffer = NULL;
@@ -160,15 +162,19 @@ int LUKS_hdr_backup(
if (r)
return r;
buffer_size = LUKS_device_sectors(hdr->keyBytes) << SECTOR_SHIFT;
hdr_size = LUKS_device_sectors(hdr->keyBytes) << SECTOR_SHIFT;
buffer_size = size_round_up(hdr_size, crypt_getpagesize());
buffer = crypt_safe_alloc(buffer_size);
if (!buffer || buffer_size < LUKS_ALIGN_KEYSLOTS) {
if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) {
r = -ENOMEM;
goto out;
}
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes).",
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS);
sizeof(*hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
log_dbg("Output backup file size: %u bytes.", buffer_size);
devfd = device_open(device, O_RDONLY);
if(devfd == -1) {
@@ -177,7 +183,7 @@ int LUKS_hdr_backup(
goto out;
}
if (read_blockwise(devfd, device_block_size(device), buffer, buffer_size) < buffer_size) {
if (read_blockwise(devfd, device_block_size(device), buffer, hdr_size) < hdr_size) {
r = -EIO;
goto out;
}
@@ -594,6 +600,28 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
return r;
}
/* Check that kernel supports requested cipher by decryption of one sector */
static int LUKS_check_cipher(struct luks_phdr *hdr, struct crypt_device *ctx)
{
int r;
struct volume_key *empty_key;
char buf[SECTOR_SIZE];
log_dbg("Checking if cipher %s-%s is usable.", hdr->cipherName, hdr->cipherMode);
empty_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!empty_key)
return -ENOMEM;
r = LUKS_decrypt_from_storage(buf, sizeof(buf),
hdr->cipherName, hdr->cipherMode,
empty_key, 0, ctx);
crypt_free_volume_key(empty_key);
memset(buf, 0, sizeof(buf));
return r;
}
int LUKS_generate_phdr(struct luks_phdr *header,
const struct volume_key *vk,
const char *cipherName, const char *cipherMode, const char *hashSpec,
@@ -605,7 +633,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
int detached_metadata_device,
struct crypt_device *ctx)
{
unsigned int i=0;
unsigned int i = 0, hdr_sectors = LUKS_device_sectors(vk->keylength);
size_t blocksPerStripeSet, currentSector;
int r;
uuid_t partitionUuid;
@@ -615,6 +643,13 @@ int LUKS_generate_phdr(struct luks_phdr *header,
if (alignPayload == 0 && !detached_metadata_device)
alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE;
if (alignPayload && detached_metadata_device && alignPayload < hdr_sectors) {
log_err(ctx, _("Data offset for detached LUKS header must be "
"either 0 or higher than header size (%d sectors).\n"),
hdr_sectors);
return -EINVAL;
}
if (crypt_hmac_size(hashSpec) < LUKS_DIGESTSIZE) {
log_err(ctx, _("Requested LUKS hash %s is not supported.\n"), hashSpec);
return -EINVAL;
@@ -640,6 +675,10 @@ int LUKS_generate_phdr(struct luks_phdr *header,
LUKS_fix_header_compatible(header);
r = LUKS_check_cipher(header, ctx);
if (r < 0)
return r;
log_dbg("Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes",
header->version, header->hashSpec ,header->cipherName, header->cipherMode,
header->keyBytes);

View File

@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <sys/select.h>
#include "libcryptsetup.h"
#include "internal.h"

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004, Christophe Saout <christophe@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-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -60,14 +60,12 @@ struct crypt_device {
struct crypt_params_plain hdr;
char *cipher;
char *cipher_mode;
char *uuid;
unsigned int key_size;
} plain;
struct { /* used in CRYPT_LOOPAES */
struct crypt_params_loopaes hdr;
char *cipher;
char *cipher_mode;
char *uuid;
unsigned int key_size;
} loopaes;
struct { /* used in CRYPT_VERITY */
@@ -185,8 +183,6 @@ int init_crypto(struct crypt_device *ctx)
{
int r;
crypt_fips_libcryptsetup_check(ctx);
r = crypt_random_init(ctx);
if (r < 0) {
log_err(ctx, _("Cannot initialize crypto RNG backend.\n"));
@@ -261,6 +257,23 @@ static int isTCRYPT(const char *type)
return (type && !strcmp(CRYPT_TCRYPT, type));
}
static int onlyLUKS(struct crypt_device *cd)
{
int r = 0;
if (cd && !cd->type) {
log_err(cd, _("Cannot determine device type. Incompatible activation of device?\n"));
r = -EINVAL;
}
if (!cd || !isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
r = -EINVAL;
}
return r;
}
/* keyslot helpers */
static int keyslot_verify_or_find_empty(struct crypt_device *cd, int *keyslot)
{
@@ -329,7 +342,6 @@ int PLAIN_activate(struct crypt_device *cd,
enum devcheck device_check;
struct crypt_dm_active_device dmd = {
.target = DM_CRYPT,
.uuid = crypt_get_uuid(cd),
.size = size,
.flags = flags,
.data_device = crypt_data_device(cd),
@@ -364,10 +376,6 @@ int PLAIN_activate(struct crypt_device *cd,
r = dm_create_device(cd, name, CRYPT_PLAIN, &dmd, 0);
// FIXME
if (!cd->u.plain.uuid && dm_query_device(cd, name, DM_ACTIVE_UUID, &dmd) >= 0)
cd->u.plain.uuid = CONST_CAST(char*)dmd.uuid;
free(dm_cipher);
return r;
}
@@ -713,9 +721,10 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
DM_ACTIVE_CRYPT_KEYSIZE, &dmd);
if (r < 0)
goto out;
if (r > 0)
r = 0;
if (isPLAIN(cd->type)) {
cd->u.plain.uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
cd->u.plain.hdr.hash = NULL; /* no way to get this */
cd->u.plain.hdr.offset = dmd.u.crypt.offset;
cd->u.plain.hdr.skip = dmd.u.crypt.iv_offset;
@@ -727,7 +736,6 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
cd->u.plain.cipher_mode = strdup(cipher_mode);
}
} else if (isLOOPAES(cd->type)) {
cd->u.loopaes.uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
cd->u.loopaes.hdr.offset = dmd.u.crypt.offset;
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher,
@@ -758,8 +766,12 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
free(cd->type);
cd->type = NULL;
r = 0;
goto out;
}
} else {
log_dbg("LUKS device header not available.");
free(cd->type);
cd->type = NULL;
r = 0;
}
} else if (isTCRYPT(cd->type)) {
r = TCRYPT_init_by_name(cd, name, &dmd, &cd->device,
@@ -784,14 +796,15 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
r = dm_query_device(cd, name,
DM_ACTIVE_DEVICE |
DM_ACTIVE_UUID |
DM_ACTIVE_VERITY_HASH_DEVICE |
DM_ACTIVE_VERITY_PARAMS, &dmd);
if (r < 0)
goto out;
if (r > 0)
r = 0;
if (isVERITY(cd->type)) {
cd->u.verity.uuid = dmd.uuid ? strdup(dmd.uuid) : NULL;
cd->u.verity.uuid = NULL; // FIXME
cd->u.verity.hdr.flags = CRYPT_VERITY_NO_HEADER; //FIXME
cd->u.verity.hdr.data_size = params.data_size;
cd->u.verity.root_hash_size = dmd.u.verity.root_hash_size;
@@ -810,7 +823,6 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
}
out:
device_free(dmd.data_device);
free(CONST_CAST(void*)dmd.uuid);
return r;
}
@@ -920,6 +932,11 @@ static int _crypt_format_plain(struct crypt_device *cd,
return -EINVAL;
}
if (uuid) {
log_err(cd, _("UUID is not supported for this crypt type.\n"));
return -EINVAL;
}
if (!(cd->type = strdup(CRYPT_PLAIN)))
return -ENOMEM;
@@ -931,8 +948,6 @@ static int _crypt_format_plain(struct crypt_device *cd,
cd->u.plain.cipher = strdup(cipher);
cd->u.plain.cipher_mode = strdup(cipher_mode);
if (uuid)
cd->u.plain.uuid = strdup(uuid);
if (params && params->hash)
cd->u.plain.hdr.hash = strdup(params->hash);
@@ -1042,6 +1057,11 @@ static int _crypt_format_loopaes(struct crypt_device *cd,
return -EINVAL;
}
if (uuid) {
log_err(cd, _("UUID is not supported for this crypt type.\n"));
return -EINVAL;
}
if (!(cd->type = strdup(CRYPT_LOOPAES)))
return -ENOMEM;
@@ -1049,9 +1069,6 @@ static int _crypt_format_loopaes(struct crypt_device *cd,
cd->u.loopaes.cipher = strdup(cipher ?: DEFAULT_LOOPAES_CIPHER);
if (uuid)
cd->u.loopaes.uuid = strdup(uuid);
if (params && params->hash)
cd->u.loopaes.hdr.hash = strdup(params->hash);
@@ -1288,7 +1305,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
int r;
/* Device context type must be initialised */
if (!cd->type || !crypt_get_uuid(cd))
if (!cd->type)
return -EINVAL;
log_dbg("Resizing device %s to %" PRIu64 " sectors.", name, new_size);
@@ -1413,11 +1430,9 @@ void crypt_free(struct crypt_device *cd)
free(CONST_CAST(void*)cd->u.plain.hdr.hash);
free(cd->u.plain.cipher);
free(cd->u.plain.cipher_mode);
free(cd->u.plain.uuid);
} else if (isLOOPAES(cd->type)) {
free(CONST_CAST(void*)cd->u.loopaes.hdr.hash);
free(cd->u.loopaes.cipher);
free(cd->u.loopaes.uuid);
} else if (isVERITY(cd->type)) {
free(CONST_CAST(void*)cd->u.verity.hdr.hash_name);
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
@@ -1440,11 +1455,9 @@ int crypt_suspend(struct crypt_device *cd,
log_dbg("Suspending volume %s.", name);
if (!cd || !isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
r = -EINVAL;
goto out;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
ci = crypt_status(NULL, name);
if (ci < CRYPT_ACTIVE) {
@@ -1485,11 +1498,9 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
log_dbg("Resuming volume %s.", name);
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
r = -EINVAL;
goto out;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
r = dm_status_suspended(cd, name);
if (r < 0)
@@ -1515,7 +1526,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
log_err(cd, _("Error during resuming device %s.\n"), name);
} else
r = keyslot;
out:
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
}
@@ -1534,11 +1545,9 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
log_dbg("Resuming volume %s.", name);
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
r = -EINVAL;
goto out;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
r = dm_status_suspended(cd, name);
if (r < 0)
@@ -1600,10 +1609,9 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
"new passphrase %sprovided.",
passphrase ? "" : "not ", new_passphrase ? "" : "not ");
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
return -EINVAL;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
r = keyslot_verify_or_find_empty(cd, &keyslot);
if (r)
@@ -1649,14 +1657,15 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
r = LUKS_set_key(keyslot, new_password, new_passwordLen,
&cd->u.luks1.hdr, vk, cd->iteration_time, &cd->u.luks1.PBKDF2_per_sec, cd);
if(r < 0) goto out;
if(r < 0)
goto out;
r = 0;
out:
if (!new_passphrase)
crypt_safe_free(new_password);
crypt_free_volume_key(vk);
return r ?: keyslot;
return r < 0 ? r : keyslot;
}
int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
@@ -1668,15 +1677,14 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
size_t new_passphrase_size)
{
struct volume_key *vk = NULL;
int r = -EINVAL;
int r;
log_dbg("Changing passphrase from old keyslot %d to new %d.",
keyslot_old, keyslot_new);
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
return -EINVAL;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
r = LUKS_open_key_with_hdr(keyslot_old, passphrase, passphrase_size,
&cd->u.luks1.hdr, &vk, cd);
@@ -1706,10 +1714,10 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
if (keyslot_old == keyslot_new) {
if (r >= 0)
log_verbose(cd, _("Key slot %d changed.\n"), r);
log_verbose(cd, _("Key slot %d changed.\n"), keyslot_new);
} else {
if (r >= 0) {
log_verbose(cd, _("Replaced with key slot %d.\n"), r);
log_verbose(cd, _("Replaced with key slot %d.\n"), keyslot_new);
r = crypt_keyslot_destroy(cd, keyslot_old);
}
}
@@ -1717,7 +1725,7 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
log_err(cd, _("Failed to swap new key slot.\n"));
out:
crypt_free_volume_key(vk);
return r ?: keyslot_new;
return r < 0 ? r : keyslot_new;
}
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
@@ -1737,10 +1745,9 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
log_dbg("Adding new keyslot, existing keyfile %s, new keyfile %s.",
keyfile ?: "[none]", new_keyfile ?: "[none]");
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
return -EINVAL;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
r = keyslot_verify_or_find_empty(cd, &keyslot);
if (r)
@@ -1813,15 +1820,14 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
size_t passphrase_size)
{
struct volume_key *vk = NULL;
int r = -EINVAL;
int r;
char *new_password = NULL; size_t new_passwordLen;
log_dbg("Adding new keyslot %d using volume key.", keyslot);
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
return -EINVAL;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
if (volume_key)
vk = crypt_alloc_volume_key(volume_key_size, volume_key);
@@ -1861,13 +1867,13 @@ out:
int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot)
{
crypt_keyslot_info ki;
int r;
log_dbg("Destroying keyslot %d.", keyslot);
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
return -EINVAL;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
ki = crypt_keyslot_status(cd, keyslot);
if (ki == CRYPT_SLOT_INVALID) {
@@ -2146,6 +2152,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
int crypt_deactivate(struct crypt_device *cd, const char *name)
{
struct crypt_device *fake_cd = NULL;
int r;
if (!name)
@@ -2153,16 +2160,24 @@ int crypt_deactivate(struct crypt_device *cd, const char *name)
log_dbg("Deactivating volume %s.", name);
if (!cd)
dm_backend_init();
if (!cd) {
r = crypt_init_by_name(&fake_cd, name);
if (r < 0)
return r;
cd = fake_cd;
}
switch (crypt_status(cd, name)) {
case CRYPT_ACTIVE:
case CRYPT_BUSY:
if (cd && isTCRYPT(cd->type))
if (isTCRYPT(cd->type))
r = TCRYPT_deactivate(cd, name);
else
r = dm_remove_device(cd, name, 0, 0);
if (r < 0 && crypt_status(cd, name) == CRYPT_BUSY) {
log_err(cd, _("Device %s is still in use.\n"), name);
r = -EBUSY;
}
break;
case CRYPT_INACTIVE:
log_err(cd, _("Device %s is not active.\n"), name);
@@ -2173,8 +2188,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name)
r = -EINVAL;
}
if (!cd)
dm_backend_exit();
crypt_free(fake_cd);
return r;
}
@@ -2230,10 +2244,9 @@ int crypt_volume_key_verify(struct crypt_device *cd,
struct volume_key *vk;
int r;
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
return -EINVAL;
}
r = onlyLUKS(cd);
if (r < 0)
return r;
vk = crypt_alloc_volume_key(volume_key_size, volume_key);
if (!vk)
@@ -2452,12 +2465,6 @@ const char *crypt_get_uuid(struct crypt_device *cd)
if (isLUKS(cd->type))
return cd->u.luks1.hdr.uuid;
if (isPLAIN(cd->type))
return cd->u.plain.uuid;
if (isLOOPAES(cd->type))
return cd->u.loopaes.uuid;
if (isVERITY(cd->type))
return cd->u.verity.uuid;
@@ -2530,10 +2537,8 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd)
crypt_keyslot_info crypt_keyslot_status(struct crypt_device *cd, int keyslot)
{
if (!isLUKS(cd->type)) {
log_err(cd, _("This operation is supported only for LUKS device.\n"));
if (onlyLUKS(cd) < 0)
return CRYPT_SLOT_INVALID;
}
return LUKS_keyslot_info(&cd->u.luks1.hdr, keyslot);
}
@@ -2607,3 +2612,8 @@ 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

@@ -2,15 +2,13 @@ moduledir = $(libdir)/cryptsetup
noinst_LTLIBRARIES = libtcrypt.la
libtcrypt_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
libtcrypt_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
libtcrypt_la_SOURCES = \
tcrypt.c \
tcrypt.h
AM_CPPFLAGS = -D_GNU_SOURCE \
-D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64 \
AM_CPPFLAGS = -include config.h \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/lib/crypto_backend

View File

@@ -2,7 +2,7 @@
* TCRYPT (TrueCrypt-compatible) volume handling
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012, Milan Broz
* Copyright (C) 2012-2014, Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -51,6 +51,7 @@ struct tcrypt_alg {
unsigned int iv_size;
unsigned int key_offset;
unsigned int iv_offset; /* or tweak key offset */
unsigned int key_extra_size;
};
struct tcrypt_algs {
@@ -66,101 +67,107 @@ struct tcrypt_algs {
static struct tcrypt_algs tcrypt_cipher[] = {
/* XTS mode */
{0,1,64,"aes","xts-plain64",
{{"aes", 64,16,0,32}}},
{{"aes", 64,16,0,32,0}}},
{0,1,64,"serpent","xts-plain64",
{{"serpent",64,16,0,32}}},
{{"serpent",64,16,0,32,0}}},
{0,1,64,"twofish","xts-plain64",
{{"twofish",64,16,0,32}}},
{{"twofish",64,16,0,32,0}}},
{0,2,128,"twofish-aes","xts-plain64",
{{"twofish",64,16, 0,64},
{"aes", 64,16,32,96}}},
{{"twofish",64,16, 0,64,0},
{"aes", 64,16,32,96,0}}},
{0,3,192,"serpent-twofish-aes","xts-plain64",
{{"serpent",64,16, 0, 96},
{"twofish",64,16,32,128},
{"aes", 64,16,64,160}}},
{{"serpent",64,16, 0, 96,0},
{"twofish",64,16,32,128,0},
{"aes", 64,16,64,160,0}}},
{0,2,128,"aes-serpent","xts-plain64",
{{"aes", 64,16, 0,64},
{"serpent",64,16,32,96}}},
{{"aes", 64,16, 0,64,0},
{"serpent",64,16,32,96,0}}},
{0,3,192,"aes-twofish-serpent","xts-plain64",
{{"aes", 64,16, 0, 96},
{"twofish",64,16,32,128},
{"serpent",64,16,64,160}}},
{{"aes", 64,16, 0, 96,0},
{"twofish",64,16,32,128,0},
{"serpent",64,16,64,160,0}}},
{0,2,128,"serpent-twofish","xts-plain64",
{{"serpent",64,16, 0,64},
{"twofish",64,16,32,96}}},
{{"serpent",64,16, 0,64,0},
{"twofish",64,16,32,96,0}}},
/* LRW mode */
{0,1,48,"aes","lrw-benbi",
{{"aes", 48,16,32,0}}},
{{"aes", 48,16,32,0,0}}},
{0,1,48,"serpent","lrw-benbi",
{{"serpent",48,16,32,0}}},
{{"serpent",48,16,32,0,0}}},
{0,1,48,"twofish","lrw-benbi",
{{"twofish",48,16,32,0}}},
{{"twofish",48,16,32,0,0}}},
{0,2,96,"twofish-aes","lrw-benbi",
{{"twofish",48,16,32,0},
{"aes", 48,16,64,0}}},
{{"twofish",48,16,32,0,0},
{"aes", 48,16,64,0,0}}},
{0,3,144,"serpent-twofish-aes","lrw-benbi",
{{"serpent",48,16,32,0},
{"twofish",48,16,64,0},
{"aes", 48,16,96,0}}},
{{"serpent",48,16,32,0,0},
{"twofish",48,16,64,0,0},
{"aes", 48,16,96,0,0}}},
{0,2,96,"aes-serpent","lrw-benbi",
{{"aes", 48,16,32,0},
{"serpent",48,16,64,0}}},
{{"aes", 48,16,32,0,0},
{"serpent",48,16,64,0,0}}},
{0,3,144,"aes-twofish-serpent","lrw-benbi",
{{"aes", 48,16,32,0},
{"twofish",48,16,64,0},
{"serpent",48,16,96,0}}},
{{"aes", 48,16,32,0,0},
{"twofish",48,16,64,0,0},
{"serpent",48,16,96,0,0}}},
{0,2,96,"serpent-twofish", "lrw-benbi",
{{"serpent",48,16,32,0},
{"twofish",48,16,64,0}}},
{{"serpent",48,16,32,0,0},
{"twofish",48,16,64,0,0}}},
/* Kernel LRW block size is fixed to 16 bytes for GF(2^128)
* thus cannot be used with blowfish where block is 8 bytes.
* There also no GF(2^64) support.
{1,1,64,"blowfish_le","lrw-benbi",
{{"blowfish_le",64,8,32,0}}},
{{"blowfish_le",64,8,32,0,0}}},
{1,2,112,"blowfish_le-aes","lrw-benbi",
{{"blowfish_le",64, 8,32,0},
{"aes", 48,16,88,0}}},
{{"blowfish_le",64, 8,32,0,0},
{"aes", 48,16,88,0,0}}},
{1,3,160,"serpent-blowfish_le-aes","lrw-benbi",
{{"serpent", 48,16, 32,0},
{"blowfish_le",64, 8, 64,0},
{"aes", 48,16,120,0}}},*/
/* CBC + "outer" CBC (both with whitening) */
{1,1,32,"aes","cbc-tcrypt",
{{"aes", 32,16,32,0}}},
{1,1,32,"serpent","cbc-tcrypt",
{{"serpent",32,16,32,0}}},
{1,1,32,"twofish","cbc-tcrypt",
{{"twofish",32,16,32,0}}},
{1,2,64,"twofish-aes","cbci-tcrypt",
{{"twofish",32,16,32,0},
{"aes", 32,16,64,0}}},
{1,3,96,"serpent-twofish-aes","cbci-tcrypt",
{{"serpent",32,16,32,0},
{"twofish",32,16,64,0},
{"aes", 32,16,96,0}}},
{1,2,64,"aes-serpent","cbci-tcrypt",
{{"aes", 32,16,32,0},
{"serpent",32,16,64,0}}},
{1,3,96,"aes-twofish-serpent", "cbci-tcrypt",
{{"aes", 32,16,32,0},
{"twofish",32,16,64,0},
{"serpent",32,16,96,0}}},
{1,2,64,"serpent-twofish", "cbci-tcrypt",
{{"serpent",32,16,32,0},
{"twofish",32,16,64,0}}},
{1,1,16,"cast5","cbc-tcrypt",
{{"cast5", 16,8,32,0}}},
{1,1,24,"des3_ede","cbc-tcrypt",
{{"des3_ede",24,8,32,0}}},
{1,1,56,"blowfish_le","cbc-tcrypt",
{{"blowfish_le",56,8,32,0}}},
{1,2,88,"blowfish_le-aes","cbc-tcrypt",
{{"blowfish_le",56, 8,32,0},
{"aes", 32,16,88,0}}},
{1,3,120,"serpent-blowfish_le-aes","cbc-tcrypt",
{{"serpent", 32,16, 32,0},
{"blowfish_le",56, 8, 64,0},
{"aes", 32,16,120,0}}},
{{"serpent", 48,16, 32,0,0},
{"blowfish_le",64, 8, 64,0,0},
{"aes", 48,16,120,0,0}}},*/
/*
* CBC + "outer" CBC (both with whitening)
* chain_key_size: alg_keys_bytes + IV_seed_bytes + whitening_bytes
*/
{1,1,32+16+16,"aes","cbc-tcw",
{{"aes", 32,16,32,0,32}}},
{1,1,32+16+16,"serpent","cbc-tcw",
{{"serpent",32,16,32,0,32}}},
{1,1,32+16+16,"twofish","cbc-tcw",
{{"twofish",32,16,32,0,32}}},
{1,2,64+16+16,"twofish-aes","cbci-tcrypt",
{{"twofish",32,16,32,0,0},
{"aes", 32,16,64,0,32}}},
{1,3,96+16+16,"serpent-twofish-aes","cbci-tcrypt",
{{"serpent",32,16,32,0,0},
{"twofish",32,16,64,0,0},
{"aes", 32,16,96,0,32}}},
{1,2,64+16+16,"aes-serpent","cbci-tcrypt",
{{"aes", 32,16,32,0,0},
{"serpent",32,16,64,0,32}}},
{1,3,96+16+16,"aes-twofish-serpent", "cbci-tcrypt",
{{"aes", 32,16,32,0,0},
{"twofish",32,16,64,0,0},
{"serpent",32,16,96,0,32}}},
{1,2,64+16+16,"serpent-twofish", "cbci-tcrypt",
{{"serpent",32,16,32,0,0},
{"twofish",32,16,64,0,32}}},
{1,1,16+8+16,"cast5","cbc-tcw",
{{"cast5", 16,8,32,0,24}}},
{1,1,24+8+16,"des3_ede","cbc-tcw",
{{"des3_ede",24,8,32,0,24}}},
{1,1,56+8+16,"blowfish_le","cbc-tcrypt",
{{"blowfish_le",56,8,32,0,24}}},
{1,2,88+16+16,"blowfish_le-aes","cbc-tcrypt",
{{"blowfish_le",56, 8,32,0,0},
{"aes", 32,16,88,0,32}}},
{1,3,120+16+16,"serpent-blowfish_le-aes","cbc-tcrypt",
{{"serpent", 32,16, 32,0,0},
{"blowfish_le",56, 8, 64,0,0},
{"aes", 32,16,120,0,32}}},
{}
};
@@ -289,6 +296,9 @@ static void TCRYPT_copy_key(struct tcrypt_alg *alg, const char *mode,
memcpy(&out_key[ks2], key, TCRYPT_LRW_IKEY_LEN);
} else if (!strncmp(mode, "cbc", 3)) {
memcpy(out_key, &key[alg->key_offset], alg->key_size);
/* IV + whitening */
memcpy(&out_key[alg->key_size], &key[alg->iv_offset],
alg->key_extra_size);
}
}
@@ -485,6 +495,12 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
else
passphrase_size = params->passphrase_size;
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded.\n"),
TCRYPT_KEY_POOL_LEN);
return -EPERM;
}
/* Calculate pool content from keyfiles */
for (i = 0; i < params->keyfiles_count; i++) {
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
@@ -520,13 +536,13 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
r = TCRYPT_decrypt_hdr(cd, hdr, key, legacy_modes);
if (r == -ENOENT) {
skipped++;
continue;
r = -EPERM;
}
if (r != -EPERM)
break;
}
if ((skipped && skipped == i) || r == -ENOTSUP) {
if ((r < 0 && r != -EPERM && skipped && skipped == i) || r == -ENOTSUP) {
log_err(cd, _("Required kernel crypto interface not available.\n"));
#ifdef ENABLE_AF_ALG
log_err(cd, _("Ensure you have algif_skcipher kernel module loaded.\n"));
@@ -557,8 +573,9 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
struct tcrypt_phdr *hdr,
struct crypt_params_tcrypt *params)
{
struct device *device = crypt_metadata_device(cd);
struct device *base_device, *device = crypt_metadata_device(cd);
ssize_t hdr_size = sizeof(struct tcrypt_phdr);
char *base_device_path;
int devfd = 0, r, bs;
assert(sizeof(struct tcrypt_phdr) == 512);
@@ -570,7 +587,23 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
if (bs < 0)
return bs;
devfd = device_open(device, O_RDONLY);
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER &&
crypt_dev_is_partition(device_path(device))) {
base_device_path = crypt_get_base_device(device_path(device));
log_dbg("Reading TCRYPT system header from device %s.", base_device_path ?: "?");
if (!base_device_path)
return -EINVAL;
r = device_alloc(&base_device, base_device_path);
if (r < 0)
return r;
devfd = device_open(base_device, O_RDONLY);
free(base_device_path);
device_free(base_device);
} else
devfd = device_open(device, O_RDONLY);
if (devfd == -1) {
log_err(cd, _("Cannot open device %s.\n"), device_path(device));
return -EINVAL;
@@ -579,8 +612,9 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
r = -EIO;
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
if (lseek(devfd, TCRYPT_HDR_SYSTEM_OFFSET, SEEK_SET) >= 0 &&
read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) {
r = TCRYPT_init_hdr(cd, hdr, params);
}
} else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
if (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_BCK, SEEK_END) >= 0 &&
@@ -630,10 +664,13 @@ int TCRYPT_activate(struct crypt_device *cd,
uint32_t flags)
{
char cipher[MAX_CIPHER_LEN], dm_name[PATH_MAX], dm_dev_name[PATH_MAX];
struct device *device = NULL;
char *part_path;
struct device *device = NULL, *part_device = NULL;
unsigned int i;
int r;
uint32_t req_flags;
struct tcrypt_algs *algs;
enum devcheck device_check;
struct crypt_dm_active_device dmd = {
.target = DM_CRYPT,
.size = 0,
@@ -661,22 +698,55 @@ int TCRYPT_activate(struct crypt_device *cd,
return -ENOTSUP;
}
if (strstr(params->mode, "-tcw"))
req_flags = DM_TCW_SUPPORTED;
else
req_flags = DM_PLAIN64_SUPPORTED;
algs = TCRYPT_get_algs(params->cipher, params->mode);
if (!algs)
return -EINVAL;
if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
dmd.size = 0;
else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
dmd.size = hdr->d.hidden_volume_size / hdr->d.sector_size;
else
dmd.size = hdr->d.volume_size / hdr->d.sector_size;
r = device_block_adjust(cd, dmd.data_device, DEV_EXCL,
if (dmd.flags & CRYPT_ACTIVATE_SHARED)
device_check = DEV_SHARED;
else
device_check = DEV_EXCL;
if ((params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) &&
!crypt_dev_is_partition(device_path(dmd.data_device))) {
part_path = crypt_get_partition_device(device_path(dmd.data_device),
dmd.u.crypt.offset, dmd.size);
if (part_path) {
if (!device_alloc(&part_device, part_path)) {
log_verbose(cd, _("Activating TCRYPT system encryption for partition %s.\n"),
part_path);
dmd.data_device = part_device;
dmd.u.crypt.offset = 0;
}
free(part_path);
} else
/*
* System encryption use the whole device mapping, there can
* be active partitions.
*/
device_check = DEV_SHARED;
}
r = device_block_adjust(cd, dmd.data_device, device_check,
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
if (r)
return r;
/* Frome here, key size for every cipher must be the same */
dmd.u.crypt.vk = crypt_alloc_volume_key(algs->cipher[0].key_size, NULL);
dmd.u.crypt.vk = crypt_alloc_volume_key(algs->cipher[0].key_size +
algs->cipher[0].key_extra_size, NULL);
if (!dmd.u.crypt.vk)
return -ENOMEM;
@@ -716,11 +786,12 @@ int TCRYPT_activate(struct crypt_device *cd,
break;
}
if (r < 0 && !(dm_flags() & DM_PLAIN64_SUPPORTED)) {
log_err(cd, _("Kernel doesn't support plain64 IV.\n"));
if (r < 0 && !(dm_flags() & req_flags)) {
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping.\n"));
r = -ENOTSUP;
}
device_free(part_device);
crypt_free_volume_key(dmd.u.crypt.vk);
return r;
}
@@ -870,8 +941,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
goto hdr_offset;
/* Mapping through whole device, not partition! */
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
if (crypt_dev_is_partition(device_path(crypt_metadata_device(cd))))
return 0;
goto hdr_offset;
}
if (params->mode && !strncmp(params->mode, "xts", 3)) {
if (hdr->d.version < 3)
@@ -901,15 +975,21 @@ hdr_offset:
uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
struct tcrypt_phdr *hdr,
struct crypt_params_tcrypt *params
)
struct crypt_params_tcrypt *params)
{
if (params->mode && !strncmp(params->mode, "xts", 3))
return TCRYPT_get_data_offset(cd, hdr, params);
else if (params->mode && !strncmp(params->mode, "lrw", 3))
return 0;
uint64_t iv_offset;
return hdr->d.mk_offset / hdr->d.sector_size;
if (params->mode && !strncmp(params->mode, "xts", 3))
iv_offset = TCRYPT_get_data_offset(cd, hdr, params);
else if (params->mode && !strncmp(params->mode, "lrw", 3))
iv_offset = 0;
else
iv_offset = hdr->d.mk_offset / hdr->d.sector_size;
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
iv_offset += crypt_dev_partition_offset(device_path(crypt_metadata_device(cd)));
return iv_offset;
}
int TCRYPT_get_volume_key(struct crypt_device *cd,

View File

@@ -2,7 +2,7 @@
* TCRYPT (TrueCrypt-compatible) header defitinion
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012, Milan Broz
* Copyright (C) 2012-2014, Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -2,7 +2,7 @@
* libcryptsetup - cryptsetup library, cipher bechmark
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012, Milan Broz
* Copyright (C) 2012-2013, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,8 +21,7 @@
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <time.h>
#include "internal.h"
@@ -32,6 +31,12 @@
*/
#define CIPHER_BLOCK_BYTES 65536
/*
* If the measured value is lower, encrypted buffer is probably too small
* and calculated values are not reliable.
*/
#define CIPHER_TIME_MIN_MS 0.001
/*
* The whole test depends on Linux kernel usermode crypto API for now.
* (The same implementations are used in dm-crypt though.)
@@ -47,19 +52,15 @@ struct cipher_perf {
size_t buffer_size;
};
static long time_ms(struct rusage *start, struct rusage *end)
static int time_ms(struct timespec *start, struct timespec *end, double *ms)
{
long ms = 0;
double start_ms, end_ms;
/* For kernel backend, we need to measure only tim in kernel.
ms = (end->ru_utime.tv_sec - start->ru_utime.tv_sec) * 1000;
ms += (end->ru_utime.tv_usec - start->ru_utime.tv_usec) / 1000;
*/
start_ms = start->tv_sec * 1000.0 + start->tv_nsec / (1000.0 * 1000);
end_ms = end->tv_sec * 1000.0 + end->tv_nsec / (1000.0 * 1000);
ms += (end->ru_stime.tv_sec - start->ru_stime.tv_sec) * 1000;
ms += (end->ru_stime.tv_usec - start->ru_stime.tv_usec) / 1000;
return ms;
*ms = end_ms - start_ms;
return 0;
}
static int cipher_perf_one(struct cipher_perf *cp, char *buf,
@@ -98,26 +99,39 @@ static int cipher_perf_one(struct cipher_perf *cp, char *buf,
return r;
}
static long cipher_measure(struct cipher_perf *cp, char *buf,
size_t buf_size, int encrypt)
static int cipher_measure(struct cipher_perf *cp, char *buf,
size_t buf_size, int encrypt, double *ms)
{
struct rusage rstart, rend;
struct timespec start, end;
int r;
if (getrusage(RUSAGE_SELF, &rstart) < 0)
/*
* Using getrusage would be better here but the precision
* is not adequate, so better stick with CLOCK_MONOTONIC
*/
if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
return -EINVAL;
r = cipher_perf_one(cp, buf, buf_size, encrypt);
if (r < 0)
return r;
if (getrusage(RUSAGE_SELF, &rend) < 0)
if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
return -EINVAL;
return time_ms(&rstart, &rend);
r = time_ms(&start, &end, ms);
if (r < 0)
return r;
if (*ms < CIPHER_TIME_MIN_MS) {
log_dbg("Measured cipher runtime (%1.6f) is too low.", *ms);
return -ERANGE;
}
return 0;
}
static double speed_mbs(unsigned long bytes, unsigned long ms)
static double speed_mbs(unsigned long bytes, double ms)
{
double speed = bytes, s = ms / 1000.;
@@ -127,32 +141,32 @@ static double speed_mbs(unsigned long bytes, unsigned long ms)
static int cipher_perf(struct cipher_perf *cp,
double *encryption_mbs, double *decryption_mbs)
{
long ms_enc, ms_dec, ms;
int repeat_enc, repeat_dec;
double ms_enc, ms_dec, ms;
int r, repeat_enc, repeat_dec;
void *buf = NULL;
if (posix_memalign(&buf, crypt_getpagesize(), cp->buffer_size))
return -ENOMEM;
ms_enc = 0;
ms_enc = 0.0;
repeat_enc = 1;
while (ms_enc < 1000) {
ms = cipher_measure(cp, buf, cp->buffer_size, 1);
if (ms < 0) {
while (ms_enc < 1000.0) {
r = cipher_measure(cp, buf, cp->buffer_size, 1, &ms);
if (r < 0) {
free(buf);
return (int)ms;
return r;
}
ms_enc += ms;
repeat_enc++;
}
ms_dec = 0;
ms_dec = 0.0;
repeat_dec = 1;
while (ms_dec < 1000) {
ms = cipher_measure(cp, buf, cp->buffer_size, 0);
if (ms < 0) {
while (ms_dec < 1000.0) {
r = cipher_measure(cp, buf, cp->buffer_size, 0, &ms);
if (r < 0) {
free(buf);
return (int)ms;
return r;
}
ms_dec += ms;
repeat_dec++;

View File

@@ -24,10 +24,9 @@
#define _UTILS_CRYPT_H
#include <unistd.h>
#include "config.h"
#define MAX_CIPHER_LEN 32
#define MAX_CIPHER_LEN_STR "32"
#define MAX_CIPHER_LEN_STR "31"
#define MAX_KEYFILES 32
struct crypt_device;

View File

@@ -221,7 +221,7 @@ int device_block_size(struct device *device)
if (fstat(fd, &st) < 0)
goto out;
if (S_ISREG(st.st_mode)) {
if (S_ISREG(st.st_mode) || device->file_path) {
r = (int)crypt_getpagesize();
goto out;
}

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004, Christophe Saout <christophe@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-2013, 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,12 +28,10 @@
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "utils_dm.h"
char *crypt_lookup_dev(const char *dev_id);
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
#include "internal.h"
static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
{
@@ -169,16 +167,12 @@ char *crypt_lookup_dev(const char *dev_id)
return devpath;
}
int crypt_sysfs_get_rotational(int major, int minor, int *rotational)
static int _read_uint64(const char *sysfs_path, uint64_t *value)
{
char path[PATH_MAX], tmp[64] = {0};
char tmp[64] = {0};
int fd, r;
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/queue/rotational",
major, minor) < 0)
return 0;
if ((fd = open(path, O_RDONLY)) < 0)
if ((fd = open(sysfs_path, O_RDONLY)) < 0)
return 0;
r = read(fd, tmp, sizeof(tmp));
close(fd);
@@ -186,8 +180,185 @@ int crypt_sysfs_get_rotational(int major, int minor, int *rotational)
if (r <= 0)
return 0;
if (sscanf(tmp, "%d", rotational) != 1)
if (sscanf(tmp, "%" PRIu64, value) != 1)
return 0;
return 1;
}
static int _sysfs_get_uint64(int major, int minor, uint64_t *value, const char *attr)
{
char path[PATH_MAX];
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/%s",
major, minor, attr) < 0)
return 0;
return _read_uint64(path, value);
}
static int _path_get_uint64(const char *sysfs_path, uint64_t *value, const char *attr)
{
char path[PATH_MAX];
if (snprintf(path, sizeof(path), "%s/%s",
sysfs_path, attr) < 0)
return 0;
return _read_uint64(path, value);
}
int crypt_dev_is_rotational(int major, int minor)
{
uint64_t val;
if (!_sysfs_get_uint64(major, minor, &val, "queue/rotational"))
return 1; /* if failed, expect rotational disk */
return val ? 1 : 0;
}
int crypt_dev_is_partition(const char *dev_path)
{
uint64_t val;
struct stat st;
if (stat(dev_path, &st) < 0)
return 0;
if (!S_ISBLK(st.st_mode))
return 0;
if (!_sysfs_get_uint64(major(st.st_rdev), minor(st.st_rdev),
&val, "partition"))
return 0;
return val ? 1 : 0;
}
uint64_t crypt_dev_partition_offset(const char *dev_path)
{
uint64_t val;
struct stat st;
if (!crypt_dev_is_partition(dev_path))
return 0;
if (stat(dev_path, &st) < 0)
return 0;
if (!_sysfs_get_uint64(major(st.st_rdev), minor(st.st_rdev),
&val, "start"))
return 0;
return val;
}
/* Try to find partition which match offset and size on top level device */
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size)
{
char link[PATH_MAX], path[PATH_MAX], part_path[PATH_MAX], *devname;
char *result = NULL;
struct stat st;
size_t devname_len;
ssize_t len;
struct dirent *entry;
DIR *dir;
uint64_t part_offset, part_size;
if (stat(dev_path, &st) < 0)
return NULL;
if (!S_ISBLK(st.st_mode))
return NULL;
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d",
major(st.st_rdev), minor(st.st_rdev)) < 0)
return NULL;
len = readlink(path, link, sizeof(link) - 1);
if (len < 0)
return NULL;
/* Get top level disk name for sysfs search */
link[len] = '\0';
devname = strrchr(link, '/');
if (!devname)
return NULL;
devname++;
/* DM devices do not use kernel partitions. */
if (dm_is_dm_kernel_name(devname))
return NULL;
dir = opendir(path);
if (!dir)
return NULL;
devname_len = strlen(devname);
while((entry = readdir(dir))) {
if (strncmp(entry->d_name, devname, devname_len))
continue;
if (snprintf(part_path, sizeof(part_path), "%s/%s",
path, entry->d_name) < 0)
continue;
if (stat(part_path, &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
if (!_path_get_uint64(part_path, &part_offset, "start") ||
!_path_get_uint64(part_path, &part_size, "size"))
continue;
if (part_offset == offset && part_size == size &&
snprintf(part_path, sizeof(part_path), "/dev/%s",
entry->d_name) > 0) {
result = strdup(part_path);
break;
}
}
}
closedir(dir);
return result;
}
/* Try to find base device from partition */
char *crypt_get_base_device(const char *dev_path)
{
char link[PATH_MAX], path[PATH_MAX], part_path[PATH_MAX], *devname;
struct stat st;
ssize_t len;
if (!crypt_dev_is_partition(dev_path))
return NULL;
if (stat(dev_path, &st) < 0)
return NULL;
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d",
major(st.st_rdev), minor(st.st_rdev)) < 0)
return NULL;
len = readlink(path, link, sizeof(link) - 1);
if (len < 0)
return NULL;
/* Get top level disk name for sysfs search */
link[len] = '\0';
devname = strrchr(link, '/');
if (!devname)
return NULL;
*devname = '\0';
devname = strrchr(link, '/');
if (!devname)
return NULL;
devname++;
if (dm_is_dm_kernel_name(devname))
return NULL;
snprintf(part_path, sizeof(part_path), "/dev/%s", devname);
return strdup(part_path);
}

View File

@@ -39,6 +39,7 @@ struct device;
#define DM_PLAIN64_SUPPORTED (1 << 3) /* plain64 IV */
#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) */
uint32_t dm_flags(void);
#define DM_ACTIVE_DEVICE (1 << 0)

View File

@@ -1,7 +1,7 @@
/*
* FIPS mode utilities
*
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2013, 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
@@ -19,45 +19,35 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "libcryptsetup.h"
#include "nls.h"
#include "utils_fips.h"
#include "config.h"
#if !ENABLE_FIPS
int crypt_fips_mode(void) { return 0; }
void crypt_fips_libcryptsetup_check(struct crypt_device *cd) {}
void crypt_fips_self_check(struct crypt_device *cd) {}
void crypt_fips_libcryptsetup_check(void) {}
#else
#include <fipscheck.h>
int crypt_fips_mode(void)
{
return FIPSCHECK_kernel_fips_mode();
return FIPSCHECK_kernel_fips_mode() && !access(FIPS_MODULE_FILE, F_OK);
}
static void crypt_fips_verify(struct crypt_device *cd,
const char *name, const char *function)
static void crypt_fips_verify(const char *name, const char *function)
{
if (!crypt_fips_mode())
return;
if (!FIPSCHECK_verify(name, function)) {
crypt_log(cd, CRYPT_LOG_ERROR, _("FIPS checksum verification failed.\n"));
fputs(_("FIPS checksum verification failed.\n"), stderr);
_exit(EXIT_FAILURE);
}
crypt_log(cd, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
}
void crypt_fips_libcryptsetup_check(struct crypt_device *cd)
void crypt_fips_libcryptsetup_check(void)
{
crypt_fips_verify(cd, LIBCRYPTSETUP_VERSION_FIPS, "crypt_init");
}
void crypt_fips_self_check(struct crypt_device *cd)
{
crypt_fips_verify(cd, NULL, NULL);
crypt_fips_verify(LIBCRYPTSETUP_VERSION_FIPS, "crypt_init");
}
#endif /* ENABLE_FIPS */

View File

@@ -1,7 +1,7 @@
/*
* FIPS mode utilities
*
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2013, 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
@@ -24,7 +24,6 @@
struct crypt_device;
int crypt_fips_mode(void);
void crypt_fips_libcryptsetup_check(struct crypt_device *cd);
void crypt_fips_self_check(struct crypt_device *cd);
void crypt_fips_libcryptsetup_check(void);
#endif /* _UTILS_FIPS_H */

View File

@@ -124,7 +124,7 @@ int crypt_wipe(struct device *device,
{
struct stat st;
char *buffer;
int devfd, flags, rotational, bsize;
int devfd, flags, bsize;
ssize_t written;
if (!size || size % SECTOR_SIZE || (size > MAXIMUM_WIPE_BYTES)) {
@@ -139,14 +139,12 @@ int crypt_wipe(struct device *device,
}
if (type == CRYPT_WIPE_DISK && S_ISBLK(st.st_mode)) {
rotational = 0;
if (!crypt_sysfs_get_rotational(major(st.st_rdev),
minor(st.st_rdev),
&rotational))
rotational = 1;
log_dbg("Rotational flag is %d.", rotational);
if (!rotational)
if (!crypt_dev_is_rotational(major(st.st_rdev),
minor(st.st_rdev))) {
type = CRYPT_WIPE_SSD;
log_dbg("Non-rotational device, using SSD wipe mode.");
} else
log_dbg("Rotational device, using normal wipe mode.");
}
bsize = device_block_size(device);

View File

@@ -2,15 +2,13 @@ moduledir = $(libdir)/cryptsetup
noinst_LTLIBRARIES = libverity.la
libverity_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
libverity_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
libverity_la_SOURCES = \
verity_hash.c \
verity.c \
verity.h
AM_CPPFLAGS = -D_GNU_SOURCE \
-D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64 \
AM_CPPFLAGS = -include config.h \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/lib/crypto_backend

View File

@@ -22,7 +22,6 @@
#define _VERITY_H
#include <unistd.h>
#include "config.h"
#define VERITY_MAX_HASH_TYPE 1
#define VERITY_BLOCK_SIZE_OK(x) ((x) % 512 || (x) < 512 || \

View File

@@ -220,7 +220,7 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
off_t hash_level_block[VERITY_MAX_LEVELS];
off_t hash_level_size[VERITY_MAX_LEVELS];
off_t data_file_blocks, s;
size_t hash_per_block, hash_per_block_bits;
size_t hash_per_block_bits;
off_t data_device_size = 0, hash_device_size = 0;
uint64_t dev_size;
int levels, i, r;
@@ -251,7 +251,6 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
}
hash_per_block_bits = get_bits_down(hash_block_size / digest_size);
hash_per_block = 1 << hash_per_block_bits;
if (!hash_per_block_bits)
return -EINVAL;
@@ -271,8 +270,7 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
for (i = levels - 1; i >= 0; i--) {
hash_level_block[i] = hash_position;
// verity position of block data_file_blocks at level i
s = data_file_blocks >> (i * hash_per_block_bits);
s = (s + hash_per_block - 1) / hash_per_block;
s = (data_file_blocks + ((off_t)1 << ((i + 1) * hash_per_block_bits)) - 1) >> ((i + 1) * hash_per_block_bits);
hash_level_size[i] = s;
if ((hash_position + s) < hash_position ||
(hash_position + s) < 0) {

View File

@@ -1,4 +1,4 @@
.TH CRYPTSETUP-REENCRYPT "8" "June 2012" "cryptsetup-reencrypt" "Maintenance Commands"
.TH CRYPTSETUP-REENCRYPT "8" "December 2013" "cryptsetup-reencrypt" "Maintenance Commands"
.SH NAME
cryptsetup-reencrypt - tool for offline LUKS device re-encryption
.SH SYNOPSIS
@@ -56,7 +56,7 @@ Set the cipher specification string.
.B "\-\-key-size, \-s \fI<bits>\fR"
Set key size in bits. The argument has to be a multiple of 8.
The possible key-sizes are limited by the cipher and mode used.
The possible key-sizes are limited by the cipher and mode used.
If you are increasing key size, there must be enough space in the LUKS header
for enlarged keyslots (data offset must be large enough) or reencryption
@@ -67,6 +67,9 @@ you can destructively shrink device with \-\-reduce-device-size option.
.TP
.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
for new device header.
.TP
.B "\-\-iter-time, \-i \fI<milliseconds>\fR"
The number of milliseconds to spend with PBKDF2 passphrase processing for the
@@ -100,6 +103,12 @@ Read a maximum of \fIvalue\fR bytes from the key file.
Default is to read the whole file up to the compiled-in
maximum.
.TP
.B "\-\-keep-key"
Do not change encryption key, just reencrypt the LUKS header and keyslots.
This option can be combined only with \fI\-\-hash\fR or \fI\-\-iter-time\fR
options.
.TP
.B "\-\-tries, \-T"
Number of retries for invalid passphrase entry.
.TP
@@ -200,9 +209,9 @@ 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 Milan Broz
Copyright \(co 2012-2014 Milan Broz
.br
Copyright \(co 2012 Red Hat, Inc.
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.

View File

@@ -1,4 +1,4 @@
.TH CRYPTSETUP "8" "May 2012" "cryptsetup" "Maintenance Commands"
.TH CRYPTSETUP "8" "December 2013" "cryptsetup" "Maintenance Commands"
.SH NAME
cryptsetup - manage plain dm-crypt and LUKS encrypted volumes
.SH SYNOPSIS
@@ -10,6 +10,10 @@ device-mapper mappings. These include plain dm-crypt volumes and
LUKS volumes. The difference is that LUKS uses a metadata header
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.
.SH PLAIN DM-CRYPT OR LUKS?
.PP
Unless you understand the cryptographic background well, use LUKS.
@@ -51,27 +55,27 @@ secure wiping by just overwriting header and key-slot area.
\fBPreviously used partitions:\fR If a partition was previously used,
it is a very good idea to wipe filesystem signatures, data, etc. before
creating a LUKS or plain dm-crypt container on it.
For a quick removal of filesystem signatures, use "wipefs". Take care
though that this may not remove everything. In particular md (RAID)
signatures at the end of a device may survive. It also does not
remove data. For a full wipe, overwrite the whole partition before
creating a LUKS or plain dm-crypt container on it.
For a quick removal of filesystem signatures, use "wipefs". Take care
though that this may not remove everything. In particular md (RAID)
signatures at the end of a device may survive. It also does not
remove data. For a full wipe, overwrite the whole partition before
container creation. If you do not know how to to that, the
cryptsetup FAQ describes several options.
.SH BASIC COMMANDS
The following are valid actions for all supported device types.
\fIopen\fR <name> <device> \-\-type <device_type>
\fIopen\fR <device> <name> \-\-type <device_type>
.IP
Opens (creates a mapping) with <name> backed by device <device>.
Opens (creates a mapping with) <name> backed by device <device>.
Device type can be \fIplain\fR, \fIluks\fR (default), \fIloopaes\fR
or \fItcrypt\fR.
For backward compatibility there are \fBopen\fR command aliases:
\fBcreate\fR: open \-\-type plain <device> <name>\fR switched arguments)
\fBcreate\fR (argument-order <name> <device>): open \-\-type plain
.br
\fBplainOpen\fR: open \-\-type plain
.br
@@ -82,7 +86,9 @@ For backward compatibility there are \fBopen\fR command aliases:
\fBtcryptOpen\fR: open \-\-type tcrypt
\fB<options>\fR are type specific and are described below
for individual device types.
for individual device types. For \fBcreate\fR, the order of the <name>
and <device> options is inverted for historical reasons, all other
aliases use the standard \fB<device> <name>\fR order.
.PP
\fIclose\fR <name>
.IP
@@ -109,7 +115,7 @@ sectors of the raw device are represented in the mapped device.
Plain dm-crypt encrypts the device sector-by-sector with a
single, non-salted hash of the passphrase. No checks
are performed, no metadata is used. There is no formatting operation.
When the raw device is mapped (created), the usual device operations
When the raw device is mapped (opened), the usual device operations
can be used on the mapped device, including filesystem creation.
Mapped devices usually reside in /dev/mapper/<name>.
@@ -119,7 +125,7 @@ The following are valid plain device type actions:
.br
\fIcreate\fR <name> <device> (\fBOBSOLETE syntax\fR)
.IP
Creates a mapping with <name> backed by device <device>.
Opens (creates a mapping with) <name> backed by device <device>.
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
@@ -159,7 +165,7 @@ The following are valid LUKS actions:
\fIluksFormat\fR <device> [<key file>]
.IP
Initializes a LUKS partition and sets the initial passphrase
(for key-slot 0),
(for key-slot 0),
either via prompting or via <key file>. Note that
if the second argument is present, then the passphrase
is taken from the file given there, without the need
@@ -170,10 +176,12 @@ from stdin and the safety-question being skipped.
You can only call luksFormat on a LUKS device that is not mapped.
\fB<options>\fR can be [\-\-cipher, \-\-verify-passphrase, \-\-key-size,
\-\-key-slot, \-\-key-file (takes precedence over optional second argument),
\-\-keyfile-offset, \-\-keyfile-size, \-\-use-random | \-\-use-urandom,
\-\-uuid, \-\-master-key-file].
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify\-passphrase,
\-\-key\-size, \-\-key\-slot,
\-\-key\-file (takes precedence over optional second argument),
\-\-keyfile\-offset, \-\-keyfile\-size, \-\-use\-random | \-\-use\-urandom,
\-\-uuid, \-\-master\-key\-file, \-\-iter\-time, \-\-header,
\-\-force\-password].
\fBWARNING:\fR Doing a luksFormat on an existing LUKS container will
make all data the old container permanently irretrievable, unless
@@ -191,9 +199,9 @@ 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].
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
\-\-keyfile\-size, \-\-readonly, \-\-test\-passphrase,
\-\-allow\-discards, \-\-header, \-\-key-slot, \-\-master\-key\-file].
.PP
\fIluksSuspend\fR <name>
.IP
@@ -215,7 +223,7 @@ the mapped device.
Resumes a suspended device and reinstates the encryption key.
Prompts interactively for a passphrase if \-\-key-file is not given.
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-header]
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-size, \-\-header]
.PP
\fIluksAddKey\fR <device> [<key file with new key>]
.IP
@@ -224,9 +232,10 @@ interactively or via \-\-key-file.
The new passphrase to be added can be specified interactively
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].
\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].
.PP
\fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>]
.IP
@@ -234,12 +243,12 @@ Removes the supplied passphrase from the LUKS device. The
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]
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
\-\-keyfile\-size]
\fBWARNING:\fR If you read the passphrase from stdin
(without further argument or with '-' as argument
to \-\-key-file), batch-mode (-q) will be implicitely
(without further argument or with '-' as argument
to \-\-key\-file), batch-mode (-q) will be implicitely
switched on and no warning will be given when you remove the
last remaining passphrase from a LUKS container. Removing
the last passphrase makes the LUKS container permanently
@@ -248,7 +257,7 @@ inaccessible.
\fIluksChangeKey\fR <device> [<new key file>]
.IP
Changes an existing passphrase. The passphrase
to be changed must be supplied interactively or via \-\-key-file.
to be changed must be supplied interactively or via \-\-key\-file.
The new passphrase can be supplied interactively or in
a file given as positional argument.
@@ -266,9 +275,9 @@ during this operation can cause the overwrite to fail after
the old passphrase has been wiped and make the LUKS container
inaccessible.
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
\-\-keyfile-size, \-\-new-keyfile-offset,
\-\-new-keyfile-size, \-\-key-slot].
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
\-\-keyfile\-size, \-\-new\-keyfile\-offset,
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-force\-password].
.PP
\fIluksKillSlot\fR <device> <key slot number>
.IP
@@ -278,7 +287,8 @@ This command can remove the last remaining key-slot, but requires
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].
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
\-\-keyfile\-size].
\fBWARNING:\fR If you read the passphrase from stdin
(without further argument or with '-' as argument
@@ -288,6 +298,15 @@ last remaining passphrase from a LUKS container. Removing
the last passphrase makes the LUKS container permanently
inaccessible.
.PP
\fIerase\fR <device>
.br
\fIluksErase\fR <device>
.IP
Erase all keyslots and make the LUKS container permanently inaccessible.
You do not need to provide any password for this operation.
\fBWARNING:\fR This operation is irreversible.
.PP
\fIluksUUID\fR <device>
.IP
Print the UUID of a LUKS device.
@@ -304,7 +323,7 @@ means the device is a LUKS device.
.IP
Dump the header information of a LUKS device.
If the \-\-dump-master-key option is used, the LUKS device master key is
If the \-\-dump\-master\-key option is used, the LUKS device master key is
dumped instead of the keyslot info. Beware that the master key cannot be
changed and can be used to decrypt the data stored in the LUKS container
without a passphrase and even without the LUKS header. This means
@@ -312,16 +331,16 @@ that if the master key is compromised, the whole device has to be
erased to prevent further access. Use this option carefully.
In order to dump the master key, a passphrase has to be supplied,
either interactively or via \-\-key-file.
either interactively or via \-\-key\-file.
\fB<options>\fR can be [\-\-dump-master-key, \-\-key-file,
\-\-keyfile-offset, \-\-keyfile-size].
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
\-\-keyfile\-offset, \-\-keyfile\-size].
\fBWARNING:\fR If \-\-dump-master-key is used with \-\-key-file
and the argument to \-\-key-file is '-', no validation question
\fBWARNING:\fR If \-\-dump\-master\-key is used with \-\-key\-file
and the argument to \-\-key\-file is '-', no validation question
will be asked and no warning given.
.PP
\fIluksHeaderBackup\fR <device> \-\-header-backup-file <file>
\fIluksHeaderBackup\fR <device> \-\-header\-backup\-file <file>
.IP
Stores a binary backup of the LUKS header and keyslot area.
.br
@@ -338,7 +357,7 @@ addition or overwrite the encrypted data area as well.
The second option is less secure, as some sectors
can survive, e.g. due to defect management.
.PP
\fIluksHeaderRestore\fR <device> \-\-header-backup-file <file>
\fIluksHeaderRestore\fR <device> \-\-header\-backup\-file <file>
.IP
Restores a binary backup of the LUKS header and keyslot area
from the specified file.
@@ -356,18 +375,19 @@ the backup will also be written to it.
cryptsetup supports mapping loop-AES encrypted partition using
a compatibility mode.
.PP
\fIopen\fR \-\-type loopaes <device> <name> \-\-key-file <keyfile>
\fIopen\fR \-\-type loopaes <device> <name> \-\-key\-file <keyfile>
.br
\fIloopaesOpen\fR <device> <name> \-\-key-file <keyfile> (\fBold syntax\fR)
\fIloopaesOpen\fR <device> <name> \-\-key\-file <keyfile> (\fBold syntax\fR)
.IP
Opens the loop-AES <device> and sets up a mapping <name>.
If the key file is encrypted with GnuPG, then you have to use
\-\-key-file=- and decrypt it before use, e.g. like this:
\-\-key\-file=\- and decrypt it before use, e.g. like this:
.br
gpg \-\-decrypt <keyfile> | cryptsetup loopaesOpen \-\-key-file=- <device> <name>
gpg \-\-decrypt <keyfile> | cryptsetup loopaesOpen \-\-key\-file=\-
<device> <name>
Use \fB\-\-keyfile-size\fR to specify the proper key length if needed.
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
need to be specified in number of 512 byte sectors.
@@ -381,8 +401,8 @@ Use \fB\-\-hash\fR to override the default hash function for
passphrase hashing (otherwise it is detected according to key
size).
\fB<options>\fR can be [\-\-key-file, \-\-key-size, \-\-offset, \-\-skip,
\-\-hash, \-\-readonly, \-\-allow-discards].
\fB<options>\fR can be [\-\-key\-file, \-\-key\-size, \-\-offset, \-\-skip,
\-\-hash, \-\-readonly, \-\-allow\-discards].
.PP
See also section 7 of the FAQ and \fBhttp://loop-aes.sourceforge.net\fR
for more information regarding loop-AES.
@@ -412,39 +432,68 @@ The \fBtcryptDump\fR command should work for all recognized TCRYPT devices
and doesn't require superuser privilege.
To map system device (device with boot loader where the whole encrypted
system resides) use \fB\-\-tcrypt-system\fR option. Use the whole
device not the system partition as the device parameter.
system resides) use \fB\-\-tcrypt\-system\fR option.
You can use partition device as the parameter (parameter must be real partition
device, not image in file), then only this partition is mapped.
If you have whole TCRYPT device as a file image and you want to map multiple
partition encrypted with system encryption, please create loopback mapping
with partitions first (\fBlosetup -P\fR, see \fPlosetup(8)\fR man page for more info),
and use loop partition as the device parameter.
If you use whole base device as parameter, one device for the whole system
encryption is mapped. This mode is available only for backward compatibility
with older cryptsetup versions which mapped TCRYPT system encryption
using whole device.
To use hidden header (and map hidden device, if available),
use \fB\-\-tcrypt-hidden\fR option.
use \fB\-\-tcrypt\-hidden\fR option.
To explicitly use backup (secondary) header, use \fB\-\-tcrypt\-backup\fR
option.
\fBNOTE:\fR There is no protection for a hidden volume if
the outer volume is mounted. The reason is that if there
were any protection, it would require some metadata describing
what to protect in the outer volume and the hidden volume would
become detectable.
.PP
\fIopen\fR \-\-type tcrypt <device> <name>
.br
\fItcryptOpen\fR <device> <name> (\fBold syntax\fR)
.IP
Opens the TCRYPT (a TrueCrypt-compatible) <device> and sets up a mapping <name>.
Opens the TCRYPT (a TrueCrypt-compatible) <device> and sets up
a mapping <name>.
\fB<options>\fR can be [\-\-key-file, \-\-tcrypt-hidden, \-\-tcrypt-system,
\-\-readonly, \-\-test-passphrase].
\fB<options>\fR can be [\-\-key\-file, \-\-tcrypt\-hidden,
\-\-tcrypt\-system, \-\-tcrypt\-backup, \-\-readonly, \-\-test\-passphrase,
\-\-allow-discards].
The keyfile parameter allows combination of file content with the
passphrase and can be repeated. Note that using keyfiles is compatible
with TCRYPT and is different from LUKS keyfile logic.
\fBWARNING:\fR Option \fB\-\-allow\-discards\fR cannot be combined with
option \fB\-\-tcrypt\-hidden\fR. For normal mapping it can cause
\fBdestruction of hidden volume\fR (hidden volume appears as unused space
for outer volume so this space can be discarded).
.PP
\fItcryptDump\fR <device>
.IP
Dump the header information of a TCRYPT device.
If the \-\-dump-master-key option is used, the TCRYPT device master key is
dumped instead of TCRYPT header info. Beware that the master key
If the \-\-dump\-master\-key option is used, the TCRYPT device master key
is dumped instead of TCRYPT header info. Beware that the master key
(or concatenated master keys if cipher chain is used)
can be used to decrypt the data stored in the TCRYPT container without
a passphrase.
This means that if the master key is compromised, the whole device has
to be erased to prevent further access. Use this option carefully.
\fB<options>\fR can be [\-\-dump-master-key, \-\-key-file, \-\-tcrypt-hidden,
\-\-tcrypt-system].
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
\-\-tcrypt\-hidden, \-\-tcrypt\-system, \-\-tcrypt\-backup].
The keyfile parameter allows combination of file content with the
passphrase and can be repeated.
@@ -475,7 +524,7 @@ Benchmarks ciphers and KDF (key derivation function).
Without parameters it tries to measure few common configurations.
To benchmark other ciphers or modes, you need to specify \fB\-\-cipher\fR
and \fB\-\-key-size\fR options or \fB\-\-hash\fR for KDF test.
and \fB\-\-key\-size\fR options or \fB\-\-hash\fR for KDF test.
\fBNOTE:\fR This benchmark is using memory only and is only informative.
You cannot directly predict real storage encryption speed from it.
@@ -486,7 +535,7 @@ If you are configuring kernel yourself, enable
"User-space interface for symmetric key cipher algorithms" in
"Cryptographic API" section (CRYPTO_USER_API_SKCIPHER .config option).
\fB<options>\fR can be [\-\-cipher, \-\-key-size, \-\-hash].
\fB<options>\fR can be [\-\-cipher, \-\-key\-size, \-\-hash].
.SH OPTIONS
.TP
.B "\-\-verbose, \-v"
@@ -496,15 +545,17 @@ Print more information on command execution.
Run in debug mode with full diagnostic logs. Debug output
lines are always prefixed by '#'.
.TP
.B "\-\-hash, \-h \fI<hash-spec>\fR"
Specifies the passphrase hash for \fIopen\fR (for plain and loopaes device types).
.B "\-\-hash, \-h \fI<hash\-spec>\fR"
Specifies the passphrase hash for \fIopen\fR (for plain and
loopaes device types).
Specifies the hash used in the LUKS key setup scheme and volume key digest
for \fIluksFormat\fR.
for \fIluksFormat\fR. The specified hash is used as hash-parameter
for PBKDF2 and for the AF splitter.
The specified hash name is passed to the compiled-in crypto backend.
Different backends may support different hashes.
For \fIluksFormat\fR, the hash
For \fIluksFormat\fR, the hash
algorithm must provide at least 160 bits of output, which
excludes, e.g., MD5. Do not use a non-crypto hash like
\fB"crc32"\fR as this breaks security.
@@ -515,16 +566,20 @@ Values compatible with old version of cryptsetup are
Use \fIcryptsetup \-\-help\fR to show the defaults.
.TP
.B "\-\-cipher, \-c \fI<cipher-spec>\fR"
.B "\-\-cipher, \-c \fI<cipher\-spec>\fR"
Set the cipher specification string.
\fIcryptsetup \-\-help\fR shows the compiled-in defaults.
The current default in the distributed sources is
"aes-cbc-essiv:sha256" for both plain dm-crypt and LUKS.
"aes-cbc-essiv:sha256" for plain dm-crypt and
"aes-xts-plain64" for LUKS.
For XTS mode (a possible future default), use "aes-xts-plain"
or better "aes-xts-plain64"
as cipher specification and optionally set a key size of
If a hash is part of the cipher spefification, then it is
used as part of the IV generation. For example, ESSIV
needs a hash function, while "plain64" does not and
hence none is specified.
For XTS mode you can optionally set a key size of
512 bits with the \-s option. Key size for XTS
mode is twice that for other modes for the same
security level.
@@ -536,7 +591,7 @@ kernel 2.6.33 or later. More information can be found in the FAQ.
When interactively asking for a passphrase, ask for it twice
and complain if both inputs do not match. Advised when creating
a regular mapping for the first time, or when running
\fIluksFormat\fR. Ignores on input from file or stdin.
\fIluksFormat\fR. Ignored on input from file or stdin.
.TP
.B "\-\-key-file, \-d \fIname\fR"
Read the passphrase from file.
@@ -544,9 +599,9 @@ Read the passphrase from file.
If the name given is "-", then the passphrase will be read from stdin.
In this case, reading will not stop at newline characters.
With LUKS, passphrases supplied via \-\-key-file are always
With LUKS, passphrases supplied via \-\-key\-file are always
the existing passphrases requested by a command, except in
the case of \fIluksFormat\fR where \-\-key-file is equivalent
the case of \fIluksFormat\fR where \-\-key\-file is equivalent
to the positional key file argument.
If you want to set a new passphrase via key file, you have to
@@ -554,37 +609,37 @@ use a positional argument to \fIluksAddKey\fR.
See section \fBNOTES ON PASSPHRASE PROCESSING\fR for more information.
.TP
.B "\-\-keyfile-offset \fIvalue\fR"
.B "\-\-keyfile\-offset \fIvalue\fR"
Skip \fIvalue\fR bytes at the beginning of the key file.
Works with all commands that accepts key files.
.TP
.B "\-\-keyfile-size, \-l \fIvalue\fR"
.B "\-\-keyfile\-size, \-l \fIvalue\fR"
Read a maximum of \fIvalue\fR bytes from the key file.
Default is to read the whole file up to the compiled-in
maximum that can be queried with \-\-help. Supplying more
data than the compiled-in maximum aborts the operation.
This option is useful
to cut trailing newlines, for example. If \-\-keyfile-offset
to cut trailing newlines, for example. If \-\-keyfile\-offset
is also given, the size count starts after the offset.
Works with all commands that accepts key files.
.TP
.B "\-\-new-keyfile-offset \fIvalue\fR"
.B "\-\-new\-keyfile\-offset \fIvalue\fR"
Skip \fIvalue\fR bytes at the start when
adding a new passphrase from key file with
\fIluksAddKey\fR.
.TP
.B "\-\-new-keyfile-size \fIvalue\fR"
.B "\-\-new\-keyfile\-size \fIvalue\fR"
Read a maximum of \fIvalue\fR bytes when adding
a new passphrase from key file with \fIluksAddKey\fR.
Default is to read the whole file up to the compiled-in
maximum length that can be queried with \-\-help.
Supplying more than the compiled in maximum aborts the
operation.
When \-\-new-keyfile-offset is also given, reading starts
When \-\-new\-keyfile\-offset is also given, reading starts
after the offset.
.TP
.B "\-\-master-key-file"
.B "\-\-master\-key\-file"
Use a master key stored in a file.
For \fIluksFormat\fR this
@@ -594,20 +649,25 @@ LUKS header and all other parameters are the same,
then the new header decrypts the data encrypted with the
header the master key was taken from.
\fBWARNING:\fR If you create your own master key, you
need to make sure to do it right. Otherwise you can end
up with a low-entropy or otherwise partially predictable
master key which will compromise security.
For \fIluksAddKey\fR this allows adding a new passphrase
without having to know an exiting one.
For \fIopen\fR this allows to open the LUKS device
without giving a passphrase.
.TP
.B "\-\-dump-master-key"
.B "\-\-dump\-master\-key"
For \fIluksDump\fR this option includes the master key in the displayed
information. Use with care, as the master key can be used to
bypass the passphrases, see also option \-\-master-key-file.
bypass the passphrases, see also option \-\-master\-key\-file.
.TP
.B "\-\-use-random"
.B "\-\-use\-random"
.TP
.B "\-\-use-urandom"
.B "\-\-use\-urandom"
For \fIluksFormat\fR these options define which kernel random number
generator will be used to create the master key (which is a
long-term key).
@@ -623,7 +683,7 @@ Using /dev/random can block a long time, potentially
forever, if not enough entropy can be harvested by
the kernel.
.TP
.B "\-\-key-slot, \-S <0-7>"
.B "\-\-key\-slot, \-S <0\-7>"
For LUKS operations that add key material, this options allows you
to specify which key slot is selected for the new key.
This option can be used for \fIluksFormat\fR,
@@ -634,7 +694,7 @@ specific key-slot to compare the passphrase against.
If the given passphrase would only match a different key-slot,
the operation fails.
.TP
.B "\-\-key-size, \-s <bits>"
.B "\-\-key\-size, \-s <bits>"
Sets key size in bits. The argument has to be a multiple of
8. The possible key-sizes are limited by the cipher and
mode used.
@@ -657,17 +717,14 @@ This option is only relevant for the \fIopen\fR action with plain
or loopaes device types.
.TP
.B "\-\-skip, \-p <number of 512 byte sectors>"
How many sectors of the encrypted data to skip at the beginning.
Start offset used in IV calculation in 512-byte sectors
(how many sectors of the encrypted data to skip at the beginning).
This option is only relevant for the \fIopen\fR action with plain
or loopaes device types.
This is different from the \-\-offset options with respect to
the sector numbers used in IV calculation.
Using \-\-offset will shift the IV calculation by the same negative amount.
Hence, if \-\-offset \fIn\fR, sector \fIn\fR will get a sector
number of \fI0\fR for the IV calculation.
Using \-\-skip causes sector \fIn\fR to also be the first sector
of the mapped device, but with its number for IV generation is \fIn\fR.
Hence, if \-\-offset \fIn\fR, and \-\-skip \fIs\fR, sector \fIn\fR
(the first sector of encrypted device) will get a sector number
of \fIs\fR for the IV calculation.
.TP
.B "\-\-readonly, \-r"
set up a read-only mapping.
@@ -675,17 +732,17 @@ set up a read-only mapping.
.B "\-\-shared"
Creates an additional mapping for one common
ciphertext device. Arbitrary mappings are supported.
This option is only relevant for the
This option is only relevant for the
\fIopen \-\-type plain\fR action. Use \-\-offset, \-\-size and \-\-skip to
specify the mapped area.
.TP
.B "\-\-iter-time, \-i <number of milliseconds>"
.B "\-\-iter\-time, \-i <number of milliseconds>"
The number of milliseconds to spend with PBKDF2 passphrase processing.
This option is only relevant for LUKS operations that set or change
passphrases, such as \fIluksFormat\fR or \fIluksAddKey\fR.
Specifying 0 as parameter selects the compiled-in default.
.TP
.B "\-\-batch-mode, \-q"
.B "\-\-batch\-mode, \-q"
Suppresses all confirmation questions. Use with care!
If the \-y option is not specified, this option also switches off
@@ -697,7 +754,7 @@ via terminal. It is relevant every time a passphrase is asked,
for example for \fIopen\fR, \fIluksFormat\fR or \fIluksAddKey\fR.
It has no effect if used in conjunction with \-\-key-file.
.br
This option is useful when the system
This option is useful when the system
should not stall if the user does not input a passphrase,
e.g. during boot. The default is a value of 0 seconds,
which means to wait forever.
@@ -709,7 +766,7 @@ every time a passphrase is asked, for example for
\fIopen\fR, \fIluksFormat\fR or \fIluksAddKey\fR.
The default is 3 tries.
.TP
.B "\-\-align-payload <number of 512 byte sectors>"
.B "\-\-align\-payload <number of 512 byte sectors>"
Align payload at a boundary of \fIvalue\fR 512-byte sectors.
This option is relevant for \fIluksFormat\fR.
@@ -729,7 +786,7 @@ used with the \fIluksUUID\fR command.
The UUID must be provided in the standard UUID format,
e.g. 12345678-1234-1234-1234-123456789abc.
.TP
.B "\-\-allow-discards\fR"
.B "\-\-allow\-discards\fR"
Allow the use of discard (TRIM) requests for device.
This option is only relevant for \fIopen\fR action.
@@ -743,7 +800,7 @@ later. If in doubt, do no use it.
A kernel version of 3.1 or later is needed. For earlier kernels
this option is ignored.
.TP
.B "\-\-test-passphrase\fR"
.B "\-\-test\-passphrase\fR"
Do not activate device, just verify passphrase.
This option is only relevant for \fIopen\fR action (the device
mapping name is not mandatory if this option is used).
@@ -753,7 +810,7 @@ Use a detached (separated) metadata device or file where the
LUKS header is stored. This options allows to store ciphertext
and LUKS header on different devices.
This option is only relevant for LUKS devices and can be
This option is only relevant for LUKS devices and can be
used with the \fIluksFormat\fR, \fIopen\fR, \fIluksSuspend\fR,
\fIluksResume\fR, \fIstatus\fR and \fIresize\fR commands.
@@ -765,7 +822,7 @@ For other commands that change the LUKS header (e.g. \fIluksAddKey\fR),
specify the device or file with the LUKS header directly as the
LUKS device.
If used with \fIluksFormat\fR, the \-\-align-payload option is taken
If used with \fIluksFormat\fR, the \-\-align\-payload option is taken
as absolute sector alignment on ciphertext device and can be zero.
\fBWARNING:\fR There is no check whether the ciphertext device specified
@@ -773,7 +830,7 @@ actually belongs to the header given. In fact you can specify an
arbitrary device as the ciphertext device for \fIopen\fR
with the \-\-header option. Use with care.
.TP
.B "\-\-force-password\fR"
.B "\-\-force\-password\fR"
Do not use password quality checking for new LUKS passwords.
This option applies only to \fIluksFormat\fR, \fIluksAddKey\fR and
@@ -806,7 +863,7 @@ low-entropy passphrases are easy to attack in plain mode.
first newline, i.e. '\\n'.
The input without the newline character is processed 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.
\fBFrom stdin\fR: Reading will continue until a newline (or until
@@ -831,7 +888,7 @@ directly specifying a binary key.
No warning will be given if the amount of data read from stdin is
less than the key size.
\fBFrom a key file\fR: It will be truncated to the
\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
@@ -849,13 +906,13 @@ the newline character.
\fBFrom stdin\fR:
LUKS will read passphrases from stdin up to the
first newline character or the compiled-in
maximum key file length. If \-\-keyfile-size is
maximum key file length. If \-\-keyfile\-size is
given, it is ignored.
\fBFrom key file\fR:
The complete keyfile is read up to the compiled-in
maximum size. Newline characters do not terminate the
input. The \-\-keyfile-size option can be used to limit
input. The \-\-keyfile\-size option can be used to limit
what is read.
\fBPassphrase processing\fR:
@@ -869,7 +926,12 @@ used key length, higher iteration times will not increase security.
The default setting of one second is sufficient for most
practical cases. The only exception is a low-entropy
passphrase used on a slow device.
passphrase used on a device with a slow CPU, as this will
result in a low iteration count. On a slow device it may
be advisable to increase the iteration time using the
\-\-iter\-time option in order to obtain a higher
iteration count. This does slow down all later luksOpen
operations accordingly.
.SH INCOHERENT BEHAVIOR FOR INVALID PASSPHRASES/KEYS
LUKS checks for a valid passphrase when an encrypted partition
is unlocked. The behavior of plain dm-crypt is different.
@@ -905,12 +967,12 @@ and for wiping deleted keyslots.
The second type is used for the volume (master) key. You can switch
between using /dev/random and /dev/urandom here, see
\fP\-\-use-random\fR and \fP\-\-use-urandom\fR
\fP\-\-use\-random\fR and \fP\-\-use\-urandom\fR
options. Using /dev/random on a system without enough entropy sources
can cause \fPluksFormat\fR to block until the requested amount of
random data is gathered. In a low-entropy situation (embedded system),
this can take a very long time and potentially forever. At the same
time, using /dev/urandom in a low-entropy situation will
time, using /dev/urandom in a low-entropy situation will
produce low-quality keys. This is a serious problem, but solving
it is out of scope for a mere man-page.
See \fPurandom(4)\fR for more information.
@@ -956,9 +1018,9 @@ Copyright \(co 2004-2006 Clemens Fruhwirth
.br
Copyright \(co 2009-2012 Red Hat, Inc.
.br
Copyright \(co 2009-2012 Milan Broz
Copyright \(co 2009-2014 Milan Broz
.br
Copyright \(co 2012 Arno Wagner
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.

View File

@@ -1,4 +1,4 @@
.TH VERITYSETUP "8" "June 2012" "veritysetup" "Maintenance Commands"
.TH VERITYSETUP "8" "December 2013" "veritysetup" "Maintenance Commands"
.SH NAME
veritysetup - manage dm-verity (block level verification) volumes
.SH SYNOPSIS
@@ -130,7 +130,9 @@ The first implementation of veritysetup was written by Chrome OS authors.
This version is based on verification code written by Mikulas Patocka <mpatocka@redhat.com>
and rewritten for libcryptsetup by Milan Broz <gmazyland@gmail.com>.
.SH COPYRIGHT
Copyright \(co 2012 Red Hat, Inc.
Copyright \(co 2012-2013 Red Hat, Inc.
.br
Copyright \(co 2012-2013 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.

17
misc/11-dm-crypt.rules Normal file
View File

@@ -0,0 +1,17 @@
# Old udev rules historically used in device-mapper.
# No need to install these until you have some weird configuration.
# (Code internally set the same flags.)
ACTION!="add|change", GOTO="crypt_end"
ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="crypt_end"
ENV{DM_UUID}=="CRYPT-TEMP-?*", GOTO="crypt_disable"
ENV{DM_UUID}!="?*", ENV{DM_NAME}=="temporary-cryptsetup-?*", GOTO="crypt_disable"
GOTO="crypt_end"
LABEL="crypt_disable"
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}="1"
ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1"
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
LABEL="crypt_end"

View File

@@ -2,13 +2,28 @@ Example of simple dracut module for reencryption of system
LUKS drive on-the-fly.
Install in /usr/[share|lib]/dracut/modules.d/90reencrypt, then
rebuild intramfs "with dracut -f -a reencrypt".
build special intramfs "with dracut -a reencrypt -o crypt".
Reencrypt module doesn't work (has a conflict) with crypt module as
of now. After successfull reencryption reboot using original initramfs.
Dracut then recognize argument rd_REENCRYPT=name:size,
e.g. rd_REENCRYPT=sda2:52G means only 52G of device
Dracut then recognize argument rd.luks.reencrypt=name:size,
e.g. rd.luks.reencrypt=sda2:52G means only 52G of device
will be reencrypted (default is whole device).
(Name is kernel name of device.)
Also, you may specify keyslot which you want to use for reencryption,
rd.luks.reencrypt_keyslot=<keyslot_number>. Bear in mind that if you
use this option, all other keyslots will be deactivated.
Another argument, rd.luks.reencrypt_key=/dev/sda:/path/to/keyfile
can be used to read password for specific keyslot from device containing
filesystem with a keyfile (file with a password). If you omit reencrypt_key
argument, reencryption would work only in case a LUKS container has
exactly one keyslot activated.
Arguments rd.luks.reencrypt_keyslot and rd.luks.reencrypt_key are not
mandatory.
Note that reencryption context is stored in ramdisk, any
fail can mean complete lost of data!

View File

@@ -7,16 +7,23 @@ check() {
depends() {
echo dm rootfs-block
return 0
}
installkernel() {
instmods dm_crypt =crypto
# requires hostonly='' override so that loop module is pulled in initramfs
# even if not loaded in actual kernel. dracut bug?
hostonly='' instmods dm_crypt =crypto loop
}
install() {
if dracut_module_included crypt; then
derror "'reencrypt' can't be installed together with 'crypt'."
derror "Add '-o crypt' option to install reencrypt module."
return 1
fi
dracut_install cryptsetup-reencrypt
inst_hook cmdline 30 "$moddir/parse-reencrypt.sh"
inst_simple "$moddir"/reencrypt.sh /sbin/reencrypt
}
}

View File

@@ -1,14 +1,19 @@
#!/bin/sh
REENC=$(getargs rd_REENCRYPT=)
REENC=$(getargs rd.luks.reencrypt=)
REENC_DEV=$(echo $REENC | sed 's/:.*//')
REENC_SIZE=$(echo $REENC | sed -n 's/.*://p')
REENC_KEY=$(getargs rd_REENCRYPT_KEY=)
REENC_KEY=$(getargs rd.luks.reencrypt_key=)
if [ -z "$REENC_KEY" ] ; then
REENC_KEY=none
fi
REENC_SLOT=$(getargs rd.luks.reencrypt_keyslot=)
if [ -z "$REENC_SLOT" ] ; then
REENC_SLOT=any
fi
if [ -n "$REENC_DEV" ] ; then
{
printf 'SUBSYSTEM!="block", GOTO="reenc_end"\n'
@@ -16,7 +21,7 @@ if [ -n "$REENC_DEV" ] ; then
printf 'KERNEL!="%s", GOTO="reenc_end"\n' $REENC_DEV
printf 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue \
--unique --onetime --name crypt-reencrypt-%%k \
/sbin/reencrypt $env{DEVNAME} %s"\n' "$REENC_KEY $REENC_SIZE"
/sbin/reencrypt $env{DEVNAME} %s"\n' "$REENC_KEY $REENC_SLOT $REENC_SIZE"
printf 'LABEL="reenc_end"\n'
} > /etc/udev/rules.d/69-reencryption.rules
fi

View File

@@ -1,10 +1,12 @@
#!/bin/sh
#
# $1=$device [$2=keyfile|none [$3=size]]
# $1=$device [$2=keyfile|none [$3=keyslot|any [$4=size]]]
#
[ -d /sys/module/dm_crypt ] || modprobe dm_crypt
[ -d /sys/module/loop ] || modprobe loop
[ -f /tmp/reencrypted ] && exit 0
. /lib/dracut-lib.sh
@@ -17,8 +19,12 @@ else
fi
PARAMS="$device -T 1 --use-fsync -B 32"
if [ -n "$3" ]; then
PARAMS="$PARAMS --device-size $3"
if [ "$3" != "any" ]; then
PARAMS="$PARAMS -S $3"
fi
if [ -n "$4" ]; then
PARAMS="$PARAMS --device-size $4"
fi
reenc_readkey() {
@@ -34,25 +40,40 @@ reenc_readkey() {
reenc_run() {
local cwd=$(pwd)
local _prompt="LUKS password for REENCRYPTING $device"
cd /tmp
if [ "$1" = "none" ] ; then
if [ "$2" != "any" ]; then
_prompt="$_prompt, using keyslot $2"
fi
/bin/plymouth ask-for-password \
--prompt "LUKS password for REENCRYPTING $device" \
--prompt "$_prompt" \
--command="/sbin/cryptsetup-reencrypt $PARAMS"
else
info "REENCRYPT using key $1"
reenc_readkey "$1" | /sbin/cryptsetup-reencrypt -d - $PARAMS
fi
_ret=$?
cd $cwd
}
info "REENCRYPT $device requested"
# flock against other interactive activities
{ flock -s 9;
reenc_run $2
} 9>/.console.lock
reenc_run $2 $3
} 9>/.console_lock
# do not ask again
>> /tmp/reencrypted
if [ $_ret -eq 0 ]; then
# do not ask again
>> /tmp/reencrypted
warn "Reencryption of device $device has finished successfully. Use previous"
warn "initramfs image (without reencrypt module) to boot the system. When"
warn "you leave the emergency shell, the system will reboot."
exit 0
emergency_shell -n "(reboot)"
[ -x /usr/bin/systemctl ] && /usr/bin/systemctl reboot
[ -x /sbin/shutdown ] && /sbin/shutdown -r now
fi
# panic the kernel otherwise
exit 1

View File

@@ -12,8 +12,10 @@ Installation
============
1. Install the version of cryptsetup the tool came with.
2. Compile with
gcc -lm -lcryptsetup chk_luks_keyslots.c -o chk_luks_keyslots
2. Compile with "make"
Manual compile can be done with
gcc -lm -lcryptsetup chk_luks_keyslots.c -o chk_luks_keyslots
Usage
=====
@@ -21,8 +23,8 @@ Usage
Call chk_luks_keyslots without arguments for an option summary.
Example of a good keyslot area:
-------------------------------
Example of a good keyslot area with keys 0 and 2 in use:
--------------------------------------------------------
root> ./chk_luks_keyslots /dev/loop0
@@ -31,17 +33,17 @@ parameters (commandline and LUKS header):
threshold: 0.900000
- processing keyslot 0: start: 0x001000 end: 0x020400
- processing keyslot 1: start: 0x021000 end: 0x040400
- processing keyslot 1: keyslot not in use
- processing keyslot 2: start: 0x041000 end: 0x060400
- processing keyslot 3: start: 0x061000 end: 0x080400
- processing keyslot 4: start: 0x081000 end: 0x0a0400
- processing keyslot 5: start: 0x0a1000 end: 0x0c0400
- processing keyslot 6: start: 0x0c1000 end: 0x0e0400
- processing keyslot 7: start: 0x0e1000 end: 0x100400
- processing keyslot 3: keyslot not in use
- processing keyslot 4: keyslot not in use
- processing keyslot 5: keyslot not in use
- processing keyslot 6: keyslot not in use
- processing keyslot 7: keyslot not in use
Example of a fault in slot 8 at offset 0x100200:
-----------------------------
Same example of a fault in slot 2 at offset 0x50000:
----------------------------------------------------
root>./chk_luks_keyslots /dev/loop2
@@ -50,14 +52,14 @@ parameters (commandline and LUKS header):
threshold: 0.900000
- processing keyslot 0: start: 0x001000 end: 0x020400
- processing keyslot 1: start: 0x021000 end: 0x040400
- processing keyslot 1: keyslot not in use
- processing keyslot 2: start: 0x041000 end: 0x060400
- processing keyslot 3: start: 0x061000 end: 0x080400
- processing keyslot 4: start: 0x081000 end: 0x0a0400
- processing keyslot 5: start: 0x0a1000 end: 0x0c0400
- processing keyslot 6: start: 0x0c1000 end: 0x0e0400
- processing keyslot 7: start: 0x0e1000 end: 0x100400
low entropy at: 0x100200 entropy: 0.846546
low entropy at: 0x050000 entropy: 0.549165
- processing keyslot 3: keyslot not in use
- processing keyslot 4: keyslot not in use
- processing keyslot 5: keyslot not in use
- processing keyslot 6: keyslot not in use
- processing keyslot 7: keyslot not in use
Same as last, but verbose:
@@ -69,48 +71,48 @@ parameters (commandline and LUKS header):
threshold: 0.900000
- processing keyslot 0: start: 0x001000 end: 0x020400
- processing keyslot 1: start: 0x021000 end: 0x040400
- processing keyslot 1: keyslot not in use
- processing keyslot 2: start: 0x041000 end: 0x060400
- processing keyslot 3: start: 0x061000 end: 0x080400
- processing keyslot 4: start: 0x081000 end: 0x0a0400
- processing keyslot 5: start: 0x0a1000 end: 0x0c0400
- processing keyslot 6: start: 0x0c1000 end: 0x0e0400
- processing keyslot 7: start: 0x0e1000 end: 0x100400
low entropy at: 0x100200 entropy: 0.846546
low entropy at: 0x050000 entropy: 0.549165
Binary dump:
0x100200 BD 0E C7 A8 7D EF 04 F6 AF 83 DF 74 94 FE 04 56 ....}......t...V
0x100210 3B 64 BD 68 A9 F6 CF 3C 37 CD 66 B7 17 4D 63 2B ;d.h...<7.f..Mc+
0x100220 8F 6E 74 7E 96 7A 2B 27 32 1B F0 80 37 5A 9A 41 .nt~.z+'2...7Z.A
0x100230 4A 6E CB C0 CF 39 95 45 92 90 E1 0B E6 08 EE 2A Jn...9.E.......*
0x100240 FA 66 6D 67 49 89 76 B1 41 CD 24 57 AA 65 F7 69 .fmgI.v.A.$W.e.i
0x100250 33 16 A7 C7 61 3D 43 B7 74 D6 86 83 1D 19 BF 85 3...a=C.t.......
0x100260 E4 22 3E 16 66 1C B0 1E 11 0D D4 26 37 AD A4 02 .">.f......&7...
0x100270 40 77 9A 5A B8 40 39 E3 A3 A0 96 08 4D 57 C5 0C @w.Z.@9.....MW..
0x100280 D4 74 89 45 FA 93 F7 FE A7 9D D3 99 43 77 8E 35 .t.E........Cw.5
0x100290 E0 55 90 3E 91 29 EA DB 5C 13 19 C9 83 CE D8 0C .U.>.)..\.......
0x1002a0 85 7F 96 26 60 16 A0 0B E1 F9 01 13 1E 59 83 98 ...&`........Y..
0x1002b0 06 B5 1D 6F B6 81 9D 60 58 70 15 30 29 42 32 C6 ...o...`Xp.0)B2.
0x1002c0 A7 55 64 00 65 ED 41 1C B4 C1 C7 10 E1 8E 60 B0 .Ud.e.A.......`.
0x1002d0 F0 9E 9C 40 5A 84 92 8D 21 F0 B8 2D 61 4E 21 9D ...@Z...!..-aN!.
0x1002e0 FA B8 18 D3 47 A4 4F D4 AB 73 C0 93 F3 8E 9A 95 ....G.O..s......
0x1002f0 A4 F1 6D EB 36 85 F4 F7 62 BA 26 D5 15 57 0D 0C ..m.6...b.&..W..
0x100300 C9 4E 19 F2 5B 5A F5 54 B8 F4 B5 57 72 08 1B 7A .N..[Z.T...Wr..z
0x100310 C3 66 7F 82 1E 75 92 C2 E9 97 64 5E F7 FB A9 05 .f...u....d^....
0x100320 CF 30 C8 6A D1 35 9B 9D 22 52 22 46 0E 4B DE 53 .0.j.5.."R"F.K.S
0x100330 68 C8 DA 5F C7 CA 31 D0 C9 B4 57 CF 0F 1F 4B 9C h.._..1...W...K.
0x100340 DF 0C F8 7C F2 E3 32 52 3C 0D D2 DC 5C CF F0 00 ...|..2R<...\...
0x100350 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
0x100360 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
0x100370 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
0x100380 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
0x100390 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
0x1003a0 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
0x1003b0 B4 81 7A F0 BE 38 7E 00 A4 61 41 06 ED 7B 40 D9 ..z..8~..aA..{@.
0x1003c0 BF 58 51 C9 CD 37 78 4D 4D B3 6E B4 7D 86 3C CB .XQ..7xMM.n.}.<.
0x1003d0 D5 39 2E FC 78 B1 3E DE C0 7F 55 25 65 71 AD 2A .9..x.>...U%eq.*
0x1003e0 1E 68 D3 3B 78 17 5F D2 08 93 50 88 D8 0A 75 4F .h.;x._...P...uO
0x1003f0 E5 AA 26 0F B4 F7 F5 88 65 2B E4 92 18 08 32 9E ..&.....e+....2.
0x050000 54 68 69 73 20 69 73 20 61 20 74 65 73 74 2D 73 This is a test-s
0x050010 65 63 74 6F 72 20 66 6F 72 20 63 68 6B 5F 6C 75 ector for chk_lu
0x050020 6B 73 5F 6B 65 79 73 6C 6F 74 73 20 74 68 65 20 ks_keyslots the
0x050030 71 75 69 63 6B 20 62 72 6F 77 6E 20 66 6F 78 20 quick brown fox
0x050040 6A 75 6D 70 73 20 6F 76 65 72 20 74 68 65 20 6C jumps over the l
0x050050 61 7A 79 20 64 6F 67 20 74 68 65 20 71 75 69 63 azy dog the quic
0x050060 6B 20 62 72 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 k brown fox jump
0x050070 73 20 6F 76 65 72 20 74 68 65 20 6C 61 7A 79 20 s over the lazy
0x050080 64 6F 67 20 74 68 65 20 71 75 69 63 6B 20 62 72 dog the quick br
0x050090 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 73 20 6F 76 own fox jumps ov
0x0500a0 65 72 20 74 68 65 20 6C 61 7A 79 20 64 6F 67 20 er the lazy dog
0x0500b0 74 68 65 20 71 75 69 63 6B 20 62 72 6F 77 6E 20 the quick brown
0x0500c0 66 6F 78 20 6A 75 6D 70 73 20 6F 76 65 72 20 74 fox jumps over t
0x0500d0 68 65 20 6C 61 7A 79 20 64 6F 67 20 74 68 65 20 he lazy dog the
0x0500e0 71 75 69 63 6B 20 62 72 6F 77 6E 20 66 6F 78 20 quick brown fox
0x0500f0 6A 75 6D 70 73 20 6F 76 65 72 20 74 68 65 20 6C jumps over the l
0x050100 61 7A 79 20 64 6F 67 20 74 68 65 20 71 75 69 63 azy dog the quic
0x050110 6B 20 62 72 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 k brown fox jump
0x050120 73 20 6F 76 65 72 20 74 68 65 20 6C 61 7A 79 20 s over the lazy
0x050130 64 6F 67 20 74 68 65 20 71 75 69 63 6B 20 62 72 dog the quick br
0x050140 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 73 20 6F 76 own fox jumps ov
0x050150 65 72 20 74 68 65 20 6C 61 7A 79 20 64 6F 67 20 er the lazy dog
0x050160 74 68 65 20 71 75 69 63 6B 20 62 72 6F 77 6E 20 the quick brown
0x050170 66 6F 78 20 6A 75 6D 70 73 20 6F 76 65 72 20 74 fox jumps over t
0x050180 68 65 20 6C 61 7A 79 20 64 6F 67 20 74 68 65 20 he lazy dog the
0x050190 71 75 69 63 6B 20 62 72 6F 77 6E 20 66 6F 78 20 quick brown fox
0x0501a0 6A 75 6D 70 73 20 6F 76 65 72 20 74 68 65 20 6C jumps over the l
0x0501b0 61 7A 79 20 64 6F 67 20 74 68 65 20 71 75 69 63 azy dog the quic
0x0501c0 6B 20 62 72 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 k brown fox jump
0x0501d0 73 20 6F 76 65 72 20 74 68 65 20 6C 61 7A 79 20 s over the lazy
0x0501e0 64 6F 67 20 74 68 65 20 71 75 69 63 6B 20 62 72 dog the quick br
0x0501f0 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 73 20 6F 76 own fox jumps ov
- processing keyslot 3: keyslot not in use
- processing keyslot 4: keyslot not in use
- processing keyslot 5: keyslot not in use
- processing keyslot 6: keyslot not in use
- processing keyslot 7: keyslot not in use
----
Copyright (C) 2012, Arno Wagner <arno@wagner.name>

View File

@@ -1,5 +1,6 @@
cs
de
es
fi
fr
id

832
po/cs.po

File diff suppressed because it is too large Load Diff

1772
po/de.po

File diff suppressed because it is too large Load Diff

1769
po/es.po Normal file

File diff suppressed because it is too large Load Diff

702
po/fi.po

File diff suppressed because it is too large Load Diff

838
po/fr.po

File diff suppressed because it is too large Load Diff

1686
po/it.po

File diff suppressed because it is too large Load Diff

730
po/nl.po

File diff suppressed because it is too large Load Diff

1505
po/pl.po

File diff suppressed because it is too large Load Diff

833
po/uk.po

File diff suppressed because it is too large Load Diff

1117
po/vi.po

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
AM_CPPFLAGS = -I$(top_srcdir)/lib $(PYTHON_INCLUDES)
AM_CPPFLAGS = -include $(top_srcdir)/config.h -I$(top_srcdir)/lib $(PYTHON_INCLUDES)
EXTRA_DIST = pycryptsetup-test.py
CLEANFILES = *.img
@@ -9,7 +9,7 @@ pyexec_LTLIBRARIES = pycryptsetup.la
pycryptsetup_la_SOURCES = pycryptsetup.c
pycryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) -fno-strict-aliasing
pycryptsetup_la_LDFLAGS = -avoid-version -module
pycryptsetup_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
pycryptsetup_la_LIBADD = $(top_builddir)/lib/libcryptsetup.la -lpython$(PYTHON_VERSION)
else
all:

View File

@@ -1,4 +1,4 @@
AM_CPPFLAGS = \
AM_CPPFLAGS = -include config.h \
-I$(top_srcdir) \
-I$(top_srcdir)/lib \
-DDATADIR=\""$(datadir)"\" \
@@ -6,8 +6,7 @@ AM_CPPFLAGS = \
-DLIBDIR=\""$(libdir)"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DVERSION=\""$(VERSION)"\" \
-D_GNU_SOURCE
-DVERSION=\""$(VERSION)"\"
# cryptsetup
cryptsetup_SOURCES = \
@@ -25,7 +24,7 @@ cryptsetup_LDADD = \
@FIPSCHECK_LIBS@ \
@PWQUALITY_LIBS@
cryptsetup_CFLAGS = -Wall
cryptsetup_CFLAGS = $(AM_CFLAGS) -Wall
sbin_PROGRAMS=cryptsetup
@@ -33,7 +32,7 @@ if STATIC_TOOLS
sbin_PROGRAMS += cryptsetup.static
cryptsetup_static_SOURCES = $(cryptsetup_SOURCES)
cryptsetup_static_CFLAGS = $(cryptsetup_CFLAGS)
cryptsetup_static_LDFLAGS = -all-static
cryptsetup_static_LDFLAGS = $(AM_LDFLAGS) -all-static
cryptsetup_static_LDADD = $(cryptsetup_LDADD) \
@CRYPTO_STATIC_LIBS@ \
@PWQUALITY_STATIC_LIBS@ \
@@ -63,7 +62,7 @@ if STATIC_TOOLS
sbin_PROGRAMS += veritysetup.static
veritysetup_static_SOURCES = $(veritysetup_SOURCES)
veritysetup_static_CFLAGS = $(veritysetup_CFLAGS)
veritysetup_static_LDFLAGS = -all-static
veritysetup_static_LDFLAGS = $(AM_LDFLAGS) -all-static
veritysetup_static_LDADD = $(veritysetup_LDADD) \
@CRYPTO_STATIC_LIBS@ \
@DEVMAPPER_STATIC_LIBS@ \
@@ -88,7 +87,7 @@ if STATIC_TOOLS
sbin_PROGRAMS += cryptsetup-reencrypt.static
cryptsetup_reencrypt_static_SOURCES = $(cryptsetup_reencrypt_SOURCES)
cryptsetup_reencrypt_static_CFLAGS = $(cryptsetup_reencrypt_CFLAGS)
cryptsetup_reencrypt_static_LDFLAGS = -all-static
cryptsetup_reencrypt_static_LDFLAGS = $(AM_LDFLAGS) -all-static
cryptsetup_reencrypt_static_LDADD = $(cryptsetup_reencrypt_LDADD) \
@CRYPTO_STATIC_LIBS@ \
@DEVMAPPER_STATIC_LIBS@ \

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004, Christophe Saout <christophe@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-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -60,6 +60,7 @@ static int opt_allow_discards = 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 const char **action_argv;
static int action_argc;
@@ -208,6 +209,50 @@ out:
return r;
}
static int tcrypt_load(struct crypt_device *cd, struct crypt_params_tcrypt *params)
{
int r, tries = opt_tries, eperm = 0;
do {
/* TCRYPT header is encrypted, get passphrase now */
r = tools_get_key(_("Enter passphrase: "),
CONST_CAST(char**)&params->passphrase,
&params->passphrase_size, 0, 0, NULL, opt_timeout,
_verify_passphrase(0), 0, cd);
if (r < 0)
continue;
if (opt_tcrypt_hidden)
params->flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
if (opt_tcrypt_system)
params->flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
if (opt_tcrypt_backup)
params->flags |= CRYPT_TCRYPT_BACKUP_HEADER;
r = crypt_load(cd, CRYPT_TCRYPT, params);
if (r == -EPERM) {
log_err(_("No device header detected with this passphrase.\n"));
eperm = 1;
}
if (r < 0) {
crypt_safe_free(CONST_CAST(char*)params->passphrase);
params->passphrase = NULL;
params->passphrase_size = 0;
}
check_signal(&r);
} while (r == -EPERM && (--tries > 0));
/* Report wrong passphrase if at least one try failed */
if (eperm && r == -EPIPE)
r = -EPERM;
return r;
}
static int action_open_tcrypt(void)
{
struct crypt_device *cd = NULL;
@@ -225,33 +270,19 @@ static int action_open_tcrypt(void)
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
/* TCRYPT header is encrypted, get passphrase now */
r = tools_get_key(_("Enter passphrase: "),
CONST_CAST(char**)&params.passphrase,
&params.passphrase_size, 0, 0, NULL, opt_timeout,
_verify_passphrase(0), 0, cd);
if (r < 0)
goto out;
if (opt_tcrypt_hidden)
params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
if (opt_tcrypt_system)
params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
r = crypt_load(cd, CRYPT_TCRYPT, &params);
check_signal(&r);
r = tcrypt_load(cd, &params);
if (r < 0)
goto out;
if (opt_readonly)
flags |= CRYPT_ACTIVATE_READONLY;
if (opt_allow_discards)
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (activated_name)
r = crypt_activate_by_volume_key(cd, activated_name, NULL, 0, flags);
out:
if (r == -EPERM)
log_err(_("No device header detected with this passphrase.\n"));
crypt_free(cd);
crypt_safe_free(CONST_CAST(char*)params.passphrase);
return r;
@@ -312,22 +343,7 @@ static int action_tcryptDump(void)
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
/* TCRYPT header is encrypted, get passphrase now */
r = tools_get_key(_("Enter passphrase: "),
CONST_CAST(char**)&params.passphrase,
&params.passphrase_size, 0, 0, NULL, opt_timeout,
_verify_passphrase(0), 0, cd);
if (r < 0)
goto out;
if (opt_tcrypt_hidden)
params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
if (opt_tcrypt_system)
params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
r = crypt_load(cd, CRYPT_TCRYPT, &params);
check_signal(&r);
r = tcrypt_load(cd, &params);
if (r < 0)
goto out;
@@ -336,8 +352,6 @@ static int action_tcryptDump(void)
else
r = crypt_dump(cd);
out:
if (r == -EPERM)
log_err(_("No device header detected with this passphrase.\n"));
crypt_free(cd);
crypt_safe_free(CONST_CAST(char*)params.passphrase);
return r;
@@ -453,6 +467,29 @@ static int action_benchmark_kdf(const char *hash)
return r;
}
static int benchmark_cipher_loop(const char *cipher, const char *cipher_mode,
size_t volume_key_size, size_t iv_size,
double *encryption_mbs, double *decryption_mbs)
{
int r, buffer_size = 1024 * 1024;
do {
r = crypt_benchmark(NULL, cipher, cipher_mode,
volume_key_size, iv_size, buffer_size,
encryption_mbs, decryption_mbs);
if (r == -ERANGE) {
if (buffer_size < 1024 * 1024 * 65)
buffer_size *= 2;
else {
log_err(_("Result of benchmark is not reliable.\n"));
r = -ENOENT;
}
}
} while (r == -ERANGE);
return r;
}
static int action_benchmark(void)
{
static struct {
@@ -482,7 +519,6 @@ static int action_benchmark(void)
double enc_mbr = 0, dec_mbr = 0;
int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS);
int iv_size = 16, skipped = 0;
int buffer_size = 1024 * 1024;
char *c;
int i, r;
@@ -504,9 +540,9 @@ static int action_benchmark(void)
strstr(cipher, "cast5"))
iv_size = 8;
r = crypt_benchmark(NULL, cipher, cipher_mode,
key_size / 8, iv_size, buffer_size,
&enc_mbr, &dec_mbr);
r = benchmark_cipher_loop(cipher, cipher_mode,
key_size / 8, iv_size,
&enc_mbr, &dec_mbr);
if (!r) {
log_std(N_("# Algorithm | Key | Encryption | Decryption\n"));
log_std("%8s-%s %4db %6.1f MiB/s %6.1f MiB/s\n",
@@ -521,9 +557,9 @@ static int action_benchmark(void)
break;
}
for (i = 0; bciphers[i].cipher; i++) {
r = crypt_benchmark(NULL, bciphers[i].cipher, bciphers[i].mode,
r = benchmark_cipher_loop(bciphers[i].cipher, bciphers[i].mode,
bciphers[i].key_size, bciphers[i].iv_size,
buffer_size, &enc_mbr, &dec_mbr);
&enc_mbr, &dec_mbr);
check_signal(&r);
if (r == -ENOTSUP || r == -EINTR)
break;
@@ -657,7 +693,7 @@ static int action_luksFormat(void)
else if (opt_urandom)
crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);
r = tools_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen,
r = tools_get_key(_("Enter passphrase: "), &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout, _verify_passphrase(1), 1, cd);
if (r < 0)
@@ -828,7 +864,7 @@ static int action_luksKillSlot(void)
if (!opt_batch_mode) {
r = verify_keyslot(cd, opt_key_slot,
_("This is the last keyslot. Device will become unusable after purging this key."),
_("Enter any remaining LUKS passphrase: "),
_("Enter any remaining passphrase: "),
opt_key_file, opt_keyfile_offset, opt_keyfile_size);
if (r < 0)
goto out;
@@ -856,7 +892,7 @@ static int action_luksRemoveKey(void)
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
goto out;
r = tools_get_key(_("Enter LUKS passphrase to be deleted: "),
r = tools_get_key(_("Enter passphrase to be deleted: "),
&password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout,
@@ -925,7 +961,7 @@ static int action_luksAddKey(void)
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 passphrase: "),
r = tools_get_key(_("Enter any existing passphrase: "),
&password, &password_size, 0, 0, NULL,
opt_timeout, _verify_passphrase(0), 0, cd);
@@ -941,7 +977,7 @@ static int action_luksAddKey(void)
r = tools_get_key(_("Enter new passphrase for key slot: "),
&password_new, &password_new_size, 0, 0, NULL,
opt_timeout, _verify_passphrase(0), 1, cd);
opt_timeout, _verify_passphrase(1), 1, cd);
if (r < 0)
goto out;
@@ -974,7 +1010,7 @@ static int action_luksChangeKey(void)
if (opt_iteration_time)
crypt_set_iteration_time(cd, opt_iteration_time);
r = tools_get_key(_("Enter LUKS passphrase to be changed: "),
r = tools_get_key(_("Enter passphrase to be changed: "),
&password, &password_size,
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout, _verify_passphrase(0), 0, cd);
@@ -988,11 +1024,11 @@ static int action_luksChangeKey(void)
if (r < 0)
goto out;
r = tools_get_key(_("Enter new LUKS passphrase: "),
r = tools_get_key(_("Enter new passphrase: "),
&password_new, &password_new_size,
opt_new_keyfile_offset, opt_new_keyfile_size,
opt_new_key_file,
opt_timeout, _verify_passphrase(0), 1, cd);
opt_timeout, _verify_passphrase(1), 1, cd);
if (r < 0)
goto out;
@@ -1010,6 +1046,12 @@ static int action_isLuks(void)
struct crypt_device *cd = NULL;
int r;
/* FIXME: argc > max should be checked for other operations as well */
if (action_argc > 1) {
log_err(_("Only one device argument for isLuks operation is supported.\n"));
return -ENODEV;
}
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
@@ -1067,7 +1109,7 @@ static int luksDump_with_volume_key(struct crypt_device *cd)
if (!vk)
return -ENOMEM;
r = tools_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen,
r = tools_get_key(_("Enter passphrase: "), &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout, 0, 0, cd);
if (r < 0)
@@ -1227,6 +1269,47 @@ args:
return -EINVAL;
}
static int action_luksErase(void)
{
struct crypt_device *cd = NULL;
crypt_keyslot_info ki;
char *msg = NULL;
int i, r;
if ((r = crypt_init(&cd, uuid_or_device(action_argv[0]))))
goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
goto out;
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) {
r = -ENOMEM;
goto out;
}
if (!yesDialog(msg, NULL)) {
r = -EPERM;
goto out;
}
for (i = 0; i < crypt_keyslot_max(CRYPT_LUKS1); i++) {
ki = crypt_keyslot_status(cd, i);
if (ki == CRYPT_SLOT_ACTIVE || ki == CRYPT_SLOT_ACTIVE_LAST) {
r = crypt_keyslot_destroy(cd, i);
if (r < 0)
goto out;
}
}
out:
free(msg);
crypt_free(cd);
return r;
}
static struct action_type {
const char *type;
int (*handler)(void);
@@ -1241,6 +1324,7 @@ static struct action_type {
{ "status", action_status, 1, 0, N_("<name>"), N_("show device status") },
{ "benchmark", action_benchmark, 0, 0, N_("<name>"), N_("benchmark cipher") },
{ "repair", action_luksRepair, 1, 1, N_("<device>"), N_("try to repair on-disk metadata") },
{ "erase", action_luksErase , 1, 1, N_("<device>"), N_("erase all keyslots (remove encryption key)") },
{ "luksFormat", action_luksFormat, 1, 1, N_("<device> [<new key file>]"), N_("formats a LUKS device") },
{ "luksAddKey", action_luksAddKey, 1, 1, N_("<device> [<new key file>]"), N_("add key to LUKS device") },
{ "luksRemoveKey",action_luksRemoveKey,1, 1, N_("<device> [<key file>]"), N_("removes supplied key or key file from LUKS device") },
@@ -1384,6 +1468,7 @@ int main(int argc, const char **argv)
{ "test-passphrase", '\0', POPT_ARG_NONE, &opt_test_passphrase, 0, N_("Do not activate device, just check passphrase."), NULL },
{ "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 },
{ "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 },
POPT_TABLEEND
@@ -1399,7 +1484,8 @@ int main(int argc, const char **argv)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
crypt_fips_self_check(NULL);
if (crypt_fips_mode())
crypt_log(NULL, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
popt_context = poptGetContext(PACKAGE, argc, argv, popt_options, 0);
poptSetOtherOptionHelp(popt_context,
@@ -1490,6 +1576,9 @@ int main(int argc, const char **argv)
!strcmp(aname, "loopaesClose") ||
!strcmp(aname, "tcryptClose")) {
aname = "close";
} else if (!strcmp(aname, "luksErase")) {
aname = "erase";
opt_type = "luks";
}
for(action = action_types; action->type; action++)
@@ -1500,7 +1589,7 @@ int main(int argc, const char **argv)
usage(popt_context, EXIT_FAILURE, _("Unknown action."),
poptGetInvocationName(popt_context));
if(action_argc < action->required_action_argc)
if (action_argc < action->required_action_argc)
help_args(action, popt_context);
/* FIXME: rewrite this from scratch */
@@ -1585,10 +1674,15 @@ int main(int argc, const char **argv)
_("Option --offset is supported only for open of plain and loopaes devices.\n"),
poptGetInvocationName(popt_context));
if ((opt_tcrypt_hidden || opt_tcrypt_system) && strcmp(aname, "tcryptDump") &&
if ((opt_tcrypt_hidden || opt_tcrypt_system || opt_tcrypt_backup) && strcmp(aname, "tcryptDump") &&
(strcmp(aname, "open") || strcmp(opt_type, "tcrypt")))
usage(popt_context, EXIT_FAILURE,
_("Option --tcrypt-hidden or --tcrypt-system is supported only for TCRYPT device.\n"),
_("Option --tcrypt-hidden, --tcrypt-system or --tcrypt-backup is supported only for TCRYPT device.\n"),
poptGetInvocationName(popt_context));
if (opt_tcrypt_hidden && opt_allow_discards)
usage(popt_context, EXIT_FAILURE,
_("Option --tcrypt-hidden cannot be combined with --allow-discards.\n"),
poptGetInvocationName(popt_context));
if (opt_debug) {

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004, Christophe Saout <christophe@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-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -24,11 +24,6 @@
#ifndef CRYPTSETUP_H
#define CRYPTSETUP_H
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

View File

@@ -1,8 +1,8 @@
/*
* cryptsetup-reencrypt - crypt utility for offline re-encryption
*
* Copyright (C) 2012, Milan Broz All rights reserved.
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2014, 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
@@ -47,6 +47,7 @@ static int opt_tries = 3;
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 const char *opt_reduce_size_str = NULL;
static uint64_t opt_reduce_size = 0;
@@ -122,6 +123,12 @@ static int alignment(int fd)
return alignment;
}
static size_t pagesize(void)
{
long r = sysconf(_SC_PAGESIZE);
return r < 0 ? 4096 : (size_t)r;
}
/* Depends on the first two fields of LUKS1 header format, magic and version */
static int device_check(struct reenc_ctx *rc, header_magic set_magic)
{
@@ -129,6 +136,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
int r, devfd;
ssize_t s;
uint16_t version;
size_t buf_size = pagesize();
devfd = open(rc->device, O_RDWR | O_EXCL | O_DIRECT);
if (devfd == -1) {
@@ -146,14 +154,14 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
goto out;
}
if (posix_memalign((void *)&buf, alignment(devfd), SECTOR_SIZE)) {
if (posix_memalign((void *)&buf, alignment(devfd), buf_size)) {
log_err(_("Allocation of aligned memory failed.\n"));
r = -ENOMEM;
goto out;
}
s = read(devfd, buf, SECTOR_SIZE);
if (s < 0 || s != SECTOR_SIZE) {
s = read(devfd, buf, buf_size);
if (s < 0 || s != buf_size) {
log_err(_("Cannot read device %s.\n"), rc->device);
r = -EIO;
goto out;
@@ -184,8 +192,8 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
if (!r) {
if (lseek(devfd, 0, SEEK_SET) == -1)
goto out;
s = write(devfd, buf, SECTOR_SIZE);
if (s < 0 || s != SECTOR_SIZE) {
s = write(devfd, buf, buf_size);
if (s < 0 || s != buf_size) {
log_err(_("Cannot write device %s.\n"), rc->device);
r = -EIO;
}
@@ -193,7 +201,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
log_dbg("LUKS signature check failed for %s.", rc->device);
out:
if (buf)
memset(buf, 0, SECTOR_SIZE);
memset(buf, 0, buf_size);
free(buf);
close(devfd);
return r;
@@ -417,7 +425,8 @@ out:
static int create_new_header(struct reenc_ctx *rc, const char *cipher,
const char *cipher_mode, const char *uuid,
int key_size, struct crypt_params_luks1 *params)
const char *key, int key_size,
struct crypt_params_luks1 *params)
{
struct crypt_device *cd_new = NULL;
int i, r;
@@ -434,7 +443,7 @@ static int create_new_header(struct reenc_ctx *rc, const char *cipher,
crypt_set_iteration_time(cd_new, opt_iteration_time);
if ((r = crypt_format(cd_new, CRYPT_LUKS1, cipher, cipher_mode,
uuid, NULL, key_size, params)))
uuid, key, key_size, params)))
goto out;
log_verbose(_("New LUKS header for device %s created.\n"), rc->device);
@@ -457,6 +466,8 @@ static int backup_luks_headers(struct reenc_ctx *rc)
struct crypt_device *cd = NULL;
struct crypt_params_luks1 params = {0};
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
char *old_key = NULL;
size_t old_key_size;
int r;
log_dbg("Creating LUKS header backup for device %s.", rc->device);
@@ -487,14 +498,30 @@ static int backup_luks_headers(struct reenc_ctx *rc)
}
}
if (opt_keep_key) {
log_dbg("Keeping key from old header.");
old_key_size = crypt_get_volume_key_size(cd);
old_key = crypt_safe_alloc(old_key_size);
if (!old_key) {
r = -ENOMEM;
goto out;
}
r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, old_key, &old_key_size,
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
if (r < 0)
goto out;
}
r = create_new_header(rc,
opt_cipher ? cipher : crypt_get_cipher(cd),
opt_cipher ? cipher_mode : crypt_get_cipher_mode(cd),
crypt_get_uuid(cd),
old_key,
opt_key_size ? opt_key_size / 8 : crypt_get_volume_key_size(cd),
&params);
out:
crypt_free(cd);
crypt_safe_free(old_key);
if (r)
log_err(_("Creation of LUKS backup headers failed.\n"));
return r;
@@ -539,8 +566,8 @@ static int backup_fake_header(struct reenc_ctx *rc)
if (r < 0)
goto out;
r = crypt_keyslot_add_by_volume_key(cd_new, 0, NULL, 0,
rc->p[0].password, rc->p[0].passwordLen);
r = crypt_keyslot_add_by_volume_key(cd_new, rc->keyslot, NULL, 0,
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
if (r < 0)
goto out;
@@ -552,7 +579,7 @@ static int backup_fake_header(struct reenc_ctx *rc)
r = create_new_header(rc,
opt_cipher ? cipher : DEFAULT_LUKS1_CIPHER,
opt_cipher ? cipher_mode : DEFAULT_LUKS1_MODE,
NULL,
NULL, NULL,
(opt_key_size ? opt_key_size : DEFAULT_LUKS1_KEYBITS) / 8,
&params);
out:
@@ -844,15 +871,14 @@ static int initialize_uuid(struct reenc_ctx *rc)
static int init_passphrase1(struct reenc_ctx *rc, struct crypt_device *cd,
const char *msg, int slot_to_check, int check)
{
int r = -EINVAL, slot, retry_count;
slot = (slot_to_check == CRYPT_ANY_SLOT) ? 0 : slot_to_check;
char *password;
int r = -EINVAL, retry_count;
size_t passwordLen;
retry_count = opt_tries ?: 1;
while (retry_count--) {
set_int_handler(0);
r = crypt_get_key(msg, &rc->p[slot].password,
&rc->p[slot].passwordLen,
r = crypt_get_key(msg, &password, &passwordLen,
0, 0, NULL /*opt_key_file*/,
0, 0, cd);
if (r < 0)
@@ -864,42 +890,49 @@ static int init_passphrase1(struct reenc_ctx *rc, struct crypt_device *cd,
set_int_block(1);
if (check)
r = crypt_activate_by_passphrase(cd, NULL, slot_to_check,
rc->p[slot].password, rc->p[slot].passwordLen, 0);
password, passwordLen, 0);
else
r = slot;
r = (slot_to_check == CRYPT_ANY_SLOT) ? 0 : slot_to_check;
if (r < 0) {
crypt_safe_free(rc->p[slot].password);
rc->p[slot].password = NULL;
rc->p[slot].passwordLen = 0;
crypt_safe_free(password);
password = NULL;
passwordLen = 0;
}
if (r < 0 && r != -EPERM)
return r;
if (r >= 0) {
rc->keyslot = slot;
rc->keyslot = r;
rc->p[r].password = password;
rc->p[r].passwordLen = passwordLen;
break;
}
log_err(_("No key available with this passphrase.\n"));
}
password = NULL;
passwordLen = 0;
return r;
}
static int init_keyfile(struct reenc_ctx *rc, struct crypt_device *cd, int slot_check)
{
int r, slot;
char *password;
int r;
size_t passwordLen;
slot = (slot_check == CRYPT_ANY_SLOT) ? 0 : slot_check;
r = crypt_get_key(NULL, &rc->p[slot].password, &rc->p[slot].passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, 0, 0, cd);
r = crypt_get_key(NULL, &password, &passwordLen, opt_keyfile_offset,
opt_keyfile_size, opt_key_file, 0, 0, cd);
if (r < 0)
return r;
r = crypt_activate_by_passphrase(cd, NULL, slot_check,
rc->p[slot].password, rc->p[slot].passwordLen, 0);
r = crypt_activate_by_passphrase(cd, NULL, slot_check, password,
passwordLen, 0);
/*
* Allow keyslot only if it is last slot or if user explicitly
* specify whch slot to use (IOW others will be disabled).
* specify which slot to use (IOW others will be disabled).
*/
if (r >= 0 && opt_key_slot == CRYPT_ANY_SLOT &&
crypt_keyslot_status(cd, r) != CRYPT_SLOT_ACTIVE_LAST) {
@@ -909,14 +942,17 @@ static int init_keyfile(struct reenc_ctx *rc, struct crypt_device *cd, int slot_
}
if (r < 0) {
crypt_safe_free(rc->p[slot].password);
rc->p[slot].password = NULL;
rc->p[slot].passwordLen = 0;
crypt_safe_free(password);
if (r == -EPERM)
log_err(_("No key available with this passphrase.\n"));
return r;
} else
rc->keyslot = slot;
} else {
rc->keyslot = r;
rc->p[r].password = password;
rc->p[r].passwordLen = passwordLen;
}
password = NULL;
passwordLen = 0;
return r;
}
@@ -931,7 +967,7 @@ static int initialize_passphrase(struct reenc_ctx *rc, const char *device)
log_dbg("Passhrases initialization.");
if (opt_new && !rc->in_progress) {
r = init_passphrase1(rc, cd, _("Enter new LUKS passphrase: "), 0, 0);
r = init_passphrase1(rc, cd, _("Enter new passphrase: "), opt_key_slot, 0);
return r > 0 ? 0 : r;
}
@@ -942,17 +978,22 @@ static int initialize_passphrase(struct reenc_ctx *rc, const char *device)
return r;
}
if (opt_key_slot != CRYPT_ANY_SLOT)
snprintf(msg, sizeof(msg),
_("Enter passphrase for key slot %u: "), opt_key_slot);
else
snprintf(msg, sizeof(msg), _("Enter any existing passphrase: "));
if (opt_key_file) {
r = init_keyfile(rc, cd, opt_key_slot);
} else if (rc->in_progress) {
r = init_passphrase1(rc, cd, _("Enter any LUKS passphrase: "),
CRYPT_ANY_SLOT, 1);
} else if (rc->in_progress || opt_key_slot != CRYPT_ANY_SLOT) {
r = init_passphrase1(rc, cd, msg, opt_key_slot, 1);
} else for (i = 0; i < MAX_SLOT; i++) {
ki = crypt_keyslot_status(cd, i);
if (ki != CRYPT_SLOT_ACTIVE && ki != CRYPT_SLOT_ACTIVE_LAST)
continue;
snprintf(msg, sizeof(msg), _("Enter LUKS passphrase for key slot %u: "), i);
snprintf(msg, sizeof(msg), _("Enter passphrase for key slot %u: "), i);
r = init_passphrase1(rc, cd, msg, i, 1);
if (r < 0)
break;
@@ -1066,11 +1107,15 @@ static int run_reencrypt(const char *device)
goto out;
}
if ((r = activate_luks_headers(&rc)))
goto out;
if (!opt_keep_key) {
log_dbg("Running data area reencryption.");
if ((r = activate_luks_headers(&rc)))
goto out;
if ((r = copy_data(&rc)))
goto out;
if ((r = copy_data(&rc)))
goto out;
} else
log_dbg("Keeping existing key, skipping data area reencryption.");
r = restore_luks_header(&rc);
out:
@@ -1109,6 +1154,7 @@ int main(int argc, const char **argv)
{ "cipher", 'c', POPT_ARG_STRING, &opt_cipher, 0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL },
{ "key-size", 's', POPT_ARG_INT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") },
{ "hash", 'h', POPT_ARG_STRING, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL },
{ "keep-key", '\0', POPT_ARG_NONE, &opt_keep_key, 0, N_("Do not change key, no data area reencryption."), NULL },
{ "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 0, N_("Read the key from a file."), NULL },
{ "iter-time", 'i', POPT_ARG_INT, &opt_iteration_time, 0, N_("PBKDF2 iteration time for LUKS (in ms)"), N_("msecs") },
{ "batch-mode", 'q', POPT_ARG_NONE, &opt_batch_mode, 0, N_("Do not ask for confirmation"), NULL },
@@ -1214,6 +1260,10 @@ int main(int argc, const char **argv)
usage(popt_context, EXIT_FAILURE, _("Option --new must be used together with --reduce-device-size."),
poptGetInvocationName(popt_context));
if (opt_keep_key && ((!opt_hash && !opt_iteration_time) || opt_cipher || opt_new))
usage(popt_context, EXIT_FAILURE, _("Option --keep-key can be used only with --hash or --iter-time."),
poptGetInvocationName(popt_context));
if (opt_debug) {
opt_verbose = 1;
crypt_set_debug_level(-1);

View File

@@ -2,7 +2,7 @@
* Password quality check wrapper
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012, Milan Broz
* Copyright (C) 2012-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004, Christophe Saout <christophe@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-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,7 +1,8 @@
/*
* veritysetup - setup cryptographic volumes for dm-verity
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2013, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2013, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -16,6 +16,7 @@ TESTS += reencryption-compat-test
endif
EXTRA_DIST = compatimage.img.bz2 compatv10image.img.bz2 \
img_fs_ext4.img.bz2 img_fs_xfs.img.bz2 \
valid_header_file.bz2 \
evil_hdr-payload_overwrite.bz2 \
evil_hdr-stripes_payload_dmg.bz2 \
@@ -33,12 +34,13 @@ clean-local:
-rm -rf tcrypt-images
differ_SOURCES = differ.c
differ_CFLAGS = -Wall -O2
differ_CFLAGS = $(AM_CFLAGS) -Wall -O2
api_test_SOURCES = api-test.c $(top_srcdir)/lib/utils_loop.c
api_test_LDADD = ../lib/libcryptsetup.la
api_test_LDFLAGS = -static
api_test_CFLAGS = -g -Wall -O0 -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1
api_test_LDFLAGS = $(AM_LDFLAGS) -static
api_test_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1
api_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h
check_PROGRAMS = api-test differ

View File

@@ -3,11 +3,16 @@
CRYPTSETUP="../src/cryptsetup"
DEV=""
DEV_STACKED="luks0xbabe"
MNT_DIR="./mnt_luks"
PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
cleanup() {
udevadm settle >/dev/null 2>&1
if [ -d "$MNT_DIR" ] ; then
umount -f $MNT_DIR 2>/dev/null
rmdir $MNT_DIR 2>/dev/null
fi
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove $DEV_STACKED >/dev/null 2>&1
rmmod scsi_debug 2>/dev/null
sleep 2
@@ -15,12 +20,18 @@ cleanup() {
fail()
{
echo "FAIL"
[ -n "$1" ] && echo "$1"
if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
cleanup
exit 100
}
skip()
{
echo "TEST SKIPPED: $1"
cleanup
exit 0
}
add_device() {
modprobe scsi_debug $@
if [ $? -ne 0 ] ; then
@@ -198,3 +209,18 @@ format_null 512 4040 8
format_null 512 4096 128
format_null 512 4096 2048
cleanup
echo "# Create enterprise-class 4K drive with fs and LUKS images."
# loop device here presents 512 block but images have 4k block
# cryptsetup should properly use 4k block on direct-io
add_device dev_size_mb=16 sector_size=4096 physblk_exp=0 num_tgts=1
for file in $(ls img_fs_*.img.bz2) ; do
echo "Format using fs image $file."
bzip2 -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
mount $DEV $MNT_DIR || skip "Mounting image is not available."
echo $PWD1 | $CRYPTSETUP luksFormat -i 1 $MNT_DIR/luks.img || fail
echo $PWD2 | $CRYPTSETUP luksFormat -i 1 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
umount $MNT_DIR
done
cleanup

View File

@@ -1,8 +1,8 @@
/*
* cryptsetup library API check functions
*
* Copyright (C) 2009-2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2012, Milan Broz
* Copyright (C) 2009-2013 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2013, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -27,6 +27,7 @@
#include <linux/fs.h>
#include <errno.h>
#include <assert.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <libdevmapper.h>
@@ -84,12 +85,16 @@
static int _debug = 0;
static int _verbose = 1;
static int _fips_mode = 0;
static int _quit = 0;
static char global_log[4096];
static int global_lines = 0;
static char *DEVICE_1 = NULL;
static char *DEVICE_2 = NULL;
static char *DEVICE_3 = NULL;
static char *THE_LOOP_DEV = NULL;
static char *tmp_file_1 = NULL;
@@ -114,6 +119,27 @@ static int device_size(const char *device, uint64_t *size)
return r;
}
static int fips_mode(void)
{
int fd;
char buf = 0;
if (access("/etc/system-fips", F_OK))
return 0;
fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY);
if (fd < 0)
return 0;
if (read(fd, &buf, 1) != 1)
buf = '0';
close(fd);
return (buf == '1');
}
static int get_luks_offsets(int metadata_device,
size_t keylength,
unsigned int alignpayload_sec,
@@ -224,7 +250,7 @@ static int _prepare_keyfile(const char *name, const char *passphrase, int size)
{
int fd, r;
fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR);
fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR|S_IWUSR);
if (fd != -1) {
r = write(fd, passphrase, size);
close(fd);
@@ -349,6 +375,9 @@ static void _cleanup(void)
if (crypt_loop_device(DEVICE_2))
crypt_loop_detach(DEVICE_2);
if (crypt_loop_device(DEVICE_3))
crypt_loop_detach(DEVICE_3);
_system("rm -f " IMAGE_EMPTY, 0);
_system("rm -f " IMAGE1, 0);
@@ -369,6 +398,7 @@ static void _cleanup(void)
free(THE_LOOP_DEV);
free(DEVICE_1);
free(DEVICE_2);
free(DEVICE_3);
}
static int _setup(void)
@@ -433,6 +463,12 @@ static int _setup(void)
fd = crypt_loop_attach(DEVICE_2, IMAGE_EMPTY, 0, 0, &ro);
close(fd);
}
if (!DEVICE_3)
DEVICE_3 = crypt_loop_get_device();
if (!DEVICE_3) {
printf("Cannot find free loop device.\n");
return 1;
}
/* Keymaterial offset is less than 8 sectors */
_system(" [ ! -e " EVL_HEADER_1 " ] && bzip2 -dk " EVL_HEADER_1 ".bz2", 1);
/* keymaterial offset aims into payload area */
@@ -451,6 +487,11 @@ static int _setup(void)
_system("modprobe dm-crypt", 0);
_system("modprobe dm-verity", 0);
_fips_mode = fips_mode();
if (_debug)
printf("FIPS MODE: %d\n", _fips_mode);
return 0;
}
@@ -496,6 +537,12 @@ static void xlog(const char *msg, const char *tst, const char *func, int line, c
else
printf(" [%s,%s:%d] %s\n", msg, func, line, tst);
}
if (_quit) {
if (_verbose)
printf("Interrupted by a signal.\n");
_cleanup();
exit(-1);
}
}
/* crypt_device context must be "cd" to parse error properly here */
@@ -505,8 +552,8 @@ static void xlog(const char *msg, const char *tst, const char *func, int line, c
#define FAIL_(x, y) do { xlog("(fail) ", #x, __FUNCTION__, __LINE__, y); \
check_ko((x), __LINE__, __FUNCTION__); \
} while(0)
#define EQ_(x, y) do { xlog("(equal) ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \
int64_t _x = (x), _y = (y); \
#define EQ_(x, y) do { int64_t _x = (x), _y = (y); \
xlog("(equal) ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \
if (_x != _y) check_equal(__LINE__, __FUNCTION__, _x, _y); \
} while(0)
#define RUN_(x, y) do { printf("%s: %s\n", #x, (y)); x(); } while (0)
@@ -760,14 +807,16 @@ static void AddDevicePlain(void)
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
// retrieve volume key check
memset(key2, 0, key_size);
key_size--;
// small buffer
FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)), "small buffer");
key_size++;
OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
if (!_fips_mode) {
memset(key2, 0, key_size);
key_size--;
// small buffer
FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)), "small buffer");
key_size++;
OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
OK_(memcmp(key, key2, key_size));
OK_(memcmp(key, key2, key_size));
}
OK_(strcmp(cipher, crypt_get_cipher(cd)));
OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
EQ_((int)key_size, crypt_get_volume_key_size(cd));
@@ -899,16 +948,18 @@ static void UseLuksDevice(void)
EQ_((int)key_size, crypt_get_volume_key_size(cd));
EQ_(1032, crypt_get_data_offset(cd));
EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1)));
OK_(crypt_volume_key_verify(cd, key, key_size));
OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
if (!_fips_mode) {
EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1)));
OK_(crypt_volume_key_verify(cd, key, key_size));
OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
key[1] = ~key[1];
FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch");
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "key mismatch");
key[1] = ~key[1];
FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch");
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "key mismatch");
}
crypt_free(cd);
}
@@ -1130,10 +1181,12 @@ static void AddDeviceLuks(void)
EQ_(7, crypt_activate_by_passphrase(cd, NULL, 7, passphrase2, strlen(passphrase2), 0));
EQ_(6, crypt_keyslot_change_by_passphrase(cd, CRYPT_ANY_SLOT, 6, passphrase2, strlen(passphrase2), passphrase, strlen(passphrase)));
EQ_(6, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
OK_(crypt_volume_key_verify(cd, key2, key_size));
if (!_fips_mode) {
EQ_(6, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
OK_(crypt_volume_key_verify(cd, key2, key_size));
OK_(memcmp(key, key2, key_size));
OK_(memcmp(key, key2, key_size));
}
OK_(strcmp(cipher, crypt_get_cipher(cd)));
OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
EQ_((int)key_size, crypt_get_volume_key_size(cd));
@@ -1271,8 +1324,8 @@ static void LuksHeaderRestore(void)
// volume key_size mismatch
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
memcpy(key2, key, key_size - 1);
OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key2, key_size - 1, &params));
memcpy(key2, key, key_size / 2);
OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key2, key_size / 2, &params));
FAIL_(crypt_header_restore(cd, CRYPT_LUKS1, VALID_HEADER), "Volume keysize mismatch");
crypt_free(cd);
@@ -1386,6 +1439,7 @@ static void LuksHeaderBackup(void)
.data_alignment = 2048,
};
char key[128];
int fd, ro = O_RDONLY;
const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
size_t key_size = strlen(mk_hex) / 2;
@@ -1393,6 +1447,8 @@ static void LuksHeaderBackup(void)
const char *cipher_mode = "cbc-essiv:sha256";
uint64_t r_payload_offset;
const char *passphrase = PASSPHRASE;
crypt_decode_key(key, mk_hex, key_size);
OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset));
@@ -1402,6 +1458,8 @@ static void LuksHeaderBackup(void)
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
EQ_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), 7);
EQ_(crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, passphrase, strlen(passphrase)), 0);
OK_(crypt_header_backup(cd, CRYPT_LUKS1, BACKUP_FILE));
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
@@ -1415,6 +1473,43 @@ static void LuksHeaderBackup(void)
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
// exercise luksOpen using backup header in file
OK_(crypt_init(&cd, BACKUP_FILE));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
OK_(crypt_init(&cd, BACKUP_FILE));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
// exercise luksOpen using backup header on block device
fd = crypt_loop_attach(DEVICE_3, BACKUP_FILE, 0, 0, &ro);
close(fd);
OK_(fd < 0);
OK_(crypt_init(&cd, DEVICE_3));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
OK_(crypt_init(&cd, DEVICE_3));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
_cleanup_dmdevices();
}
@@ -1713,6 +1808,7 @@ static void TcryptTest(void)
};
double enc_mbr = 0, dec_mbr = 0;
const char *tcrypt_dev = "tcrypt-images/tck_5-sha512-xts-aes";
const char *tcrypt_dev2 = "tcrypt-images/tc_5-sha512-xts-serpent-twofish-aes";
size_t key_size = 64;
char key[key_size], key_def[key_size];
const char *key_hex =
@@ -1743,12 +1839,14 @@ static void TcryptTest(void)
EQ_(256, crypt_get_data_offset(cd));
memset(key, 0, key_size);
key_size--;
// small buffer
FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0), "small buffer");
key_size++;
OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0));
OK_(memcmp(key, key_def, key_size));
if (!_fips_mode) {
key_size--;
// small buffer
FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0), "small buffer");
key_size++;
OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0));
OK_(memcmp(key, key_def, key_size));
}
reset_log();
crypt_set_log_callback(cd, &new_log, NULL);
@@ -1780,6 +1878,18 @@ static void TcryptTest(void)
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
OK_(crypt_init(&cd, tcrypt_dev2));
params.keyfiles = NULL;
params.keyfiles_count = 0;
OK_(crypt_load(cd, CRYPT_TCRYPT, &params));
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, NULL, 0, CRYPT_ACTIVATE_READONLY));
crypt_free(cd);
// Deactivate the whole chain
EQ_(crypt_status(NULL, CDEVICE_1 "_1"), CRYPT_BUSY);
OK_(crypt_deactivate(NULL, CDEVICE_1));
EQ_(crypt_status(NULL, CDEVICE_1 "_1"), CRYPT_INACTIVE);
}
// Check that gcrypt is properly initialised in format
@@ -1788,7 +1898,7 @@ static void NonFIPSAlg(void)
struct crypt_device *cd;
struct crypt_params_luks1 params = {0};
char key[128] = "";
size_t key_size = 128;
size_t key_size = 128 / 8;
const char *cipher = "aes";
const char *cipher_mode = "cbc-essiv:sha256";
int ret;
@@ -1817,8 +1927,14 @@ static void NonFIPSAlg(void)
crypt_free(cd);
}
static void int_handler(int sig __attribute__((__unused__)))
{
_quit++;
}
int main(int argc, char *argv[])
{
struct sigaction sa = { .sa_handler = int_handler };
int i;
if (getuid() != 0) {
@@ -1833,6 +1949,10 @@ int main(int argc, char *argv[])
_debug = _verbose = 1;
}
/* Handle interrupt properly */
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
_cleanup();
if (_setup())
goto out;

View File

@@ -39,6 +39,7 @@ KEY_MATERIAL5_EXT="S331776-395264"
TEST_UUID="12345678-1234-1234-1234-123456789abc"
LOOPDEV=$(losetup -f 2>/dev/null)
[ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
function remove_mapping()
{
@@ -63,6 +64,12 @@ function fail()
exit 2
}
function can_fail_fips()
{
# Ignore this fail if running in FIPS mode
[ -z "$FIPS_MODE" -o "$FIPS_MODE" -eq 0 ] && fail $1
}
function skip()
{
[ -n "$1" ] && echo "$1"
@@ -390,8 +397,8 @@ echo $PWD1 | $CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 0: ENABLED" || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q $TEST_UUID || fail
echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key | grep -q "MK dump:" || fail
$CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" || fail
echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key | grep -q "MK dump:" || can_fail_fips
$CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" || can_fail_fips
prepare "[22] remove disappeared device" wipe
dmsetup create $DEV_NAME --table "0 5000 linear $LOOPDEV 2" || fail
@@ -520,6 +527,8 @@ $CRYPTSETUP luksOpen -S 5 -d $KEY1 $LOOPDEV $DEV_NAME && fail
prepare "[28] Detached LUKS header" wipe
dd if=/dev/zero of=$HEADER_IMG bs=1M count=4 >/dev/null 2>&1
echo $PWD1 | $CRYPTSETUP luksFormat -i1 $LOOPDEV --header $HEADER_IMG || fail
echo $PWD1 | $CRYPTSETUP luksFormat -i1 $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP luksFormat -i1 $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail
echo $PWD1 | $CRYPTSETUP luksFormat -i1 $LOOPDEV --header $HEADER_IMG --align-payload 0 || fail
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail
$CRYPTSETUP -q resize $DEV_NAME --size 100 --header $HEADER_IMG || fail
@@ -537,5 +546,14 @@ $CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail
$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
prepare "[30] LUKS erase" wipe
$CRYPTSETUP -q luksFormat -i1 $LOOPDEV $KEY5 --key-slot 5 || fail
$CRYPTSETUP luksAddKey -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: ENABLED" || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: ENABLED" || fail
$CRYPTSETUP luksErase -q $LOOPDEV || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: DISABLED" || fail
remove_mapping
exit 0

BIN
tests/img_fs_ext4.img.bz2 Normal file

Binary file not shown.

BIN
tests/img_fs_xfs.img.bz2 Normal file

Binary file not shown.

View File

@@ -20,6 +20,12 @@ cleanup() {
exit $1
}
function fail()
{
echo " $1 [FAILED]"
cleanup 2
}
crypt_key() # hash keysize pwd/file name outkey [limit]
{
DEV2=$DEV_NAME"_x"
@@ -50,8 +56,13 @@ crypt_key() # hash keysize pwd/file name outkey [limit]
$CRYPTSETUP create -c $MODE -d $4 -h $1 -s $2 $DEV2 /dev/mapper/$DEV_NAME 2>/dev/null
ret=$?
;;
failpwd)
echo -e -n "$4" | $CRYPTSETUP create -c $MODE -h $1 -s $2 $LIMIT $DEV2 /dev/mapper/$DEV_NAME 2>/dev/null && fail "Expecting failure"
echo " [OK]"
return
;;
*)
fail
fail ""
;;
esac
@@ -107,6 +118,9 @@ crypt_key unknown* 256 file /dev/zero 00000000000000000000000000000000000000000
crypt_key sha256:20 256 pwd "xxx" cd2eb0837c9b4c962c22d2ff8b5441b7b4580588000000000000000000000000
crypt_key sha256:32 256 pwd "xxx" cd2eb0837c9b4c962c22d2ff8b5441b7b45805887f051d39bf133b583baf6860
crypt_key sha256: 256 failpwd "xxx" x
crypt_key sha256:xx 256 failpwd "xxx" x
# key file, 80 chars
echo -n -e "0123456789abcdef\n\x01\x00\x03\xff\xff\r\xff\xff\n\r" \
"2352j3rkjhadcfasc823rqaw7e1 3dq sdq3d 2dkjqw3h2=====" >$KEY_FILE
@@ -121,6 +135,12 @@ crypt_key sha256 512 file $KEY_FILE $KEY_FILE_HEX
crypt_key plain 128 cat /dev/zero 00000000000000000000000000000000 16
crypt_key plain 128 cat /dev/zero 00000000000000000000000000000000 17
crypt_key plain 128 cat $KEY_FILE ${KEY_FILE_HEX:0:28}0000 14
# limiting plain (no hash)
crypt_key plain 256 pwd "xxxxxxxx" 7878787878787878000000000000000000000000000000000000000000000000
crypt_key plain:2 256 pwd "xxxxxxxx" 7878000000000000000000000000000000000000000000000000000000000000
crypt_key plain:9 256 failpwd "xxxxxxxx" x
crypt_key sha256 128 cat $KEY_FILE a82c9227cc54c7475620ce85ba1fca1e 14
crypt_key sha256:14 128 cat $KEY_FILE a82c9227cc54c7475620ce85ba1f0000 14

View File

@@ -6,16 +6,27 @@ REENC=../src/cryptsetup-reencrypt
DEV_NAME=reenc9768
DEV_NAME2=reenc1273
IMG=reenc-data
ORIG_IMG=reenc-data-orig
KEY1=key1
PWD1="93R4P4pIqAH8"
PWD2="1cND4319812f"
PWD3="1-9Qu5Ejfnqv"
function del_scsi_device()
{
rmmod scsi_debug 2>/dev/null
sleep 2
}
function remove_mapping()
{
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
rm -f $IMG $KEY1 >/dev/null 2>&1
rm -f $IMG $ORIG_IMG $KEY1 >/dev/null 2>&1
LOOPDEV1=""
del_scsi_device
}
function fail()
@@ -32,12 +43,25 @@ function skip()
exit 0
}
function add_scsi_device() {
del_scsi_device
modprobe scsi_debug $@
if [ $? -ne 0 ] ; then
echo "This kernel seems to not support proper scsi_debug module, test skipped."
exit 0
fi
sleep 2
SCSI_DEV="/dev/"$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
[ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV."
}
function open_crypt()
{
if [ -n "$1" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME || fail
else
$CRYPTSETUP luksOpen -d key1 $LOOPDEV1 $DEV_NAME || fail
$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV1 $DEV_NAME || fail
fi
}
@@ -80,6 +104,63 @@ function check_hash() # $1 pwd, $2 hash
$CRYPTSETUP remove $DEV_NAME || fail
}
function backup_orig()
{
sync
losetup -d $LOOPDEV1
cp $IMG $ORIG_IMG
losetup $LOOPDEV1 $IMG
}
function rollback()
{
sync
losetup -d $LOOPDEV1
cp $ORIG_IMG $IMG
losetup $LOOPDEV1 $IMG
}
function check_slot() #space separeted list of ENABLED key slots
{
local _KS0=DISABLED
local _KS1=$_KS0 _KS2=$_KS0 _KS3=$_KS0 _KS4=$_KS0 _KS5=$_KS0 _KS6=$_KS0 _KS7=$_KS0
local _tmp
for _tmp in $*; do
eval _KS$_tmp=ENABLED
done
local _out=$($CRYPTSETUP luksDump $LOOPDEV1 | grep -e "Key Slot" | cut -d ' ' -f 4)
local _i=0
for _tmp in $_out; do
eval local _orig="\${_KS${_i}}"
if [ "$_tmp" != "$_orig" ]; then
echo "Keyslot $_i is $_tmp, expected result: $_orig"
return 1
fi
_i=$[_i+1]
done
return 0
}
function simple_scsi_reenc()
{
echo -n "$1"
echo $PWD1 | $CRYPTSETUP luksFormat -i1 $SCSI_DEV || fail
echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail
HASH=$(sha256sum /dev/mapper/$DEV_NAME | cut -d' ' -f 1)
$CRYPTSETUP luksClose $DEV_NAME || fail
echo $PWD1 | $REENC -q -i 1 $SCSI_DEV || fail
echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail
check_hash_dev /dev/mapper/$DEV_NAME $HASH
$CRYPTSETUP luksClose $DEV_NAME || fail
}
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
[ ! -x "$REENC" ] && skip "Cannot find $REENC, test skipped."
@@ -112,12 +193,15 @@ echo $PWD1 | $REENC $LOOPDEV1 -q -i 1 || fail
check_hash $PWD1 $HASH2
echo "[3] Reencryption with keyfile"
echo $PWD1 | $CRYPTSETUP -q luksFormat -d key1 -c aes-cbc-essiv:sha256 -s 128 -i 1 --align-payload 4096 $LOOPDEV1 || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat -d $KEY1 -c aes-cbc-essiv:sha256 -s 128 -i 1 --align-payload 4096 $LOOPDEV1 || fail
wipe
check_hash "" $HASH1
echo $PWD1 | $CRYPTSETUP -q luksAddKey -d key1 $LOOPDEV1 || fail
$REENC $LOOPDEV1 -d key1 -S 0 -i 1 -q || fail
echo $PWD1 | $CRYPTSETUP -q luksAddKey -d $KEY1 $LOOPDEV1 || fail
$REENC $LOOPDEV1 -d $KEY1 -i 1 -q 2>/dev/null && fail
$REENC $LOOPDEV1 -d $KEY1 -S 0 -i 1 -q || fail
check_hash "" $HASH1
check_slot 0 || fail "Only keyslot 0 expected to be enabled"
$REENC $LOOPDEV1 -d $KEY1 -i 1 -q || fail
# FIXME echo $PWD1 | $REENC ...
echo "[4] Encryption of not yet encrypted device"
@@ -131,5 +215,56 @@ dmsetup remove $DEV_NAME2 || fail
echo $PWD1 | $REENC $LOOPDEV1 -c aes-cbc-essiv:sha256 -s 128 --new --reduce-device-size "$OFFSET"S -q
check_hash $PWD1 $HASH3
echo "[5] Reencryption using specific keyslot"
echo $PWD2 | $CRYPTSETUP -q luksFormat -i 1 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey -i 1 -S 1 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey -i 1 -S 2 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey -i 1 -S 3 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey -i 1 -S 4 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey -i 1 -S 5 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey -i 1 -S 6 $LOOPDEV1 || fail
echo -e "$PWD2\n$PWD3" | $CRYPTSETUP -q luksAddKey -i 1 -S 7 $LOOPDEV1 || fail
backup_orig
echo $PWD2 | $REENC -i 1 -S 0 -q $LOOPDEV1 || fail
check_slot 0 || fail "Only keyslot 0 expected to be enabled"
wipe $PWD2
rollback
echo $PWD1 | $REENC -i 1 -S 1 -q $LOOPDEV1 || fail
check_slot 1 || fail "Only keyslot 1 expected to be enabled"
wipe $PWD1
rollback
echo $PWD2 | $REENC -i 1 -S 6 -q $LOOPDEV1 || fail
check_slot 6 || fail "Only keyslot 6 expected to be enabled"
wipe $PWD2
rollback
echo $PWD3 | $REENC -i 1 -S 7 -q $LOOPDEV1 || fail
check_slot 7 || fail "Only keyslot 7 expected to be enabled"
wipe $PWD3
rollback
echo "[6] Reencryption using all active keyslots"
echo -e "$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD3" | $REENC -q $LOOPDEV1 || fail
check_slot 0 1 2 3 4 5 6 7 || fail "All keyslots expected to be enabled"
echo "[7] Reencryption of block devices with different block size"
add_scsi_device sector_size=512 dev_size_mb=8
simple_scsi_reenc "[512 sector]"
add_scsi_device sector_size=4096 dev_size_mb=8
simple_scsi_reenc "[4096 sector]"
add_scsi_device sector_size=512 physblk_exp=3 dev_size_mb=8
simple_scsi_reenc "[4096/512 sector]"
echo "[OK]"
echo "[8] Header only reencryption (hash and iteration time)"
echo $PWD1 | $CRYPTSETUP -q luksFormat --hash sha1 $LOOPDEV1 || fail
wipe $PWD1
check_hash $PWD1 $HASH1
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha256 --iter-time 1
check_hash $PWD1 $HASH1
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha512
check_hash $PWD1 $HASH1
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --iter-time 1
check_hash $PWD1 $HASH1
remove_mapping
exit 0

View File

@@ -65,6 +65,7 @@ function test_required()
}
test_required
export LANG=C
[ ! -d $TST_DIR ] && tar xjf tcrypt-images.tar.bz2
@@ -95,10 +96,11 @@ if [ $(id -u) != 0 ]; then
exit 0
fi
echo "ACTIVATION FS UUID CHECK (LRW/XTS modes only)"
for file in $(ls $TST_DIR/tc_*-lrw-* $TST_DIR/tc_*-xts-*) ; do
echo "ACTIVATION FS UUID CHECK"
for file in $(ls $TST_DIR/tc_*) ; do
echo -n " $file"
echo $PASSWORD | $CRYPTSETUP tcryptOpen -r $file $MAP || fail
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
$CRYPTSETUP status $MAP >/dev/null || fail
$CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
@@ -107,10 +109,11 @@ for file in $(ls $TST_DIR/tc_*-lrw-* $TST_DIR/tc_*-xts-*) ; do
echo " [OK]"
done
echo "ACTIVATION FS UUID (HIDDEN) CHECK (LRW/XTS modes only)"
for file in $(ls $TST_DIR/tc_*-lrw-*-hidden $TST_DIR/tc_*-xts-*-hidden) ; do
echo "ACTIVATION FS UUID (HIDDEN) CHECK"
for file in $(ls $TST_DIR/tc_*-hidden) ; do
echo -n " $file"
echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen -r $file $MAP --tcrypt-hidden || fail
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
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
$CRYPTSETUP remove $MAP || fail
[ "$UUID" != "CAFE-BABE" ] && fail "UUID check failed."

Binary file not shown.